10ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Ceres Solver - A fast non-linear least squares minimizer
20ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
30ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// http://code.google.com/p/ceres-solver/
40ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
50ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Redistribution and use in source and binary forms, with or without
60ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// modification, are permitted provided that the following conditions are met:
70ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
80ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions of source code must retain the above copyright notice,
90ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   this list of conditions and the following disclaimer.
100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions in binary form must reproduce the above copyright notice,
110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   this list of conditions and the following disclaimer in the documentation
120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   and/or other materials provided with the distribution.
130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Neither the name of Google Inc. nor the names of its contributors may be
140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   used to endorse or promote products derived from this software without
150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   specific prior written permission.
160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// POSSIBILITY OF SUCH DAMAGE.
280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Author: keir@google.com (Keir Mierle)
300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/gradient_checking_cost_function.h"
320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <algorithm>
340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <cmath>
350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <numeric>
360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <string>
370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <vector>
380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/cost_function.h"
400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/internal/eigen.h"
410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/internal/scoped_ptr.h"
420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/parameter_block.h"
430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/problem.h"
440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/problem_impl.h"
450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/program.h"
460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/residual_block.h"
4779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/dynamic_numeric_diff_cost_function.h"
480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/stringprintf.h"
490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/types.h"
500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "glog/logging.h"
510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace ceres {
530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace internal {
540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace {
550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// True if x and y have an absolute relative difference less than
570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// relative_precision and false otherwise. Stores the relative and absolute
580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// difference in relative/absolute_error if non-NULL.
590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongbool IsClose(double x, double y, double relative_precision,
600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong             double *relative_error,
610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong             double *absolute_error) {
620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  double local_absolute_error;
630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  double local_relative_error;
640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  if (!absolute_error) {
650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    absolute_error = &local_absolute_error;
660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  }
670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  if (!relative_error) {
680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    relative_error = &local_relative_error;
690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  }
700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  *absolute_error = fabs(x - y);
710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  *relative_error = *absolute_error / max(fabs(x), fabs(y));
720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  if (x == 0 || y == 0) {
730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // If x or y is exactly zero, then relative difference doesn't have any
740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // meaning. Take the absolute difference instead.
750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    *relative_error = *absolute_error;
760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  }
770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  return fabs(*relative_error) < fabs(relative_precision);
780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongclass GradientCheckingCostFunction : public CostFunction {
810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong public:
820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  GradientCheckingCostFunction(const CostFunction* function,
830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                               double relative_step_size,
840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                               double relative_precision,
850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                               const string& extra_info)
860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      : function_(function),
870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        relative_precision_(relative_precision),
880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        extra_info_(extra_info) {
8979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    DynamicNumericDiffCostFunction<CostFunction, CENTRAL>*
9079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez        finite_diff_cost_function =
9179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez        new DynamicNumericDiffCostFunction<CostFunction, CENTRAL>(
9279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez            function,
9379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez            DO_NOT_TAKE_OWNERSHIP,
9479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez            relative_step_size);
9579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
9679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    const vector<int32>& parameter_block_sizes =
9779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez        function->parameter_block_sizes();
9879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    for (int i = 0; i < parameter_block_sizes.size(); ++i) {
9979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez      finite_diff_cost_function->AddParameterBlock(parameter_block_sizes[i]);
10079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    }
10179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    *mutable_parameter_block_sizes() = parameter_block_sizes;
1020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    set_num_residuals(function->num_residuals());
10379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    finite_diff_cost_function->SetNumResiduals(num_residuals());
10479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    finite_diff_cost_function_.reset(finite_diff_cost_function);
1050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  }
1060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual ~GradientCheckingCostFunction() { }
1080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual bool Evaluate(double const* const* parameters,
1100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                        double* residuals,
1110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                        double** jacobians) const {
1120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    if (!jacobians) {
1130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      // Nothing to check in this case; just forward.
1140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      return function_->Evaluate(parameters, residuals, NULL);
1150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
1160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    int num_residuals = function_->num_residuals();
1180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // Make space for the jacobians of the two methods.
12079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    const vector<int32>& block_sizes = function_->parameter_block_sizes();
1210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    vector<Matrix> term_jacobians(block_sizes.size());
1220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    vector<Matrix> finite_difference_jacobians(block_sizes.size());
1230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    vector<double*> term_jacobian_pointers(block_sizes.size());
1240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    vector<double*> finite_difference_jacobian_pointers(block_sizes.size());
1250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    for (int i = 0; i < block_sizes.size(); i++) {
1260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      term_jacobians[i].resize(num_residuals, block_sizes[i]);
1270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      term_jacobian_pointers[i] = term_jacobians[i].data();
1280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      finite_difference_jacobians[i].resize(num_residuals, block_sizes[i]);
1290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      finite_difference_jacobian_pointers[i] =
1300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          finite_difference_jacobians[i].data();
1310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
1320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // Evaluate the derivative using the user supplied code.
1340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    if (!function_->Evaluate(parameters,
1350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                             residuals,
1360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                             &term_jacobian_pointers[0])) {
1370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      LOG(WARNING) << "Function evaluation failed.";
1380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      return false;
1390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
1400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // Evaluate the derivative using numeric derivatives.
1420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    finite_diff_cost_function_->Evaluate(
1430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        parameters,
1440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        residuals,
1450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        &finite_difference_jacobian_pointers[0]);
1460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // See if any elements have relative error larger than the threshold.
1480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    int num_bad_jacobian_components = 0;
1490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    double worst_relative_error = 0;
1500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // Accumulate the error message for all the jacobians, since it won't get
1520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // output if there are no bad jacobian components.
1530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    string m;
1540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    for (int k = 0; k < block_sizes.size(); k++) {
1550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      // Copy the original jacobian blocks into the jacobians array.
1560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      if (jacobians[k] != NULL) {
1570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        MatrixRef(jacobians[k],
1580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                  term_jacobians[k].rows(),
1590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                  term_jacobians[k].cols()) = term_jacobians[k];
1600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      }
1610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      StringAppendF(&m,
1630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                    "========== "
1640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                    "Jacobian for " "block %d: (%ld by %ld)) "
1650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                    "==========\n",
1660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                    k,
1670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                    static_cast<long>(term_jacobians[k].rows()),
1680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                    static_cast<long>(term_jacobians[k].cols()));
1690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      // The funny spacing creates appropriately aligned column headers.
1700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      m += " block  row  col        user dx/dy    num diff dx/dy         "
1710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong           "abs error    relative error         parameter          residual\n";
1720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      for (int i = 0; i < term_jacobians[k].rows(); i++) {
1740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        for (int j = 0; j < term_jacobians[k].cols(); j++) {
1750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          double term_jacobian = term_jacobians[k](i, j);
1760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          double finite_jacobian = finite_difference_jacobians[k](i, j);
1770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          double relative_error, absolute_error;
1780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          bool bad_jacobian_entry =
1790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong              !IsClose(term_jacobian,
1800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                       finite_jacobian,
1810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                       relative_precision_,
1820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                       &relative_error,
1830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                       &absolute_error);
1840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          worst_relative_error = std::max(worst_relative_error,
1850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                          relative_error);
1860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          StringAppendF(&m, "%6d %4d %4d %17g %17g %17g %17g %17g %17g",
1880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                        k, i, j,
1890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                        term_jacobian, finite_jacobian,
1900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                        absolute_error, relative_error,
1910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                        parameters[k][j],
1920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                        residuals[i]);
1930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          if (bad_jacobian_entry) {
1950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            num_bad_jacobian_components++;
1960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            StringAppendF(
1970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                &m, " ------ (%d,%d,%d) Relative error worse than %g",
1980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                k, i, j, relative_precision_);
1990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          }
2000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          m += "\n";
2010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        }
2020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      }
2030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
2040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // Since there were some bad errors, dump comprehensive debug info.
2060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    if (num_bad_jacobian_components) {
2070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      string header = StringPrintf("Detected %d bad jacobian component(s). "
2080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   "Worst relative error was %g.\n",
2090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   num_bad_jacobian_components,
2100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   worst_relative_error);
2110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      if (!extra_info_.empty()) {
2120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        header += "Extra info for this residual: " + extra_info_ + "\n";
2130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      }
2140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      LOG(WARNING) << "\n" << header << m;
2150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
2160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    return true;
2170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  }
2180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong private:
2200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  const CostFunction* function_;
2210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  internal::scoped_ptr<CostFunction> finite_diff_cost_function_;
2220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  double relative_precision_;
2230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  string extra_info_;
2240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong};
2250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}  // namespace
2270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongCostFunction *CreateGradientCheckingCostFunction(
2290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const CostFunction *cost_function,
2300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    double relative_step_size,
2310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    double relative_precision,
2320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const string& extra_info) {
2330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  return new GradientCheckingCostFunction(cost_function,
2340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                          relative_step_size,
2350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                          relative_precision,
2360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                          extra_info);
2370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
2380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongProblemImpl* CreateGradientCheckingProblemImpl(ProblemImpl* problem_impl,
2400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                               double relative_step_size,
2410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                               double relative_precision) {
2420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // We create new CostFunctions by wrapping the original CostFunction
2430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // in a gradient checking CostFunction. So its okay for the
2440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // ProblemImpl to take ownership of it and destroy it. The
2450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // LossFunctions and LocalParameterizations are reused and since
2460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // they are owned by problem_impl, gradient_checking_problem_impl
2470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // should not take ownership of it.
2480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  Problem::Options gradient_checking_problem_options;
2490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  gradient_checking_problem_options.cost_function_ownership = TAKE_OWNERSHIP;
2500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  gradient_checking_problem_options.loss_function_ownership =
2510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      DO_NOT_TAKE_OWNERSHIP;
2520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  gradient_checking_problem_options.local_parameterization_ownership =
2530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      DO_NOT_TAKE_OWNERSHIP;
2540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ProblemImpl* gradient_checking_problem_impl = new ProblemImpl(
2560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      gradient_checking_problem_options);
2570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  Program* program = problem_impl->mutable_program();
2590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // For every ParameterBlock in problem_impl, create a new parameter
2610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // block with the same local parameterization and constancy.
2620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  const vector<ParameterBlock*>& parameter_blocks = program->parameter_blocks();
2630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  for (int i = 0; i < parameter_blocks.size(); ++i) {
2640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    ParameterBlock* parameter_block = parameter_blocks[i];
2650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    gradient_checking_problem_impl->AddParameterBlock(
2660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        parameter_block->mutable_user_state(),
2670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        parameter_block->Size(),
2680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        parameter_block->mutable_local_parameterization());
2690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    if (parameter_block->IsConstant()) {
2710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      gradient_checking_problem_impl->SetParameterBlockConstant(
2720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          parameter_block->mutable_user_state());
2730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
2740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  }
2750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // For every ResidualBlock in problem_impl, create a new
2770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // ResidualBlock by wrapping its CostFunction inside a
2780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // GradientCheckingCostFunction.
2790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  const vector<ResidualBlock*>& residual_blocks = program->residual_blocks();
2800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  for (int i = 0; i < residual_blocks.size(); ++i) {
2810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    ResidualBlock* residual_block = residual_blocks[i];
2820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // Build a human readable string which identifies the
2840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // ResidualBlock. This is used by the GradientCheckingCostFunction
2850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // when logging debugging information.
2860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    string extra_info = StringPrintf(
2870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        "Residual block id %d; depends on parameters [", i);
2880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    vector<double*> parameter_blocks;
2890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    for (int j = 0; j < residual_block->NumParameterBlocks(); ++j) {
2900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      ParameterBlock* parameter_block = residual_block->parameter_blocks()[j];
2910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      parameter_blocks.push_back(parameter_block->mutable_user_state());
2920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      StringAppendF(&extra_info, "%p", parameter_block->mutable_user_state());
2930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      extra_info += (j < residual_block->NumParameterBlocks() - 1) ? ", " : "]";
2940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
2950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // Wrap the original CostFunction in a GradientCheckingCostFunction.
2970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CostFunction* gradient_checking_cost_function =
2980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        CreateGradientCheckingCostFunction(residual_block->cost_function(),
2990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                           relative_step_size,
3000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                           relative_precision,
3010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                           extra_info);
3020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
3030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // The const_cast is necessary because
3040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // ProblemImpl::AddResidualBlock can potentially take ownership of
3050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // the LossFunction, but in this case we are guaranteed that this
3060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // will not be the case, so this const_cast is harmless.
3070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    gradient_checking_problem_impl->AddResidualBlock(
3080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        gradient_checking_cost_function,
3090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        const_cast<LossFunction*>(residual_block->loss_function()),
3100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        parameter_blocks);
3110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  }
3120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
3130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  return gradient_checking_problem_impl;
3140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
3150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
3160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
3170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}  // namespace internal
3180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}  // namespace ceres
319