// Ceres Solver - A fast non-linear least squares minimizer // Copyright 2013 Google Inc. All rights reserved. // http://code.google.com/p/ceres-solver/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of Google Inc. nor the names of its contributors may be // used to endorse or promote products derived from this software without // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // // Author: sameeragarwal@google.com (Sameer Agarwal) // // A wrapper class that takes a variadic functor evaluating a // function, numerically differentiates it and makes it available as a // templated functor so that it can be easily used as part of Ceres' // automatic differentiation framework. // // For example: // // For example, let us assume that // // struct IntrinsicProjection // IntrinsicProjection(const double* observations); // bool operator()(const double* calibration, // const double* point, // double* residuals); // }; // // is a functor that implements the projection of a point in its local // coordinate system onto its image plane and subtracts it from the // observed point projection. // // Now we would like to compose the action of this functor with the // action of camera extrinsics, i.e., rotation and translation, which // is given by the following templated function // // template // void RotateAndTranslatePoint(const T* rotation, // const T* translation, // const T* point, // T* result); // // To compose the extrinsics and intrinsics, we can construct a // CameraProjection functor as follows. // // struct CameraProjection { // typedef NumericDiffFunctor // IntrinsicProjectionFunctor; // // CameraProjection(double* observation) { // intrinsic_projection_.reset( // new IntrinsicProjectionFunctor(observation)) { // } // // template // bool operator()(const T* rotation, // const T* translation, // const T* intrinsics, // const T* point, // T* residuals) const { // T transformed_point[3]; // RotateAndTranslatePoint(rotation, translation, point, transformed_point); // return (*intrinsic_projection_)(intrinsics, transformed_point, residual); // } // // private: // scoped_ptr intrinsic_projection_; // }; // // Here, we made the choice of using CENTRAL differences to compute // the jacobian of IntrinsicProjection. // // Now, we are ready to construct an automatically differentiated cost // function as // // CostFunction* cost_function = // new AutoDiffCostFunction( // new CameraProjection(observations)); // // cost_function now seamlessly integrates automatic differentiation // of RotateAndTranslatePoint with a numerically differentiated // version of IntrinsicProjection. #ifndef CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_ #define CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_ #include "ceres/numeric_diff_cost_function.h" #include "ceres/types.h" #include "ceres/cost_function_to_functor.h" namespace ceres { template class NumericDiffFunctor { public: // relative_step_size controls the step size used by the numeric // differentiation process. explicit NumericDiffFunctor(double relative_step_size = 1e-6) : functor_( new NumericDiffCostFunction(new Functor, relative_step_size)) { } NumericDiffFunctor(Functor* functor, double relative_step_size = 1e-6) : functor_(new NumericDiffCostFunction( functor, relative_step_size)) { } bool operator()(const double* x0, double* residuals) const { return functor_(x0, residuals); } bool operator()(const double* x0, const double* x1, double* residuals) const { return functor_(x0, x1, residuals); } bool operator()(const double* x0, const double* x1, const double* x2, double* residuals) const { return functor_(x0, x1, x2, residuals); } bool operator()(const double* x0, const double* x1, const double* x2, const double* x3, double* residuals) const { return functor_(x0, x1, x2, x3, residuals); } bool operator()(const double* x0, const double* x1, const double* x2, const double* x3, const double* x4, double* residuals) const { return functor_(x0, x1, x2, x3, x4, residuals); } bool operator()(const double* x0, const double* x1, const double* x2, const double* x3, const double* x4, const double* x5, double* residuals) const { return functor_(x0, x1, x2, x3, x4, x5, residuals); } bool operator()(const double* x0, const double* x1, const double* x2, const double* x3, const double* x4, const double* x5, const double* x6, double* residuals) const { return functor_(x0, x1, x2, x3, x4, x5, x6, residuals); } bool operator()(const double* x0, const double* x1, const double* x2, const double* x3, const double* x4, const double* x5, const double* x6, const double* x7, double* residuals) const { return functor_(x0, x1, x2, x3, x4, x5, x6, x7, residuals); } bool operator()(const double* x0, const double* x1, const double* x2, const double* x3, const double* x4, const double* x5, const double* x6, const double* x7, const double* x8, double* residuals) const { return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, residuals); } bool operator()(const double* x0, const double* x1, const double* x2, const double* x3, const double* x4, const double* x5, const double* x6, const double* x7, const double* x8, const double* x9, double* residuals) const { return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, residuals); } template bool operator()(const T* x0, T* residuals) const { return functor_(x0, residuals); } template bool operator()(const T* x0, const T* x1, T* residuals) const { return functor_(x0, x1, residuals); } template bool operator()(const T* x0, const T* x1, const T* x2, T* residuals) const { return functor_(x0, x1, x2, residuals); } template bool operator()(const T* x0, const T* x1, const T* x2, const T* x3, T* residuals) const { return functor_(x0, x1, x2, x3, residuals); } template bool operator()(const T* x0, const T* x1, const T* x2, const T* x3, const T* x4, T* residuals) const { return functor_(x0, x1, x2, x3, x4, residuals); } template bool operator()(const T* x0, const T* x1, const T* x2, const T* x3, const T* x4, const T* x5, T* residuals) const { return functor_(x0, x1, x2, x3, x4, x5, residuals); } template bool operator()(const T* x0, const T* x1, const T* x2, const T* x3, const T* x4, const T* x5, const T* x6, T* residuals) const { return functor_(x0, x1, x2, x3, x4, x5, x6, residuals); } template bool operator()(const T* x0, const T* x1, const T* x2, const T* x3, const T* x4, const T* x5, const T* x6, const T* x7, T* residuals) const { return functor_(x0, x1, x2, x3, x4, x5, x6, x7, residuals); } template bool operator()(const T* x0, const T* x1, const T* x2, const T* x3, const T* x4, const T* x5, const T* x6, const T* x7, const T* x8, T* residuals) const { return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, residuals); } template bool operator()(const T* x0, const T* x1, const T* x2, const T* x3, const T* x4, const T* x5, const T* x6, const T* x7, const T* x8, const T* x9, T* residuals) const { return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, residuals); } private: CostFunctionToFunctor functor_; }; } // namespace ceres #endif // CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_