11d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// Ceres Solver - A fast non-linear least squares minimizer
21d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// Copyright 2013 Google Inc. All rights reserved.
31d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// http://code.google.com/p/ceres-solver/
41d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
51d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// Redistribution and use in source and binary forms, with or without
61d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// modification, are permitted provided that the following conditions are met:
71d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
81d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// * Redistributions of source code must retain the above copyright notice,
91d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   this list of conditions and the following disclaimer.
101d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// * Redistributions in binary form must reproduce the above copyright notice,
111d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   this list of conditions and the following disclaimer in the documentation
121d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   and/or other materials provided with the distribution.
131d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// * Neither the name of Google Inc. nor the names of its contributors may be
141d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   used to endorse or promote products derived from this software without
151d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   specific prior written permission.
161d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
171d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
181d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
211d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
221d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
231d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
241d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
251d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
261d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
271d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// POSSIBILITY OF SUCH DAMAGE.
281d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
291d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// Author: sameeragarwal@google.com (Sameer Agarwal)
301d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
311d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// A wrapper class that takes a variadic functor evaluating a
321d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// function, numerically differentiates it and makes it available as a
331d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// templated functor so that it can be easily used as part of Ceres'
341d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// automatic differentiation framework.
351d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
361d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// For example:
371d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
381d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// For example, let us assume that
391d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
401d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//  struct IntrinsicProjection
411d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//    IntrinsicProjection(const double* observations);
421d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//    bool operator()(const double* calibration,
431d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//                    const double* point,
441d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//                    double* residuals);
451d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//  };
461d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
471d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// is a functor that implements the projection of a point in its local
481d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// coordinate system onto its image plane and subtracts it from the
491d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// observed point projection.
501d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
511d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// Now we would like to compose the action of this functor with the
521d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// action of camera extrinsics, i.e., rotation and translation, which
531d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// is given by the following templated function
541d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
551d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   template<typename T>
561d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   void RotateAndTranslatePoint(const T* rotation,
571d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//                                const T* translation,
581d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//                                const T* point,
591d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//                                T* result);
601d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
611d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// To compose the extrinsics and intrinsics, we can construct a
621d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// CameraProjection functor as follows.
631d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
641d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// struct CameraProjection {
651d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//    typedef NumericDiffFunctor<IntrinsicProjection, CENTRAL, 2, 5, 3>
661d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//       IntrinsicProjectionFunctor;
671d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
681d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   CameraProjection(double* observation) {
691d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//     intrinsic_projection_.reset(
701d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//         new IntrinsicProjectionFunctor(observation)) {
711d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   }
721d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
731d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   template <typename T>
741d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   bool operator()(const T* rotation,
751d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//                   const T* translation,
761d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//                   const T* intrinsics,
771d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//                   const T* point,
781d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//                   T* residuals) const {
791d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//     T transformed_point[3];
801d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//     RotateAndTranslatePoint(rotation, translation, point, transformed_point);
811d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//     return (*intrinsic_projection_)(intrinsics, transformed_point, residual);
821d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   }
831d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
841d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//  private:
851d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//   scoped_ptr<IntrinsicProjectionFunctor> intrinsic_projection_;
861d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// };
871d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
881d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// Here, we made the choice of using CENTRAL differences to compute
891d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// the jacobian of IntrinsicProjection.
901d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
911d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// Now, we are ready to construct an automatically differentiated cost
921d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// function as
931d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
941d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// CostFunction* cost_function =
951d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//    new AutoDiffCostFunction<CameraProjection, 2, 3, 3, 5>(
961d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//        new CameraProjection(observations));
971d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//
981d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// cost_function now seamlessly integrates automatic differentiation
991d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// of RotateAndTranslatePoint with a numerically differentiated
1001d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// version of IntrinsicProjection.
1011d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1021d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling#ifndef CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_
1031d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling#define CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_
1041d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1051d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling#include "ceres/numeric_diff_cost_function.h"
1061d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling#include "ceres/types.h"
1071d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling#include "ceres/cost_function_to_functor.h"
1081d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1091d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberlingnamespace ceres {
1101d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1111d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberlingtemplate<typename Functor,
1121d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling         NumericDiffMethod kMethod = CENTRAL,
1131d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling         int kNumResiduals = 0,
1141d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling         int N0 = 0, int N1 = 0 , int N2 = 0, int N3 = 0, int N4 = 0,
1151d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling         int N5 = 0, int N6 = 0 , int N7 = 0, int N8 = 0, int N9 = 0>
1161d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberlingclass NumericDiffFunctor {
1171d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling public:
1181d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  // relative_step_size controls the step size used by the numeric
1191d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  // differentiation process.
1201d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  explicit NumericDiffFunctor(double relative_step_size = 1e-6)
1211d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling      : functor_(
1221d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling          new NumericDiffCostFunction<Functor,
1231d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                                      kMethod,
1241d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                                      kNumResiduals,
1251d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                                      N0, N1, N2, N3, N4,
1261d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                                      N5, N6, N7, N8, N9>(new Functor,
12779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez                                                          TAKE_OWNERSHIP,
12879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez                                                          kNumResiduals,
1291d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                                                          relative_step_size)) {
1301d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
1311d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1321d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  NumericDiffFunctor(Functor* functor, double relative_step_size = 1e-6)
1331d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling      : functor_(new NumericDiffCostFunction<Functor,
1341d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                                             kMethod,
1351d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                                             kNumResiduals,
1361d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                                             N0, N1, N2, N3, N4,
1371d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                                             N5, N6, N7, N8, N9>(
13879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez                                                 functor,
13979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez                                                 TAKE_OWNERSHIP,
14079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez                                                 kNumResiduals,
14179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez                                                 relative_step_size)) {
1421d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
1431d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1441d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const double* x0, double* residuals) const {
1451d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, residuals);
1461d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
1471d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1481d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const double* x0,
1491d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x1,
1501d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  double* residuals) const {
1511d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, residuals);
1521d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
1531d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1541d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const double* x0,
1551d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x1,
1561d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x2,
1571d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  double* residuals) const {
1581d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, residuals);
1591d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
1601d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1611d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const double* x0,
1621d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x1,
1631d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x2,
1641d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x3,
1651d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  double* residuals) const {
1661d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, residuals);
1671d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
1681d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1691d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const double* x0,
1701d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x1,
1711d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x2,
1721d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x3,
1731d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x4,
1741d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  double* residuals) const {
1751d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, residuals);
1761d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
1771d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1781d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const double* x0,
1791d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x1,
1801d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x2,
1811d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x3,
1821d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x4,
1831d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x5,
1841d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  double* residuals) const {
1851d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, x5, residuals);
1861d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
1871d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1881d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const double* x0,
1891d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x1,
1901d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x2,
1911d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x3,
1921d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x4,
1931d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x5,
1941d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x6,
1951d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  double* residuals) const {
1961d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, x5, x6, residuals);
1971d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
1981d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1991d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const double* x0,
2001d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x1,
2011d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x2,
2021d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x3,
2031d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x4,
2041d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x5,
2051d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x6,
2061d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x7,
2071d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  double* residuals) const {
2081d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, x5, x6, x7, residuals);
2091d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
2101d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
2111d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const double* x0,
2121d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x1,
2131d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x2,
2141d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x3,
2151d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x4,
2161d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x5,
2171d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x6,
2181d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x7,
2191d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x8,
2201d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  double* residuals) const {
2211d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, residuals);
2221d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
2231d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
2241d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const double* x0,
2251d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x1,
2261d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x2,
2271d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x3,
2281d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x4,
2291d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x5,
2301d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x6,
2311d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x7,
2321d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x8,
2331d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const double* x9,
2341d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  double* residuals) const {
2351d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, residuals);
2361d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
2371d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
2381d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  template <typename T>
2391d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const T* x0, T* residuals) const {
2401d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, residuals);
2411d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
2421d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
2431d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  template <typename T>
2441d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const T* x0,
2451d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x1,
2461d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  T* residuals) const {
2471d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, residuals);
2481d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
2491d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
2501d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  template <typename T>
2511d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const T* x0,
2521d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x1,
2531d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x2,
2541d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  T* residuals) const {
2551d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, residuals);
2561d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
2571d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
2581d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  template <typename T>
2591d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const T* x0,
2601d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x1,
2611d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x2,
2621d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x3,
2631d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  T* residuals) const {
2641d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, residuals);
2651d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
2661d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
2671d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  template <typename T>
2681d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const T* x0,
2691d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x1,
2701d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x2,
2711d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x3,
2721d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x4,
2731d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  T* residuals) const {
2741d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, residuals);
2751d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
2761d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
2771d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  template <typename T>
2781d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const T* x0,
2791d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x1,
2801d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x2,
2811d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x3,
2821d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x4,
2831d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x5,
2841d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  T* residuals) const {
2851d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, x5, residuals);
2861d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
2871d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
2881d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  template <typename T>
2891d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const T* x0,
2901d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x1,
2911d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x2,
2921d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x3,
2931d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x4,
2941d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x5,
2951d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x6,
2961d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  T* residuals) const {
2971d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, x5, x6, residuals);
2981d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
2991d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
3001d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  template <typename T>
3011d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const T* x0,
3021d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x1,
3031d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x2,
3041d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x3,
3051d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x4,
3061d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x5,
3071d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x6,
3081d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x7,
3091d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  T* residuals) const {
3101d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, x5, x6, x7, residuals);
3111d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
3121d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
3131d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  template <typename T>
3141d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const T* x0,
3151d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x1,
3161d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x2,
3171d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x3,
3181d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x4,
3191d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x5,
3201d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x6,
3211d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x7,
3221d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x8,
3231d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  T* residuals) const {
3241d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, residuals);
3251d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
3261d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
3271d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  template <typename T>
3281d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool operator()(const T* x0,
3291d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x1,
3301d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x2,
3311d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x3,
3321d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x4,
3331d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x5,
3341d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x6,
3351d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x7,
3361d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x8,
3371d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  const T* x9,
3381d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                  T* residuals) const {
3391d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, residuals);
3401d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  }
3411d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
3421d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
3431d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling private:
3441d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  CostFunctionToFunctor<kNumResiduals,
3451d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                        N0, N1, N2, N3, N4,
3461d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                        N5, N6, N7, N8, N9> functor_;
3471d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling};
3481d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
3491d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling}  // namespace ceres
3501d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
3511d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling#endif  // CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_
352