Blame docs/source/nnls_modeling.rst

Packit ea1746
.. default-domain:: cpp
Packit ea1746
Packit ea1746
.. cpp:namespace:: ceres
Packit ea1746
Packit ea1746
.. _`chapter-nnls_modeling`:
Packit ea1746
Packit ea1746
=================================
Packit ea1746
Modeling Non-linear Least Squares
Packit ea1746
=================================
Packit ea1746
Packit ea1746
Introduction
Packit ea1746
============
Packit ea1746
Packit ea1746
Ceres solver consists of two distinct parts. A modeling API which
Packit ea1746
provides a rich set of tools to construct an optimization problem one
Packit ea1746
term at a time and a solver API that controls the minimization
Packit ea1746
algorithm. This chapter is devoted to the task of modeling
Packit ea1746
optimization problems using Ceres. :ref:`chapter-nnls_solving` discusses
Packit ea1746
the various ways in which an optimization problem can be solved using
Packit ea1746
Ceres.
Packit ea1746
Packit ea1746
Ceres solves robustified bounds constrained non-linear least squares
Packit ea1746
problems of the form:
Packit ea1746
Packit ea1746
.. math:: :label: ceresproblem
Packit ea1746
Packit ea1746
   \min_{\mathbf{x}} &\quad \frac{1}{2}\sum_{i}
Packit ea1746
   \rho_i\left(\left\|f_i\left(x_{i_1},
Packit ea1746
   ... ,x_{i_k}\right)\right\|^2\right)  \\
Packit ea1746
   \text{s.t.} &\quad l_j \le x_j \le u_j
Packit ea1746
Packit ea1746
In Ceres parlance, the expression
Packit ea1746
:math:`\rho_i\left(\left\|f_i\left(x_{i_1},...,x_{i_k}\right)\right\|^2\right)`
Packit ea1746
is known as a **residual block**, where :math:`f_i(\cdot)` is a
Packit ea1746
:class:`CostFunction` that depends on the **parameter blocks**
Packit ea1746
:math:`\left\{x_{i_1},... , x_{i_k}\right\}`.
Packit ea1746
Packit ea1746
In most optimization problems small groups of scalars occur
Packit ea1746
together. For example the three components of a translation vector and
Packit ea1746
the four components of the quaternion that define the pose of a
Packit ea1746
camera. We refer to such a group of scalars as a **parameter block**. Of
Packit ea1746
course a parameter block can be just a single scalar too.
Packit ea1746
Packit ea1746
:math:`\rho_i` is a :class:`LossFunction`. A :class:`LossFunction` is
Packit ea1746
a scalar valued function that is used to reduce the influence of
Packit ea1746
outliers on the solution of non-linear least squares problems.
Packit ea1746
Packit ea1746
:math:`l_j` and :math:`u_j` are lower and upper bounds on the
Packit ea1746
parameter block :math:`x_j`.
Packit ea1746
Packit ea1746
As a special case, when :math:`\rho_i(x) = x`, i.e., the identity
Packit ea1746
function, and :math:`l_j = -\infty` and :math:`u_j = \infty` we get
Packit ea1746
the more familiar unconstrained `non-linear least squares problem
Packit ea1746
<http://en.wikipedia.org/wiki/Non-linear_least_squares>`_.
Packit ea1746
Packit ea1746
.. math:: :label: ceresproblemunconstrained
Packit ea1746
Packit ea1746
   \frac{1}{2}\sum_{i} \left\|f_i\left(x_{i_1}, ... ,x_{i_k}\right)\right\|^2.
Packit ea1746
Packit ea1746
:class:`CostFunction`
Packit ea1746
=====================
Packit ea1746
Packit ea1746
For each term in the objective function, a :class:`CostFunction` is
Packit ea1746
responsible for computing a vector of residuals and if asked a vector
Packit ea1746
of Jacobian matrices, i.e., given :math:`\left[x_{i_1}, ... ,
Packit ea1746
x_{i_k}\right]`, compute the vector
Packit ea1746
:math:`f_i\left(x_{i_1},...,x_{i_k}\right)` and the matrices
Packit ea1746
Packit ea1746
 .. math:: J_{ij} = \frac{\partial}{\partial
Packit ea1746
           x_{i_j}}f_i\left(x_{i_1},...,x_{i_k}\right),\quad \forall j
Packit ea1746
           \in \{1, \ldots, k\}
Packit ea1746
Packit ea1746
.. class:: CostFunction
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
    class CostFunction {
Packit ea1746
     public:
Packit ea1746
      virtual bool Evaluate(double const* const* parameters,
Packit ea1746
                            double* residuals,
Packit ea1746
                            double** jacobians) = 0;
Packit ea1746
      const vector<int32>& parameter_block_sizes();
Packit ea1746
      int num_residuals() const;
Packit ea1746
Packit ea1746
     protected:
Packit ea1746
      vector<int32>* mutable_parameter_block_sizes();
Packit ea1746
      void set_num_residuals(int num_residuals);
Packit ea1746
    };
Packit ea1746
Packit ea1746
Packit ea1746
The signature of the :class:`CostFunction` (number and sizes of input
Packit ea1746
parameter blocks and number of outputs) is stored in
Packit ea1746
:member:`CostFunction::parameter_block_sizes_` and
Packit ea1746
:member:`CostFunction::num_residuals_` respectively. User code
Packit ea1746
inheriting from this class is expected to set these two members with
Packit ea1746
the corresponding accessors. This information will be verified by the
Packit ea1746
:class:`Problem` when added with :func:`Problem::AddResidualBlock`.
Packit ea1746
Packit ea1746
.. function:: bool CostFunction::Evaluate(double const* const* parameters, double* residuals, double** jacobians)
Packit ea1746
Packit ea1746
   Compute the residual vector and the Jacobian matrices.
Packit ea1746
Packit ea1746
   ``parameters`` is an array of pointers to arrays containing the
Packit ea1746
   various parameter blocks. ``parameters`` has the same number of
Packit ea1746
   elements as :member:`CostFunction::parameter_block_sizes_` and the
Packit ea1746
   parameter blocks are in the same order as
Packit ea1746
   :member:`CostFunction::parameter_block_sizes_`.
Packit ea1746
Packit ea1746
   ``residuals`` is an array of size ``num_residuals_``.
Packit ea1746
Packit ea1746
   ``jacobians`` is an array of size
Packit ea1746
   :member:`CostFunction::parameter_block_sizes_` containing pointers
Packit ea1746
   to storage for Jacobian matrices corresponding to each parameter
Packit ea1746
   block. The Jacobian matrices are in the same order as
Packit ea1746
   :member:`CostFunction::parameter_block_sizes_`. ``jacobians[i]`` is
Packit ea1746
   an array that contains :member:`CostFunction::num_residuals_` x
Packit ea1746
   :member:`CostFunction::parameter_block_sizes_` ``[i]``
Packit ea1746
   elements. Each Jacobian matrix is stored in row-major order, i.e.,
Packit ea1746
   ``jacobians[i][r * parameter_block_size_[i] + c]`` =
Packit ea1746
   :math:`\frac{\partial residual[r]}{\partial parameters[i][c]}`
Packit ea1746
Packit ea1746
Packit ea1746
   If ``jacobians`` is ``NULL``, then no derivatives are returned;
Packit ea1746
   this is the case when computing cost only. If ``jacobians[i]`` is
Packit ea1746
   ``NULL``, then the Jacobian matrix corresponding to the
Packit ea1746
   :math:`i^{\textrm{th}}` parameter block must not be returned, this
Packit ea1746
   is the case when a parameter block is marked constant.
Packit ea1746
Packit ea1746
   **NOTE** The return value indicates whether the computation of the
Packit ea1746
   residuals and/or jacobians was successful or not.
Packit ea1746
Packit ea1746
   This can be used to communicate numerical failures in Jacobian
Packit ea1746
   computations for instance.
Packit ea1746
Packit ea1746
:class:`SizedCostFunction`
Packit ea1746
==========================
Packit ea1746
Packit ea1746
.. class:: SizedCostFunction
Packit ea1746
Packit ea1746
   If the size of the parameter blocks and the size of the residual
Packit ea1746
   vector is known at compile time (this is the common case),
Packit ea1746
   :class:`SizeCostFunction` can be used where these values can be
Packit ea1746
   specified as template parameters and the user only needs to
Packit ea1746
   implement :func:`CostFunction::Evaluate`.
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
    template
Packit ea1746
             int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0,
Packit ea1746
             int N5 = 0, int N6 = 0, int N7 = 0, int N8 = 0, int N9 = 0>
Packit ea1746
    class SizedCostFunction : public CostFunction {
Packit ea1746
     public:
Packit ea1746
      virtual bool Evaluate(double const* const* parameters,
Packit ea1746
                            double* residuals,
Packit ea1746
                            double** jacobians) const = 0;
Packit ea1746
    };
Packit ea1746
Packit ea1746
Packit ea1746
:class:`AutoDiffCostFunction`
Packit ea1746
=============================
Packit ea1746
Packit ea1746
.. class:: AutoDiffCostFunction
Packit ea1746
Packit ea1746
   Defining a :class:`CostFunction` or a :class:`SizedCostFunction`
Packit ea1746
   can be a tedious and error prone especially when computing
Packit ea1746
   derivatives.  To this end Ceres provides `automatic differentiation
Packit ea1746
   <http://en.wikipedia.org/wiki/Automatic_differentiation>`_.
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
     template 
Packit ea1746
            int kNumResiduals,  // Number of residuals, or ceres::DYNAMIC.
Packit ea1746
            int N0,       // Number of parameters in block 0.
Packit ea1746
            int N1 = 0,   // Number of parameters in block 1.
Packit ea1746
            int N2 = 0,   // Number of parameters in block 2.
Packit ea1746
            int N3 = 0,   // Number of parameters in block 3.
Packit ea1746
            int N4 = 0,   // Number of parameters in block 4.
Packit ea1746
            int N5 = 0,   // Number of parameters in block 5.
Packit ea1746
            int N6 = 0,   // Number of parameters in block 6.
Packit ea1746
            int N7 = 0,   // Number of parameters in block 7.
Packit ea1746
            int N8 = 0,   // Number of parameters in block 8.
Packit ea1746
            int N9 = 0>   // Number of parameters in block 9.
Packit ea1746
     class AutoDiffCostFunction : public
Packit ea1746
     SizedCostFunction<kNumResiduals, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9> {
Packit ea1746
      public:
Packit ea1746
       explicit AutoDiffCostFunction(CostFunctor* functor);
Packit ea1746
       // Ignore the template parameter kNumResiduals and use
Packit ea1746
       // num_residuals instead.
Packit ea1746
       AutoDiffCostFunction(CostFunctor* functor, int num_residuals);
Packit ea1746
     };
Packit ea1746
Packit ea1746
   To get an auto differentiated cost function, you must define a
Packit ea1746
   class with a templated ``operator()`` (a functor) that computes the
Packit ea1746
   cost function in terms of the template parameter ``T``. The
Packit ea1746
   autodiff framework substitutes appropriate ``Jet`` objects for
Packit ea1746
   ``T`` in order to compute the derivative when necessary, but this
Packit ea1746
   is hidden, and you should write the function as if ``T`` were a
Packit ea1746
   scalar type (e.g. a double-precision floating point number).
Packit ea1746
Packit ea1746
   The function must write the computed value in the last argument
Packit ea1746
   (the only non-``const`` one) and return true to indicate success.
Packit ea1746
Packit ea1746
   For example, consider a scalar error :math:`e = k - x^\top y`,
Packit ea1746
   where both :math:`x` and :math:`y` are two-dimensional vector
Packit ea1746
   parameters and :math:`k` is a constant. The form of this error,
Packit ea1746
   which is the difference between a constant and an expression, is a
Packit ea1746
   common pattern in least squares problems. For example, the value
Packit ea1746
   :math:`x^\top y` might be the model expectation for a series of
Packit ea1746
   measurements, where there is an instance of the cost function for
Packit ea1746
   each measurement :math:`k`.
Packit ea1746
Packit ea1746
   The actual cost added to the total problem is :math:`e^2`, or
Packit ea1746
   :math:`(k - x^\top y)^2`; however, the squaring is implicitly done
Packit ea1746
   by the optimization framework.
Packit ea1746
Packit ea1746
   To write an auto-differentiable cost function for the above model,
Packit ea1746
   first define the object
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
    class MyScalarCostFunctor {
Packit ea1746
      MyScalarCostFunctor(double k): k_(k) {}
Packit ea1746
Packit ea1746
      template <typename T>
Packit ea1746
      bool operator()(const T* const x , const T* const y, T* e) const {
Packit ea1746
        e[0] = k_ - x[0] * y[0] - x[1] * y[1];
Packit ea1746
        return true;
Packit ea1746
      }
Packit ea1746
Packit ea1746
     private:
Packit ea1746
      double k_;
Packit ea1746
    };
Packit ea1746
Packit ea1746
Packit ea1746
   Note that in the declaration of ``operator()`` the input parameters
Packit ea1746
   ``x`` and ``y`` come first, and are passed as const pointers to arrays
Packit ea1746
   of ``T``. If there were three input parameters, then the third input
Packit ea1746
   parameter would come after ``y``. The output is always the last
Packit ea1746
   parameter, and is also a pointer to an array. In the example above,
Packit ea1746
   ``e`` is a scalar, so only ``e[0]`` is set.
Packit ea1746
Packit ea1746
   Then given this class definition, the auto differentiated cost
Packit ea1746
   function for it can be constructed as follows.
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
    CostFunction* cost_function
Packit ea1746
        = new AutoDiffCostFunction<MyScalarCostFunctor, 1, 2, 2>(
Packit ea1746
            new MyScalarCostFunctor(1.0));              ^  ^  ^
Packit ea1746
                                                        |  |  |
Packit ea1746
                            Dimension of residual ------+  |  |
Packit ea1746
                            Dimension of x ----------------+  |
Packit ea1746
                            Dimension of y -------------------+
Packit ea1746
Packit ea1746
Packit ea1746
   In this example, there is usually an instance for each measurement
Packit ea1746
   of ``k``.
Packit ea1746
Packit ea1746
   In the instantiation above, the template parameters following
Packit ea1746
   ``MyScalarCostFunction``, ``<1, 2, 2>`` describe the functor as
Packit ea1746
   computing a 1-dimensional output from two arguments, both
Packit ea1746
   2-dimensional.
Packit ea1746
Packit ea1746
   :class:`AutoDiffCostFunction` also supports cost functions with a
Packit ea1746
   runtime-determined number of residuals. For example:
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
     CostFunction* cost_function
Packit ea1746
         = new AutoDiffCostFunction<MyScalarCostFunctor, DYNAMIC, 2, 2>(
Packit ea1746
             new CostFunctorWithDynamicNumResiduals(1.0),   ^     ^  ^
Packit ea1746
             runtime_number_of_residuals); <----+           |     |  |
Packit ea1746
                                                |           |     |  |
Packit ea1746
                                                |           |     |  |
Packit ea1746
               Actual number of residuals ------+           |     |  |
Packit ea1746
               Indicate dynamic number of residuals --------+     |  |
Packit ea1746
               Dimension of x ------------------------------------+  |
Packit ea1746
               Dimension of y ---------------------------------------+
Packit ea1746
Packit ea1746
   The framework can currently accommodate cost functions of up to 10
Packit ea1746
   independent variables, and there is no limit on the dimensionality
Packit ea1746
   of each of them.
Packit ea1746
Packit ea1746
   **WARNING 1** A common beginner's error when first using
Packit ea1746
   :class:`AutoDiffCostFunction` is to get the sizing wrong. In particular,
Packit ea1746
   there is a tendency to set the template parameters to (dimension of
Packit ea1746
   residual, number of parameters) instead of passing a dimension
Packit ea1746
   parameter for *every parameter block*. In the example above, that
Packit ea1746
   would be ``<MyScalarCostFunction, 1, 2>``, which is missing the 2
Packit ea1746
   as the last template argument.
Packit ea1746
Packit ea1746
Packit ea1746
:class:`DynamicAutoDiffCostFunction`
Packit ea1746
====================================
Packit ea1746
Packit ea1746
.. class:: DynamicAutoDiffCostFunction
Packit ea1746
Packit ea1746
   :class:`AutoDiffCostFunction` requires that the number of parameter
Packit ea1746
   blocks and their sizes be known at compile time. It also has an
Packit ea1746
   upper limit of 10 parameter blocks. In a number of applications,
Packit ea1746
   this is not enough e.g., Bezier curve fitting, Neural Network
Packit ea1746
   training etc.
Packit ea1746
Packit ea1746
     .. code-block:: c++
Packit ea1746
Packit ea1746
      template <typename CostFunctor, int Stride = 4>
Packit ea1746
      class DynamicAutoDiffCostFunction : public CostFunction {
Packit ea1746
      };
Packit ea1746
Packit ea1746
   In such cases :class:`DynamicAutoDiffCostFunction` can be
Packit ea1746
   used. Like :class:`AutoDiffCostFunction` the user must define a
Packit ea1746
   templated functor, but the signature of the functor differs
Packit ea1746
   slightly. The expected interface for the cost functors is:
Packit ea1746
Packit ea1746
     .. code-block:: c++
Packit ea1746
Packit ea1746
       struct MyCostFunctor {
Packit ea1746
         template<typename T>
Packit ea1746
         bool operator()(T const* const* parameters, T* residuals) const {
Packit ea1746
         }
Packit ea1746
       }
Packit ea1746
Packit ea1746
   Since the sizing of the parameters is done at runtime, you must
Packit ea1746
   also specify the sizes after creating the dynamic autodiff cost
Packit ea1746
   function. For example:
Packit ea1746
Packit ea1746
     .. code-block:: c++
Packit ea1746
Packit ea1746
       DynamicAutoDiffCostFunction<MyCostFunctor, 4>* cost_function =
Packit ea1746
         new DynamicAutoDiffCostFunction<MyCostFunctor, 4>(
Packit ea1746
           new MyCostFunctor());
Packit ea1746
       cost_function->AddParameterBlock(5);
Packit ea1746
       cost_function->AddParameterBlock(10);
Packit ea1746
       cost_function->SetNumResiduals(21);
Packit ea1746
Packit ea1746
   Under the hood, the implementation evaluates the cost function
Packit ea1746
   multiple times, computing a small set of the derivatives (four by
Packit ea1746
   default, controlled by the ``Stride`` template parameter) with each
Packit ea1746
   pass. There is a performance tradeoff with the size of the passes;
Packit ea1746
   Smaller sizes are more cache efficient but result in larger number
Packit ea1746
   of passes, and larger stride lengths can destroy cache-locality
Packit ea1746
   while reducing the number of passes over the cost function. The
Packit ea1746
   optimal value depends on the number and sizes of the various
Packit ea1746
   parameter blocks.
Packit ea1746
Packit ea1746
   As a rule of thumb, try using :class:`AutoDiffCostFunction` before
Packit ea1746
   you use :class:`DynamicAutoDiffCostFunction`.
Packit ea1746
Packit ea1746
:class:`NumericDiffCostFunction`
Packit ea1746
================================
Packit ea1746
Packit ea1746
.. class:: NumericDiffCostFunction
Packit ea1746
Packit ea1746
  In some cases, its not possible to define a templated cost functor,
Packit ea1746
  for example when the evaluation of the residual involves a call to a
Packit ea1746
  library function that you do not have control over.  In such a
Packit ea1746
  situation, `numerical differentiation
Packit ea1746
  <http://en.wikipedia.org/wiki/Numerical_differentiation>`_ can be
Packit ea1746
  used.
Packit ea1746
Packit ea1746
  .. NOTE ::
Packit ea1746
Packit ea1746
    TODO(sameeragarwal): Add documentation for the constructor and for
Packit ea1746
    NumericDiffOptions. Update DynamicNumericDiffOptions in a similar
Packit ea1746
    manner.
Packit ea1746
Packit ea1746
  .. code-block:: c++
Packit ea1746
Packit ea1746
      template 
Packit ea1746
                NumericDiffMethodType method = CENTRAL,
Packit ea1746
                int kNumResiduals,  // Number of residuals, or ceres::DYNAMIC.
Packit ea1746
                int N0,       // Number of parameters in block 0.
Packit ea1746
                int N1 = 0,   // Number of parameters in block 1.
Packit ea1746
                int N2 = 0,   // Number of parameters in block 2.
Packit ea1746
                int N3 = 0,   // Number of parameters in block 3.
Packit ea1746
                int N4 = 0,   // Number of parameters in block 4.
Packit ea1746
                int N5 = 0,   // Number of parameters in block 5.
Packit ea1746
                int N6 = 0,   // Number of parameters in block 6.
Packit ea1746
                int N7 = 0,   // Number of parameters in block 7.
Packit ea1746
                int N8 = 0,   // Number of parameters in block 8.
Packit ea1746
                int N9 = 0>   // Number of parameters in block 9.
Packit ea1746
      class NumericDiffCostFunction : public
Packit ea1746
      SizedCostFunction<kNumResiduals, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9> {
Packit ea1746
      };
Packit ea1746
Packit ea1746
  To get a numerically differentiated :class:`CostFunction`, you must
Packit ea1746
  define a class with a ``operator()`` (a functor) that computes the
Packit ea1746
  residuals. The functor must write the computed value in the last
Packit ea1746
  argument (the only non-``const`` one) and return ``true`` to
Packit ea1746
  indicate success.  Please see :class:`CostFunction` for details on
Packit ea1746
  how the return value may be used to impose simple constraints on the
Packit ea1746
  parameter block. e.g., an object of the form
Packit ea1746
Packit ea1746
  .. code-block:: c++
Packit ea1746
Packit ea1746
     struct ScalarFunctor {
Packit ea1746
      public:
Packit ea1746
       bool operator()(const double* const x1,
Packit ea1746
                       const double* const x2,
Packit ea1746
                       double* residuals) const;
Packit ea1746
     }
Packit ea1746
Packit ea1746
  For example, consider a scalar error :math:`e = k - x'y`, where both
Packit ea1746
  :math:`x` and :math:`y` are two-dimensional column vector
Packit ea1746
  parameters, the prime sign indicates transposition, and :math:`k` is
Packit ea1746
  a constant. The form of this error, which is the difference between
Packit ea1746
  a constant and an expression, is a common pattern in least squares
Packit ea1746
  problems. For example, the value :math:`x'y` might be the model
Packit ea1746
  expectation for a series of measurements, where there is an instance
Packit ea1746
  of the cost function for each measurement :math:`k`.
Packit ea1746
Packit ea1746
  To write an numerically-differentiable class:`CostFunction` for the
Packit ea1746
  above model, first define the object
Packit ea1746
Packit ea1746
  .. code-block::  c++
Packit ea1746
Packit ea1746
     class MyScalarCostFunctor {
Packit ea1746
       MyScalarCostFunctor(double k): k_(k) {}
Packit ea1746
Packit ea1746
       bool operator()(const double* const x,
Packit ea1746
                       const double* const y,
Packit ea1746
                       double* residuals) const {
Packit ea1746
         residuals[0] = k_ - x[0] * y[0] + x[1] * y[1];
Packit ea1746
         return true;
Packit ea1746
       }
Packit ea1746
Packit ea1746
      private:
Packit ea1746
       double k_;
Packit ea1746
     };
Packit ea1746
Packit ea1746
  Note that in the declaration of ``operator()`` the input parameters
Packit ea1746
  ``x`` and ``y`` come first, and are passed as const pointers to
Packit ea1746
  arrays of ``double`` s. If there were three input parameters, then
Packit ea1746
  the third input parameter would come after ``y``. The output is
Packit ea1746
  always the last parameter, and is also a pointer to an array. In the
Packit ea1746
  example above, the residual is a scalar, so only ``residuals[0]`` is
Packit ea1746
  set.
Packit ea1746
Packit ea1746
  Then given this class definition, the numerically differentiated
Packit ea1746
  :class:`CostFunction` with central differences used for computing
Packit ea1746
  the derivative can be constructed as follows.
Packit ea1746
Packit ea1746
  .. code-block:: c++
Packit ea1746
Packit ea1746
    CostFunction* cost_function
Packit ea1746
        = new NumericDiffCostFunction<MyScalarCostFunctor, CENTRAL, 1, 2, 2>(
Packit ea1746
            new MyScalarCostFunctor(1.0));                    ^     ^  ^  ^
Packit ea1746
                                                              |     |  |  |
Packit ea1746
                                  Finite Differencing Scheme -+     |  |  |
Packit ea1746
                                  Dimension of residual ------------+  |  |
Packit ea1746
                                  Dimension of x ----------------------+  |
Packit ea1746
                                  Dimension of y -------------------------+
Packit ea1746
Packit ea1746
  In this example, there is usually an instance for each measurement
Packit ea1746
  of `k`.
Packit ea1746
Packit ea1746
  In the instantiation above, the template parameters following
Packit ea1746
  ``MyScalarCostFunctor``, ``1, 2, 2``, describe the functor as
Packit ea1746
  computing a 1-dimensional output from two arguments, both
Packit ea1746
  2-dimensional.
Packit ea1746
Packit ea1746
  NumericDiffCostFunction also supports cost functions with a
Packit ea1746
  runtime-determined number of residuals. For example:
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
     CostFunction* cost_function
Packit ea1746
         = new NumericDiffCostFunction<MyScalarCostFunctor, CENTRAL, DYNAMIC, 2, 2>(
Packit ea1746
             new CostFunctorWithDynamicNumResiduals(1.0),               ^     ^  ^
Packit ea1746
             TAKE_OWNERSHIP,                                            |     |  |
Packit ea1746
             runtime_number_of_residuals); <----+                       |     |  |
Packit ea1746
                                                |                       |     |  |
Packit ea1746
                                                |                       |     |  |
Packit ea1746
               Actual number of residuals ------+                       |     |  |
Packit ea1746
               Indicate dynamic number of residuals --------------------+     |  |
Packit ea1746
               Dimension of x ------------------------------------------------+  |
Packit ea1746
               Dimension of y ---------------------------------------------------+
Packit ea1746
Packit ea1746
Packit ea1746
  The framework can currently accommodate cost functions of up to 10
Packit ea1746
  independent variables, and there is no limit on the dimensionality
Packit ea1746
  of each of them.
Packit ea1746
Packit ea1746
  There are three available numeric differentiation schemes in ceres-solver:
Packit ea1746
Packit ea1746
  The ``FORWARD`` difference method, which approximates :math:`f'(x)`
Packit ea1746
  by computing :math:`\frac{f(x+h)-f(x)}{h}`, computes the cost
Packit ea1746
  function one additional time at :math:`x+h`. It is the fastest but
Packit ea1746
  least accurate method.
Packit ea1746
Packit ea1746
  The ``CENTRAL`` difference method is more accurate at the cost of
Packit ea1746
  twice as many function evaluations than forward difference,
Packit ea1746
  estimating :math:`f'(x)` by computing
Packit ea1746
  :math:`\frac{f(x+h)-f(x-h)}{2h}`.
Packit ea1746
Packit ea1746
  The ``RIDDERS`` difference method[Ridders]_ is an adaptive scheme
Packit ea1746
  that estimates derivatives by performing multiple central
Packit ea1746
  differences at varying scales. Specifically, the algorithm starts at
Packit ea1746
  a certain :math:`h` and as the derivative is estimated, this step
Packit ea1746
  size decreases.  To conserve function evaluations and estimate the
Packit ea1746
  derivative error, the method performs Richardson extrapolations
Packit ea1746
  between the tested step sizes.  The algorithm exhibits considerably
Packit ea1746
  higher accuracy, but does so by additional evaluations of the cost
Packit ea1746
  function.
Packit ea1746
Packit ea1746
  Consider using ``CENTRAL`` differences to begin with. Based on the
Packit ea1746
  results, either try forward difference to improve performance or
Packit ea1746
  Ridders' method to improve accuracy.
Packit ea1746
Packit ea1746
  **WARNING** A common beginner's error when first using
Packit ea1746
  :class:`NumericDiffCostFunction` is to get the sizing wrong. In
Packit ea1746
  particular, there is a tendency to set the template parameters to
Packit ea1746
  (dimension of residual, number of parameters) instead of passing a
Packit ea1746
  dimension parameter for *every parameter*. In the example above,
Packit ea1746
  that would be ``<MyScalarCostFunctor, 1, 2>``, which is missing the
Packit ea1746
  last ``2`` argument. Please be careful when setting the size
Packit ea1746
  parameters.
Packit ea1746
Packit ea1746
Packit ea1746
Numeric Differentiation & LocalParameterization
Packit ea1746
-----------------------------------------------
Packit ea1746
Packit ea1746
   If your cost function depends on a parameter block that must lie on
Packit ea1746
   a manifold and the functor cannot be evaluated for values of that
Packit ea1746
   parameter block not on the manifold then you may have problems
Packit ea1746
   numerically differentiating such functors.
Packit ea1746
Packit ea1746
   This is because numeric differentiation in Ceres is performed by
Packit ea1746
   perturbing the individual coordinates of the parameter blocks that
Packit ea1746
   a cost functor depends on. In doing so, we assume that the
Packit ea1746
   parameter blocks live in an Euclidean space and ignore the
Packit ea1746
   structure of manifold that they live As a result some of the
Packit ea1746
   perturbations may not lie on the manifold corresponding to the
Packit ea1746
   parameter block.
Packit ea1746
Packit ea1746
   For example consider a four dimensional parameter block that is
Packit ea1746
   interpreted as a unit Quaternion. Perturbing the coordinates of
Packit ea1746
   this parameter block will violate the unit norm property of the
Packit ea1746
   parameter block.
Packit ea1746
Packit ea1746
   Fixing this problem requires that :class:`NumericDiffCostFunction`
Packit ea1746
   be aware of the :class:`LocalParameterization` associated with each
Packit ea1746
   parameter block and only generate perturbations in the local
Packit ea1746
   tangent space of each parameter block.
Packit ea1746
Packit ea1746
   For now this is not considered to be a serious enough problem to
Packit ea1746
   warrant changing the :class:`NumericDiffCostFunction` API. Further,
Packit ea1746
   in most cases it is relatively straightforward to project a point
Packit ea1746
   off the manifold back onto the manifold before using it in the
Packit ea1746
   functor. For example in case of the Quaternion, normalizing the
Packit ea1746
   4-vector before using it does the trick.
Packit ea1746
Packit ea1746
   **Alternate Interface**
Packit ea1746
Packit ea1746
   For a variety of reasons, including compatibility with legacy code,
Packit ea1746
   :class:`NumericDiffCostFunction` can also take
Packit ea1746
   :class:`CostFunction` objects as input. The following describes
Packit ea1746
   how.
Packit ea1746
Packit ea1746
   To get a numerically differentiated cost function, define a
Packit ea1746
   subclass of :class:`CostFunction` such that the
Packit ea1746
   :func:`CostFunction::Evaluate` function ignores the ``jacobians``
Packit ea1746
   parameter. The numeric differentiation wrapper will fill in the
Packit ea1746
   jacobian parameter if necessary by repeatedly calling the
Packit ea1746
   :func:`CostFunction::Evaluate` with small changes to the
Packit ea1746
   appropriate parameters, and computing the slope. For performance,
Packit ea1746
   the numeric differentiation wrapper class is templated on the
Packit ea1746
   concrete cost function, even though it could be implemented only in
Packit ea1746
   terms of the :class:`CostFunction` interface.
Packit ea1746
Packit ea1746
   The numerically differentiated version of a cost function for a
Packit ea1746
   cost function can be constructed as follows:
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
     CostFunction* cost_function
Packit ea1746
         = new NumericDiffCostFunction<MyCostFunction, CENTRAL, 1, 4, 8>(
Packit ea1746
             new MyCostFunction(...), TAKE_OWNERSHIP);
Packit ea1746
Packit ea1746
   where ``MyCostFunction`` has 1 residual and 2 parameter blocks with
Packit ea1746
   sizes 4 and 8 respectively. Look at the tests for a more detailed
Packit ea1746
   example.
Packit ea1746
Packit ea1746
:class:`DynamicNumericDiffCostFunction`
Packit ea1746
=======================================
Packit ea1746
Packit ea1746
.. class:: DynamicNumericDiffCostFunction
Packit ea1746
Packit ea1746
   Like :class:`AutoDiffCostFunction` :class:`NumericDiffCostFunction`
Packit ea1746
   requires that the number of parameter blocks and their sizes be
Packit ea1746
   known at compile time. It also has an upper limit of 10 parameter
Packit ea1746
   blocks. In a number of applications, this is not enough.
Packit ea1746
Packit ea1746
     .. code-block:: c++
Packit ea1746
Packit ea1746
      template <typename CostFunctor, NumericDiffMethodType method = CENTRAL>
Packit ea1746
      class DynamicNumericDiffCostFunction : public CostFunction {
Packit ea1746
      };
Packit ea1746
Packit ea1746
   In such cases when numeric differentiation is desired,
Packit ea1746
   :class:`DynamicNumericDiffCostFunction` can be used.
Packit ea1746
Packit ea1746
   Like :class:`NumericDiffCostFunction` the user must define a
Packit ea1746
   functor, but the signature of the functor differs slightly. The
Packit ea1746
   expected interface for the cost functors is:
Packit ea1746
Packit ea1746
     .. code-block:: c++
Packit ea1746
Packit ea1746
       struct MyCostFunctor {
Packit ea1746
         bool operator()(double const* const* parameters, double* residuals) const {
Packit ea1746
         }
Packit ea1746
       }
Packit ea1746
Packit ea1746
   Since the sizing of the parameters is done at runtime, you must
Packit ea1746
   also specify the sizes after creating the dynamic numeric diff cost
Packit ea1746
   function. For example:
Packit ea1746
Packit ea1746
     .. code-block:: c++
Packit ea1746
Packit ea1746
       DynamicNumericDiffCostFunction<MyCostFunctor>* cost_function =
Packit ea1746
         new DynamicNumericDiffCostFunction<MyCostFunctor>(new MyCostFunctor);
Packit ea1746
       cost_function->AddParameterBlock(5);
Packit ea1746
       cost_function->AddParameterBlock(10);
Packit ea1746
       cost_function->SetNumResiduals(21);
Packit ea1746
Packit ea1746
   As a rule of thumb, try using :class:`NumericDiffCostFunction` before
Packit ea1746
   you use :class:`DynamicNumericDiffCostFunction`.
Packit ea1746
Packit ea1746
   **WARNING** The same caution about mixing local parameterizations
Packit ea1746
   with numeric differentiation applies as is the case with
Packit ea1746
   :class:`NumericDiffCostFunction`.
Packit ea1746
Packit ea1746
:class:`CostFunctionToFunctor`
Packit ea1746
==============================
Packit ea1746
Packit ea1746
.. class:: CostFunctionToFunctor
Packit ea1746
Packit ea1746
   :class:`CostFunctionToFunctor` is an adapter class that allows
Packit ea1746
   users to use :class:`CostFunction` objects in templated functors
Packit ea1746
   which are to be used for automatic differentiation. This allows
Packit ea1746
   the user to seamlessly mix analytic, numeric and automatic
Packit ea1746
   differentiation.
Packit ea1746
Packit ea1746
   For example, let us assume that
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
     class IntrinsicProjection : public SizedCostFunction<2, 5, 3> {
Packit ea1746
       public:
Packit ea1746
         IntrinsicProjection(const double* observation);
Packit ea1746
         virtual bool Evaluate(double const* const* parameters,
Packit ea1746
                               double* residuals,
Packit ea1746
                               double** jacobians) const;
Packit ea1746
     };
Packit ea1746
Packit ea1746
   is a :class:`CostFunction` that implements the projection of a
Packit ea1746
   point in its local coordinate system onto its image plane and
Packit ea1746
   subtracts it from the observed point projection. It can compute its
Packit ea1746
   residual and either via analytic or numerical differentiation can
Packit ea1746
   compute its jacobians.
Packit ea1746
Packit ea1746
   Now we would like to compose the action of this
Packit ea1746
   :class:`CostFunction` with the action of camera extrinsics, i.e.,
Packit ea1746
   rotation and translation. Say we have a templated function
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
      template<typename T>
Packit ea1746
      void RotateAndTranslatePoint(const T* rotation,
Packit ea1746
                                   const T* translation,
Packit ea1746
                                   const T* point,
Packit ea1746
                                   T* result);
Packit ea1746
Packit ea1746
Packit ea1746
   Then we can now do the following,
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
    struct CameraProjection {
Packit ea1746
      CameraProjection(double* observation)
Packit ea1746
      : intrinsic_projection_(new IntrinsicProjection(observation)) {
Packit ea1746
      }
Packit ea1746
Packit ea1746
      template <typename T>
Packit ea1746
      bool operator()(const T* rotation,
Packit ea1746
                      const T* translation,
Packit ea1746
                      const T* intrinsics,
Packit ea1746
                      const T* point,
Packit ea1746
                      T* residual) const {
Packit ea1746
        T transformed_point[3];
Packit ea1746
        RotateAndTranslatePoint(rotation, translation, point, transformed_point);
Packit ea1746
Packit ea1746
        // Note that we call intrinsic_projection_, just like it was
Packit ea1746
        // any other templated functor.
Packit ea1746
        return intrinsic_projection_(intrinsics, transformed_point, residual);
Packit ea1746
      }
Packit ea1746
Packit ea1746
     private:
Packit ea1746
      CostFunctionToFunctor<2,5,3> intrinsic_projection_;
Packit ea1746
    };
Packit ea1746
Packit ea1746
   Note that :class:`CostFunctionToFunctor` takes ownership of the
Packit ea1746
   :class:`CostFunction` that was passed in to the constructor.
Packit ea1746
Packit ea1746
   In the above example, we assumed that ``IntrinsicProjection`` is a
Packit ea1746
   ``CostFunction`` capable of evaluating its value and its
Packit ea1746
   derivatives. Suppose, if that were not the case and
Packit ea1746
   ``IntrinsicProjection`` was defined as follows:
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
    struct IntrinsicProjection
Packit ea1746
      IntrinsicProjection(const double* observation) {
Packit ea1746
        observation_[0] = observation[0];
Packit ea1746
        observation_[1] = observation[1];
Packit ea1746
      }
Packit ea1746
Packit ea1746
      bool operator()(const double* calibration,
Packit ea1746
                      const double* point,
Packit ea1746
                      double* residuals) {
Packit ea1746
        double projection[2];
Packit ea1746
        ThirdPartyProjectionFunction(calibration, point, projection);
Packit ea1746
        residuals[0] = observation_[0] - projection[0];
Packit ea1746
        residuals[1] = observation_[1] - projection[1];
Packit ea1746
        return true;
Packit ea1746
      }
Packit ea1746
     double observation_[2];
Packit ea1746
    };
Packit ea1746
Packit ea1746
Packit ea1746
  Here ``ThirdPartyProjectionFunction`` is some third party library
Packit ea1746
  function that we have no control over. So this function can compute
Packit ea1746
  its value and we would like to use numeric differentiation to
Packit ea1746
  compute its derivatives. In this case we can use a combination of
Packit ea1746
  ``NumericDiffCostFunction`` and ``CostFunctionToFunctor`` to get the
Packit ea1746
  job done.
Packit ea1746
Packit ea1746
  .. code-block:: c++
Packit ea1746
Packit ea1746
   struct CameraProjection {
Packit ea1746
     CameraProjection(double* observation)
Packit ea1746
       intrinsic_projection_(
Packit ea1746
         new NumericDiffCostFunction<IntrinsicProjection, CENTRAL, 2, 5, 3>(
Packit ea1746
           new IntrinsicProjection(observation)) {
Packit ea1746
     }
Packit ea1746
Packit ea1746
     template <typename T>
Packit ea1746
     bool operator()(const T* rotation,
Packit ea1746
                     const T* translation,
Packit ea1746
                     const T* intrinsics,
Packit ea1746
                     const T* point,
Packit ea1746
                     T* residuals) const {
Packit ea1746
       T transformed_point[3];
Packit ea1746
       RotateAndTranslatePoint(rotation, translation, point, transformed_point);
Packit ea1746
       return intrinsic_projection_(intrinsics, transformed_point, residual);
Packit ea1746
     }
Packit ea1746
Packit ea1746
    private:
Packit ea1746
     CostFunctionToFunctor<2,5,3> intrinsic_projection_;
Packit ea1746
   };
Packit ea1746
Packit ea1746
:class:`DynamicCostFunctionToFunctor`
Packit ea1746
=====================================
Packit ea1746
Packit ea1746
.. class:: DynamicCostFunctionToFunctor
Packit ea1746
Packit ea1746
   :class:`DynamicCostFunctionToFunctor` provides the same functionality as
Packit ea1746
   :class:`CostFunctionToFunctor` for cases where the number and size of the
Packit ea1746
   parameter vectors and residuals are not known at compile-time. The API
Packit ea1746
   provided by :class:`DynamicCostFunctionToFunctor` matches what would be
Packit ea1746
   expected by :class:`DynamicAutoDiffCostFunction`, i.e. it provides a
Packit ea1746
   templated functor of this form:
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
    template<typename T>
Packit ea1746
    bool operator()(T const* const* parameters, T* residuals) const;
Packit ea1746
Packit ea1746
   Similar to the example given for :class:`CostFunctionToFunctor`, let us
Packit ea1746
   assume that
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
     class IntrinsicProjection : public CostFunction {
Packit ea1746
       public:
Packit ea1746
         IntrinsicProjection(const double* observation);
Packit ea1746
         virtual bool Evaluate(double const* const* parameters,
Packit ea1746
                               double* residuals,
Packit ea1746
                               double** jacobians) const;
Packit ea1746
     };
Packit ea1746
Packit ea1746
   is a :class:`CostFunction` that projects a point in its local coordinate
Packit ea1746
   system onto its image plane and subtracts it from the observed point
Packit ea1746
   projection.
Packit ea1746
Packit ea1746
   Using this :class:`CostFunction` in a templated functor would then look like
Packit ea1746
   this:
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
    struct CameraProjection {
Packit ea1746
      CameraProjection(double* observation)
Packit ea1746
          : intrinsic_projection_(new IntrinsicProjection(observation)) {
Packit ea1746
      }
Packit ea1746
Packit ea1746
      template <typename T>
Packit ea1746
      bool operator()(T const* const* parameters,
Packit ea1746
                      T* residual) const {
Packit ea1746
        const T* rotation = parameters[0];
Packit ea1746
        const T* translation = parameters[1];
Packit ea1746
        const T* intrinsics = parameters[2];
Packit ea1746
        const T* point = parameters[3];
Packit ea1746
Packit ea1746
        T transformed_point[3];
Packit ea1746
        RotateAndTranslatePoint(rotation, translation, point, transformed_point);
Packit ea1746
Packit ea1746
        const T* projection_parameters[2];
Packit ea1746
        projection_parameters[0] = intrinsics;
Packit ea1746
        projection_parameters[1] = transformed_point;
Packit ea1746
        return intrinsic_projection_(projection_parameters, residual);
Packit ea1746
      }
Packit ea1746
Packit ea1746
     private:
Packit ea1746
      DynamicCostFunctionToFunctor intrinsic_projection_;
Packit ea1746
    };
Packit ea1746
Packit ea1746
   Like :class:`CostFunctionToFunctor`, :class:`DynamicCostFunctionToFunctor`
Packit ea1746
   takes ownership of the :class:`CostFunction` that was passed in to the
Packit ea1746
   constructor.
Packit ea1746
Packit ea1746
:class:`ConditionedCostFunction`
Packit ea1746
================================
Packit ea1746
Packit ea1746
.. class:: ConditionedCostFunction
Packit ea1746
Packit ea1746
   This class allows you to apply different conditioning to the residual
Packit ea1746
   values of a wrapped cost function. An example where this is useful is
Packit ea1746
   where you have an existing cost function that produces N values, but you
Packit ea1746
   want the total cost to be something other than just the sum of these
Packit ea1746
   squared values - maybe you want to apply a different scaling to some
Packit ea1746
   values, to change their contribution to the cost.
Packit ea1746
Packit ea1746
   Usage:
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
       //  my_cost_function produces N residuals
Packit ea1746
       CostFunction* my_cost_function = ...
Packit ea1746
       CHECK_EQ(N, my_cost_function->num_residuals());
Packit ea1746
       vector<CostFunction*> conditioners;
Packit ea1746
Packit ea1746
       //  Make N 1x1 cost functions (1 parameter, 1 residual)
Packit ea1746
       CostFunction* f_1 = ...
Packit ea1746
       conditioners.push_back(f_1);
Packit ea1746
Packit ea1746
       CostFunction* f_N = ...
Packit ea1746
       conditioners.push_back(f_N);
Packit ea1746
       ConditionedCostFunction* ccf =
Packit ea1746
         new ConditionedCostFunction(my_cost_function, conditioners);
Packit ea1746
Packit ea1746
Packit ea1746
   Now ``ccf`` 's ``residual[i]`` (i=0..N-1) will be passed though the
Packit ea1746
   :math:`i^{\text{th}}` conditioner.
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
      ccf_residual[i] = f_i(my_cost_function_residual[i])
Packit ea1746
Packit ea1746
   and the Jacobian will be affected appropriately.
Packit ea1746
Packit ea1746
Packit ea1746
:class:`GradientChecker`
Packit ea1746
================================
Packit ea1746
Packit ea1746
.. class:: GradientChecker
Packit ea1746
Packit ea1746
    This class compares the Jacobians returned by a cost function against
Packit ea1746
    derivatives estimated using finite differencing. It is meant as a tool for
Packit ea1746
    unit testing, giving you more fine-grained control than the check_gradients
Packit ea1746
    option in the solver options.
Packit ea1746
Packit ea1746
    The condition enforced is that
Packit ea1746
Packit ea1746
    .. math:: \forall{i,j}: \frac{J_{ij} - J'_{ij}}{max_{ij}(J_{ij} - J'_{ij})} < r
Packit ea1746
Packit ea1746
    where :math:`J_{ij}` is the jacobian as computed by the supplied cost
Packit ea1746
    function (by the user) multiplied by the local parameterization Jacobian,
Packit ea1746
    :math:`J'_{ij}` is the jacobian as computed by finite differences,
Packit ea1746
    multiplied by the local parameterization Jacobian as well, and :math:`r`
Packit ea1746
    is the relative precision.
Packit ea1746
Packit ea1746
   Usage:
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
       //  my_cost_function takes two parameter blocks. The first has a local
Packit ea1746
       //  parameterization associated with it.
Packit ea1746
       CostFunction* my_cost_function = ...
Packit ea1746
       LocalParameterization* my_parameterization = ...
Packit ea1746
       NumericDiffOptions numeric_diff_options;
Packit ea1746
Packit ea1746
       std::vector<LocalParameterization*> local_parameterizations;
Packit ea1746
       local_parameterizations.push_back(my_parameterization);
Packit ea1746
       local_parameterizations.push_back(NULL);
Packit ea1746
Packit ea1746
       std::vector parameter1;
Packit ea1746
       std::vector parameter2;
Packit ea1746
       // Fill parameter 1 & 2 with test data...
Packit ea1746
Packit ea1746
       std::vector<double*> parameter_blocks;
Packit ea1746
       parameter_blocks.push_back(parameter1.data());
Packit ea1746
       parameter_blocks.push_back(parameter2.data());
Packit ea1746
Packit ea1746
       GradientChecker gradient_checker(my_cost_function,
Packit ea1746
           local_parameterizations, numeric_diff_options);
Packit ea1746
       GradientCheckResults results;
Packit ea1746
       if (!gradient_checker.Probe(parameter_blocks.data(), 1e-9, &results) {
Packit ea1746
         LOG(ERROR) << "An error has occurred:\n" << results.error_log;
Packit ea1746
       }
Packit ea1746
Packit ea1746
Packit ea1746
:class:`NormalPrior`
Packit ea1746
====================
Packit ea1746
Packit ea1746
.. class:: NormalPrior
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
     class NormalPrior: public CostFunction {
Packit ea1746
      public:
Packit ea1746
       // Check that the number of rows in the vector b are the same as the
Packit ea1746
       // number of columns in the matrix A, crash otherwise.
Packit ea1746
       NormalPrior(const Matrix& A, const Vector& b);
Packit ea1746
Packit ea1746
       virtual bool Evaluate(double const* const* parameters,
Packit ea1746
                             double* residuals,
Packit ea1746
                             double** jacobians) const;
Packit ea1746
      };
Packit ea1746
Packit ea1746
   Implements a cost function of the form
Packit ea1746
Packit ea1746
   .. math::  cost(x) = ||A(x - b)||^2
Packit ea1746
Packit ea1746
   where, the matrix :math:`A` and the vector :math:`b` are fixed and :math:`x`
Packit ea1746
   is the variable. In case the user is interested in implementing a cost
Packit ea1746
   function of the form
Packit ea1746
Packit ea1746
  .. math::  cost(x) = (x - \mu)^T S^{-1} (x - \mu)
Packit ea1746
Packit ea1746
  where, :math:`\mu` is a vector and :math:`S` is a covariance matrix,
Packit ea1746
  then, :math:`A = S^{-1/2}`, i.e the matrix :math:`A` is the square
Packit ea1746
  root of the inverse of the covariance, also known as the stiffness
Packit ea1746
  matrix. There are however no restrictions on the shape of
Packit ea1746
  :math:`A`. It is free to be rectangular, which would be the case if
Packit ea1746
  the covariance matrix :math:`S` is rank deficient.
Packit ea1746
Packit ea1746
Packit ea1746
Packit ea1746
.. _`section-loss_function`:
Packit ea1746
Packit ea1746
:class:`LossFunction`
Packit ea1746
=====================
Packit ea1746
Packit ea1746
.. class:: LossFunction
Packit ea1746
Packit ea1746
   For least squares problems where the minimization may encounter
Packit ea1746
   input terms that contain outliers, that is, completely bogus
Packit ea1746
   measurements, it is important to use a loss function that reduces
Packit ea1746
   their influence.
Packit ea1746
Packit ea1746
   Consider a structure from motion problem. The unknowns are 3D
Packit ea1746
   points and camera parameters, and the measurements are image
Packit ea1746
   coordinates describing the expected reprojected position for a
Packit ea1746
   point in a camera. For example, we want to model the geometry of a
Packit ea1746
   street scene with fire hydrants and cars, observed by a moving
Packit ea1746
   camera with unknown parameters, and the only 3D points we care
Packit ea1746
   about are the pointy tippy-tops of the fire hydrants. Our magic
Packit ea1746
   image processing algorithm, which is responsible for producing the
Packit ea1746
   measurements that are input to Ceres, has found and matched all
Packit ea1746
   such tippy-tops in all image frames, except that in one of the
Packit ea1746
   frame it mistook a car's headlight for a hydrant. If we didn't do
Packit ea1746
   anything special the residual for the erroneous measurement will
Packit ea1746
   result in the entire solution getting pulled away from the optimum
Packit ea1746
   to reduce the large error that would otherwise be attributed to the
Packit ea1746
   wrong measurement.
Packit ea1746
Packit ea1746
   Using a robust loss function, the cost for large residuals is
Packit ea1746
   reduced. In the example above, this leads to outlier terms getting
Packit ea1746
   down-weighted so they do not overly influence the final solution.
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
    class LossFunction {
Packit ea1746
     public:
Packit ea1746
      virtual void Evaluate(double s, double out[3]) const = 0;
Packit ea1746
    };
Packit ea1746
Packit ea1746
Packit ea1746
   The key method is :func:`LossFunction::Evaluate`, which given a
Packit ea1746
   non-negative scalar ``s``, computes
Packit ea1746
Packit ea1746
   .. math:: out = \begin{bmatrix}\rho(s), & \rho'(s), & \rho''(s)\end{bmatrix}
Packit ea1746
Packit ea1746
   Here the convention is that the contribution of a term to the cost
Packit ea1746
   function is given by :math:`\frac{1}{2}\rho(s)`, where :math:`s
Packit ea1746
   =\|f_i\|^2`. Calling the method with a negative value of :math:`s`
Packit ea1746
   is an error and the implementations are not required to handle that
Packit ea1746
   case.
Packit ea1746
Packit ea1746
   Most sane choices of :math:`\rho` satisfy:
Packit ea1746
Packit ea1746
   .. math::
Packit ea1746
Packit ea1746
      \rho(0) &= 0\\
Packit ea1746
      \rho'(0) &= 1\\
Packit ea1746
      \rho'(s) &< 1 \text{ in the outlier region}\\
Packit ea1746
      \rho''(s) &< 0 \text{ in the outlier region}
Packit ea1746
Packit ea1746
   so that they mimic the squared cost for small residuals.
Packit ea1746
Packit ea1746
   **Scaling**
Packit ea1746
Packit ea1746
   Given one robustifier :math:`\rho(s)` one can change the length
Packit ea1746
   scale at which robustification takes place, by adding a scale
Packit ea1746
   factor :math:`a > 0` which gives us :math:`\rho(s,a) = a^2 \rho(s /
Packit ea1746
   a^2)` and the first and second derivatives as :math:`\rho'(s /
Packit ea1746
   a^2)` and :math:`(1 / a^2) \rho''(s / a^2)` respectively.
Packit ea1746
Packit ea1746
Packit ea1746
   The reason for the appearance of squaring is that :math:`a` is in
Packit ea1746
   the units of the residual vector norm whereas :math:`s` is a squared
Packit ea1746
   norm. For applications it is more convenient to specify :math:`a` than
Packit ea1746
   its square.
Packit ea1746
Packit ea1746
Instances
Packit ea1746
---------
Packit ea1746
Packit ea1746
Ceres includes a number of predefined loss functions. For simplicity
Packit ea1746
we described their unscaled versions. The figure below illustrates
Packit ea1746
their shape graphically. More details can be found in
Packit ea1746
``include/ceres/loss_function.h``.
Packit ea1746
Packit ea1746
.. figure:: loss.png
Packit ea1746
   :figwidth: 500px
Packit ea1746
   :height: 400px
Packit ea1746
   :align: center
Packit ea1746
Packit ea1746
   Shape of the various common loss functions.
Packit ea1746
Packit ea1746
.. class:: TrivialLoss
Packit ea1746
Packit ea1746
      .. math:: \rho(s) = s
Packit ea1746
Packit ea1746
.. class:: HuberLoss
Packit ea1746
Packit ea1746
   .. math:: \rho(s) = \begin{cases} s & s \le 1\\ 2 \sqrt{s} - 1 & s > 1 \end{cases}
Packit ea1746
Packit ea1746
.. class:: SoftLOneLoss
Packit ea1746
Packit ea1746
   .. math:: \rho(s) = 2 (\sqrt{1+s} - 1)
Packit ea1746
Packit ea1746
.. class:: CauchyLoss
Packit ea1746
Packit ea1746
   .. math:: \rho(s) = \log(1 + s)
Packit ea1746
Packit ea1746
.. class:: ArctanLoss
Packit ea1746
Packit ea1746
   .. math:: \rho(s) = \arctan(s)
Packit ea1746
Packit ea1746
.. class:: TolerantLoss
Packit ea1746
Packit ea1746
   .. math:: \rho(s,a,b) = b \log(1 + e^{(s - a) / b}) - b \log(1 + e^{-a / b})
Packit ea1746
Packit ea1746
.. class:: ComposedLoss
Packit ea1746
Packit ea1746
   Given two loss functions ``f`` and ``g``, implements the loss
Packit ea1746
   function ``h(s) = f(g(s))``.
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
      class ComposedLoss : public LossFunction {
Packit ea1746
       public:
Packit ea1746
        explicit ComposedLoss(const LossFunction* f,
Packit ea1746
                              Ownership ownership_f,
Packit ea1746
                              const LossFunction* g,
Packit ea1746
                              Ownership ownership_g);
Packit ea1746
      };
Packit ea1746
Packit ea1746
.. class:: ScaledLoss
Packit ea1746
Packit ea1746
   Sometimes you want to simply scale the output value of the
Packit ea1746
   robustifier. For example, you might want to weight different error
Packit ea1746
   terms differently (e.g., weight pixel reprojection errors
Packit ea1746
   differently from terrain errors).
Packit ea1746
Packit ea1746
   Given a loss function :math:`\rho(s)` and a scalar :math:`a`, :class:`ScaledLoss`
Packit ea1746
   implements the function :math:`a \rho(s)`.
Packit ea1746
Packit ea1746
   Since we treat a ``NULL`` Loss function as the Identity loss
Packit ea1746
   function, :math:`rho` = ``NULL``: is a valid input and will result
Packit ea1746
   in the input being scaled by :math:`a`. This provides a simple way
Packit ea1746
   of implementing a scaled ResidualBlock.
Packit ea1746
Packit ea1746
.. class:: LossFunctionWrapper
Packit ea1746
Packit ea1746
   Sometimes after the optimization problem has been constructed, we
Packit ea1746
   wish to mutate the scale of the loss function. For example, when
Packit ea1746
   performing estimation from data which has substantial outliers,
Packit ea1746
   convergence can be improved by starting out with a large scale,
Packit ea1746
   optimizing the problem and then reducing the scale. This can have
Packit ea1746
   better convergence behavior than just using a loss function with a
Packit ea1746
   small scale.
Packit ea1746
Packit ea1746
   This templated class allows the user to implement a loss function
Packit ea1746
   whose scale can be mutated after an optimization problem has been
Packit ea1746
   constructed, e.g,
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
     Problem problem;
Packit ea1746
Packit ea1746
     // Add parameter blocks
Packit ea1746
Packit ea1746
     CostFunction* cost_function =
Packit ea1746
         new AutoDiffCostFunction < UW_Camera_Mapper, 2, 9, 3>(
Packit ea1746
             new UW_Camera_Mapper(feature_x, feature_y));
Packit ea1746
Packit ea1746
     LossFunctionWrapper* loss_function(new HuberLoss(1.0), TAKE_OWNERSHIP);
Packit ea1746
     problem.AddResidualBlock(cost_function, loss_function, parameters);
Packit ea1746
Packit ea1746
     Solver::Options options;
Packit ea1746
     Solver::Summary summary;
Packit ea1746
     Solve(options, &problem, &summary);
Packit ea1746
Packit ea1746
     loss_function->Reset(new HuberLoss(1.0), TAKE_OWNERSHIP);
Packit ea1746
     Solve(options, &problem, &summary);
Packit ea1746
Packit ea1746
Packit ea1746
Theory
Packit ea1746
------
Packit ea1746
Packit ea1746
Let us consider a problem with a single problem and a single parameter
Packit ea1746
block.
Packit ea1746
Packit ea1746
.. math::
Packit ea1746
Packit ea1746
 \min_x \frac{1}{2}\rho(f^2(x))
Packit ea1746
Packit ea1746
Packit ea1746
Then, the robustified gradient and the Gauss-Newton Hessian are
Packit ea1746
Packit ea1746
.. math::
Packit ea1746
Packit ea1746
        g(x) &= \rho'J^\top(x)f(x)\\
Packit ea1746
        H(x) &= J^\top(x)\left(\rho' + 2 \rho''f(x)f^\top(x)\right)J(x)
Packit ea1746
Packit ea1746
where the terms involving the second derivatives of :math:`f(x)` have
Packit ea1746
been ignored. Note that :math:`H(x)` is indefinite if
Packit ea1746
:math:`\rho''f(x)^\top f(x) + \frac{1}{2}\rho' < 0`. If this is not
Packit ea1746
the case, then its possible to re-weight the residual and the Jacobian
Packit ea1746
matrix such that the corresponding linear least squares problem for
Packit ea1746
the robustified Gauss-Newton step.
Packit ea1746
Packit ea1746
Packit ea1746
Let :math:`\alpha` be a root of
Packit ea1746
Packit ea1746
.. math:: \frac{1}{2}\alpha^2 - \alpha - \frac{\rho''}{\rho'}\|f(x)\|^2 = 0.
Packit ea1746
Packit ea1746
Packit ea1746
Then, define the rescaled residual and Jacobian as
Packit ea1746
Packit ea1746
.. math::
Packit ea1746
Packit ea1746
        \tilde{f}(x) &= \frac{\sqrt{\rho'}}{1 - \alpha} f(x)\\
Packit ea1746
        \tilde{J}(x) &= \sqrt{\rho'}\left(1 - \alpha
Packit ea1746
                        \frac{f(x)f^\top(x)}{\left\|f(x)\right\|^2} \right)J(x)
Packit ea1746
Packit ea1746
Packit ea1746
In the case :math:`2 \rho''\left\|f(x)\right\|^2 + \rho' \lesssim 0`,
Packit ea1746
we limit :math:`\alpha \le 1- \epsilon` for some small
Packit ea1746
:math:`\epsilon`. For more details see [Triggs]_.
Packit ea1746
Packit ea1746
With this simple rescaling, one can use any Jacobian based non-linear
Packit ea1746
least squares algorithm to robustified non-linear least squares
Packit ea1746
problems.
Packit ea1746
Packit ea1746
Packit ea1746
:class:`LocalParameterization`
Packit ea1746
==============================
Packit ea1746
Packit ea1746
.. class:: LocalParameterization
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
     class LocalParameterization {
Packit ea1746
      public:
Packit ea1746
       virtual ~LocalParameterization() {}
Packit ea1746
       virtual bool Plus(const double* x,
Packit ea1746
                         const double* delta,
Packit ea1746
                         double* x_plus_delta) const = 0;
Packit ea1746
       virtual bool ComputeJacobian(const double* x, double* jacobian) const = 0;
Packit ea1746
       virtual bool MultiplyByJacobian(const double* x,
Packit ea1746
                                       const int num_rows,
Packit ea1746
                                       const double* global_matrix,
Packit ea1746
                                       double* local_matrix) const;
Packit ea1746
       virtual int GlobalSize() const = 0;
Packit ea1746
       virtual int LocalSize() const = 0;
Packit ea1746
     };
Packit ea1746
Packit ea1746
   Sometimes the parameters :math:`x` can overparameterize a
Packit ea1746
   problem. In that case it is desirable to choose a parameterization
Packit ea1746
   to remove the null directions of the cost. More generally, if
Packit ea1746
   :math:`x` lies on a manifold of a smaller dimension than the
Packit ea1746
   ambient space that it is embedded in, then it is numerically and
Packit ea1746
   computationally more effective to optimize it using a
Packit ea1746
   parameterization that lives in the tangent space of that manifold
Packit ea1746
   at each point.
Packit ea1746
Packit ea1746
   For example, a sphere in three dimensions is a two dimensional
Packit ea1746
   manifold, embedded in a three dimensional space. At each point on
Packit ea1746
   the sphere, the plane tangent to it defines a two dimensional
Packit ea1746
   tangent space. For a cost function defined on this sphere, given a
Packit ea1746
   point :math:`x`, moving in the direction normal to the sphere at
Packit ea1746
   that point is not useful. Thus a better way to parameterize a point
Packit ea1746
   on a sphere is to optimize over two dimensional vector
Packit ea1746
   :math:`\Delta x` in the tangent space at the point on the sphere
Packit ea1746
   point and then "move" to the point :math:`x + \Delta x`, where the
Packit ea1746
   move operation involves projecting back onto the sphere. Doing so
Packit ea1746
   removes a redundant dimension from the optimization, making it
Packit ea1746
   numerically more robust and efficient.
Packit ea1746
Packit ea1746
   More generally we can define a function
Packit ea1746
Packit ea1746
   .. math:: x' = \boxplus(x, \Delta x),
Packit ea1746
Packit ea1746
   where :math:`x'` has the same size as :math:`x`, and :math:`\Delta
Packit ea1746
   x` is of size less than or equal to :math:`x`. The function
Packit ea1746
   :math:`\boxplus`, generalizes the definition of vector
Packit ea1746
   addition. Thus it satisfies the identity
Packit ea1746
Packit ea1746
   .. math:: \boxplus(x, 0) = x,\quad \forall x.
Packit ea1746
Packit ea1746
   Instances of :class:`LocalParameterization` implement the
Packit ea1746
   :math:`\boxplus` operation and its derivative with respect to
Packit ea1746
   :math:`\Delta x` at :math:`\Delta x = 0`.
Packit ea1746
Packit ea1746
Packit ea1746
.. function:: int LocalParameterization::GlobalSize()
Packit ea1746
Packit ea1746
   The dimension of the ambient space in which the parameter block
Packit ea1746
   :math:`x` lives.
Packit ea1746
Packit ea1746
.. function:: int LocalParameterization::LocalSize()
Packit ea1746
Packit ea1746
   The size of the tangent space
Packit ea1746
   that :math:`\Delta x` lives in.
Packit ea1746
Packit ea1746
.. function:: bool LocalParameterization::Plus(const double* x, const double* delta, double* x_plus_delta) const
Packit ea1746
Packit ea1746
    :func:`LocalParameterization::Plus` implements :math:`\boxplus(x,\Delta x)`.
Packit ea1746
Packit ea1746
.. function:: bool LocalParameterization::ComputeJacobian(const double* x, double* jacobian) const
Packit ea1746
Packit ea1746
   Computes the Jacobian matrix
Packit ea1746
Packit ea1746
   .. math:: J = \left . \frac{\partial }{\partial \Delta x} \boxplus(x,\Delta x)\right|_{\Delta x = 0}
Packit ea1746
Packit ea1746
   in row major form.
Packit ea1746
Packit ea1746
.. function:: bool MultiplyByJacobian(const double* x, const int num_rows, const double* global_matrix, double* local_matrix) const
Packit ea1746
Packit ea1746
   local_matrix = global_matrix * jacobian
Packit ea1746
Packit ea1746
   global_matrix is a num_rows x GlobalSize  row major matrix.
Packit ea1746
   local_matrix is a num_rows x LocalSize row major matrix.
Packit ea1746
   jacobian is the matrix returned by :func:`LocalParameterization::ComputeJacobian` at :math:`x`.
Packit ea1746
Packit ea1746
   This is only used by GradientProblem. For most normal uses, it is
Packit ea1746
   okay to use the default implementation.
Packit ea1746
Packit ea1746
Instances
Packit ea1746
---------
Packit ea1746
Packit ea1746
.. class:: IdentityParameterization
Packit ea1746
Packit ea1746
   A trivial version of :math:`\boxplus` is when :math:`\Delta x` is
Packit ea1746
   of the same size as :math:`x` and
Packit ea1746
Packit ea1746
   .. math::  \boxplus(x, \Delta x) = x + \Delta x
Packit ea1746
Packit ea1746
.. class:: SubsetParameterization
Packit ea1746
Packit ea1746
   A more interesting case if :math:`x` is a two dimensional vector,
Packit ea1746
   and the user wishes to hold the first coordinate constant. Then,
Packit ea1746
   :math:`\Delta x` is a scalar and :math:`\boxplus` is defined as
Packit ea1746
Packit ea1746
   .. math::
Packit ea1746
Packit ea1746
      \boxplus(x, \Delta x) = x + \left[ \begin{array}{c} 0 \\ 1
Packit ea1746
                                  \end{array} \right] \Delta x
Packit ea1746
Packit ea1746
   :class:`SubsetParameterization` generalizes this construction to
Packit ea1746
   hold any part of a parameter block constant.
Packit ea1746
Packit ea1746
.. class:: QuaternionParameterization
Packit ea1746
Packit ea1746
   Another example that occurs commonly in Structure from Motion
Packit ea1746
   problems is when camera rotations are parameterized using a
Packit ea1746
   quaternion. There, it is useful only to make updates orthogonal to
Packit ea1746
   that 4-vector defining the quaternion. One way to do this is to let
Packit ea1746
   :math:`\Delta x` be a 3 dimensional vector and define
Packit ea1746
   :math:`\boxplus` to be
Packit ea1746
Packit ea1746
    .. math:: \boxplus(x, \Delta x) = \left[ \cos(|\Delta x|), \frac{\sin\left(|\Delta x|\right)}{|\Delta x|} \Delta x \right] * x
Packit ea1746
      :label: quaternion
Packit ea1746
Packit ea1746
   The multiplication between the two 4-vectors on the right hand side
Packit ea1746
   is the standard quaternion
Packit ea1746
   product. :class:`QuaternionParameterization` is an implementation
Packit ea1746
   of :eq:`quaternion`.
Packit ea1746
Packit ea1746
.. class:: EigenQuaternionParameterization
Packit ea1746
Packit ea1746
   Eigen uses a different internal memory layout for the elements of the
Packit ea1746
   quaternion than what is commonly used. Specifically, Eigen stores the
Packit ea1746
   elements in memory as [x, y, z, w] where the real part is last
Packit ea1746
   whereas it is typically stored first. Note, when creating an Eigen
Packit ea1746
   quaternion through the constructor the elements are accepted in w, x,
Packit ea1746
   y, z order. Since Ceres operates on parameter blocks which are raw
Packit ea1746
   double pointers this difference is important and requires a different
Packit ea1746
   parameterization. :class:`EigenQuaternionParameterization` uses the
Packit ea1746
   same update as :class:`QuaternionParameterization` but takes into
Packit ea1746
   account Eigen's internal memory element ordering.
Packit ea1746
Packit ea1746
.. class:: HomogeneousVectorParameterization
Packit ea1746
Packit ea1746
   In computer vision, homogeneous vectors are commonly used to
Packit ea1746
   represent entities in projective geometry such as points in
Packit ea1746
   projective space. One example where it is useful to use this
Packit ea1746
   over-parameterization is in representing points whose triangulation
Packit ea1746
   is ill-conditioned. Here it is advantageous to use homogeneous
Packit ea1746
   vectors, instead of an Euclidean vector, because it can represent
Packit ea1746
   points at infinity.
Packit ea1746
Packit ea1746
   When using homogeneous vectors it is useful to only make updates
Packit ea1746
   orthogonal to that :math:`n`-vector defining the homogeneous
Packit ea1746
   vector [HartleyZisserman]_. One way to do this is to let :math:`\Delta x`
Packit ea1746
   be a :math:`n-1` dimensional vector and define :math:`\boxplus` to be
Packit ea1746
Packit ea1746
    .. math:: \boxplus(x, \Delta x) = \left[ \frac{\sin\left(0.5 |\Delta x|\right)}{|\Delta x|} \Delta x, \cos(0.5 |\Delta x|) \right] * x
Packit ea1746
Packit ea1746
   The multiplication between the two vectors on the right hand side
Packit ea1746
   is defined as an operator which applies the update orthogonal to
Packit ea1746
   :math:`x` to remain on the sphere. Note, it is assumed that
Packit ea1746
   last element of :math:`x` is the scalar component of the homogeneous
Packit ea1746
   vector.
Packit ea1746
Packit ea1746
Packit ea1746
.. class:: ProductParameterization
Packit ea1746
Packit ea1746
   Consider an optimization problem over the space of rigid
Packit ea1746
   transformations :math:`SE(3)`, which is the Cartesian product of
Packit ea1746
   :math:`SO(3)` and :math:`\mathbb{R}^3`. Suppose you are using
Packit ea1746
   Quaternions to represent the rotation, Ceres ships with a local
Packit ea1746
   parameterization for that and :math:`\mathbb{R}^3` requires no, or
Packit ea1746
   :class:`IdentityParameterization` parameterization. So how do we
Packit ea1746
   construct a local parameterization for a parameter block a rigid
Packit ea1746
   transformation?
Packit ea1746
Packit ea1746
   In cases, where a parameter block is the Cartesian product of a
Packit ea1746
   number of manifolds and you have the local parameterization of the
Packit ea1746
   individual manifolds available, :class:`ProductParameterization`
Packit ea1746
   can be used to construct a local parameterization of the cartesian
Packit ea1746
   product. For the case of the rigid transformation, where say you
Packit ea1746
   have a parameter block of size 7, where the first four entries
Packit ea1746
   represent the rotation as a quaternion, a local parameterization
Packit ea1746
   can be constructed as
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
     ProductParameterization se3_param(new QuaternionParameterization(),
Packit ea1746
                                       new IdentityTransformation(3));
Packit ea1746
Packit ea1746
Packit ea1746
:class:`AutoDiffLocalParameterization`
Packit ea1746
======================================
Packit ea1746
Packit ea1746
.. class:: AutoDiffLocalParameterization
Packit ea1746
Packit ea1746
  :class:`AutoDiffLocalParameterization` does for
Packit ea1746
  :class:`LocalParameterization` what :class:`AutoDiffCostFunction`
Packit ea1746
  does for :class:`CostFunction`. It allows the user to define a
Packit ea1746
  templated functor that implements the
Packit ea1746
  :func:`LocalParameterization::Plus` operation and it uses automatic
Packit ea1746
  differentiation to implement the computation of the Jacobian.
Packit ea1746
Packit ea1746
  To get an auto differentiated local parameterization, you must
Packit ea1746
  define a class with a templated operator() (a functor) that computes
Packit ea1746
Packit ea1746
     .. math:: x' = \boxplus(x, \Delta x),
Packit ea1746
Packit ea1746
  For example, Quaternions have a three dimensional local
Packit ea1746
  parameterization. Its plus operation can be implemented as (taken
Packit ea1746
  from `internal/ceres/autodiff_local_parameterization_test.cc
Packit ea1746
  <https://ceres-solver.googlesource.com/ceres-solver/+/master/internal/ceres/autodiff_local_parameterization_test.cc>`_
Packit ea1746
  )
Packit ea1746
Packit ea1746
    .. code-block:: c++
Packit ea1746
Packit ea1746
      struct QuaternionPlus {
Packit ea1746
        template<typename T>
Packit ea1746
        bool operator()(const T* x, const T* delta, T* x_plus_delta) const {
Packit ea1746
          const T squared_norm_delta =
Packit ea1746
              delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2];
Packit ea1746
Packit ea1746
          T q_delta[4];
Packit ea1746
          if (squared_norm_delta > 0.0) {
Packit ea1746
            T norm_delta = sqrt(squared_norm_delta);
Packit ea1746
            const T sin_delta_by_delta = sin(norm_delta) / norm_delta;
Packit ea1746
            q_delta[0] = cos(norm_delta);
Packit ea1746
            q_delta[1] = sin_delta_by_delta * delta[0];
Packit ea1746
            q_delta[2] = sin_delta_by_delta * delta[1];
Packit ea1746
            q_delta[3] = sin_delta_by_delta * delta[2];
Packit ea1746
          } else {
Packit ea1746
            // We do not just use q_delta = [1,0,0,0] here because that is a
Packit ea1746
            // constant and when used for automatic differentiation will
Packit ea1746
            // lead to a zero derivative. Instead we take a first order
Packit ea1746
            // approximation and evaluate it at zero.
Packit ea1746
            q_delta[0] = T(1.0);
Packit ea1746
            q_delta[1] = delta[0];
Packit ea1746
            q_delta[2] = delta[1];
Packit ea1746
            q_delta[3] = delta[2];
Packit ea1746
          }
Packit ea1746
Packit ea1746
          Quaternionproduct(q_delta, x, x_plus_delta);
Packit ea1746
          return true;
Packit ea1746
        }
Packit ea1746
      };
Packit ea1746
Packit ea1746
  Given this struct, the auto differentiated local
Packit ea1746
  parameterization can now be constructed as
Packit ea1746
Packit ea1746
  .. code-block:: c++
Packit ea1746
Packit ea1746
     LocalParameterization* local_parameterization =
Packit ea1746
         new AutoDiffLocalParameterization<QuaternionPlus, 4, 3>;
Packit ea1746
                                                           |  |
Packit ea1746
                                Global Size ---------------+  |
Packit ea1746
                                Local Size -------------------+
Packit ea1746
Packit ea1746
Packit ea1746
:class:`Problem`
Packit ea1746
================
Packit ea1746
Packit ea1746
.. class:: Problem
Packit ea1746
Packit ea1746
   :class:`Problem` holds the robustified bounds constrained
Packit ea1746
   non-linear least squares problem :eq:`ceresproblem`. To create a
Packit ea1746
   least squares problem, use the :func:`Problem::AddResidualBlock`
Packit ea1746
   and :func:`Problem::AddParameterBlock` methods.
Packit ea1746
Packit ea1746
   For example a problem containing 3 parameter blocks of sizes 3, 4
Packit ea1746
   and 5 respectively and two residual blocks of size 2 and 6:
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
     double x1[] = { 1.0, 2.0, 3.0 };
Packit ea1746
     double x2[] = { 1.0, 2.0, 3.0, 5.0 };
Packit ea1746
     double x3[] = { 1.0, 2.0, 3.0, 6.0, 7.0 };
Packit ea1746
Packit ea1746
     Problem problem;
Packit ea1746
     problem.AddResidualBlock(new MyUnaryCostFunction(...), x1);
Packit ea1746
     problem.AddResidualBlock(new MyBinaryCostFunction(...), x2, x3);
Packit ea1746
Packit ea1746
   :func:`Problem::AddResidualBlock` as the name implies, adds a
Packit ea1746
   residual block to the problem. It adds a :class:`CostFunction`, an
Packit ea1746
   optional :class:`LossFunction` and connects the
Packit ea1746
   :class:`CostFunction` to a set of parameter block.
Packit ea1746
Packit ea1746
   The cost function carries with it information about the sizes of
Packit ea1746
   the parameter blocks it expects. The function checks that these
Packit ea1746
   match the sizes of the parameter blocks listed in
Packit ea1746
   ``parameter_blocks``. The program aborts if a mismatch is
Packit ea1746
   detected. ``loss_function`` can be ``NULL``, in which case the cost
Packit ea1746
   of the term is just the squared norm of the residuals.
Packit ea1746
Packit ea1746
   The user has the option of explicitly adding the parameter blocks
Packit ea1746
   using :func:`Problem::AddParameterBlock`. This causes additional
Packit ea1746
   correctness checking; however, :func:`Problem::AddResidualBlock`
Packit ea1746
   implicitly adds the parameter blocks if they are not present, so
Packit ea1746
   calling :func:`Problem::AddParameterBlock` explicitly is not
Packit ea1746
   required.
Packit ea1746
Packit ea1746
   :func:`Problem::AddParameterBlock` explicitly adds a parameter
Packit ea1746
   block to the :class:`Problem`. Optionally it allows the user to
Packit ea1746
   associate a :class:`LocalParameterization` object with the
Packit ea1746
   parameter block too. Repeated calls with the same arguments are
Packit ea1746
   ignored. Repeated calls with the same double pointer but a
Packit ea1746
   different size results in undefined behavior.
Packit ea1746
Packit ea1746
   You can set any parameter block to be constant using
Packit ea1746
   :func:`Problem::SetParameterBlockConstant` and undo this using
Packit ea1746
   :func:`SetParameterBlockVariable`.
Packit ea1746
Packit ea1746
   In fact you can set any number of parameter blocks to be constant,
Packit ea1746
   and Ceres is smart enough to figure out what part of the problem
Packit ea1746
   you have constructed depends on the parameter blocks that are free
Packit ea1746
   to change and only spends time solving it. So for example if you
Packit ea1746
   constructed a problem with a million parameter blocks and 2 million
Packit ea1746
   residual blocks, but then set all but one parameter blocks to be
Packit ea1746
   constant and say only 10 residual blocks depend on this one
Packit ea1746
   non-constant parameter block. Then the computational effort Ceres
Packit ea1746
   spends in solving this problem will be the same if you had defined
Packit ea1746
   a problem with one parameter block and 10 residual blocks.
Packit ea1746
Packit ea1746
   **Ownership**
Packit ea1746
Packit ea1746
   :class:`Problem` by default takes ownership of the
Packit ea1746
   ``cost_function``, ``loss_function`` and ``local_parameterization``
Packit ea1746
   pointers. These objects remain live for the life of the
Packit ea1746
   :class:`Problem`. If the user wishes to keep control over the
Packit ea1746
   destruction of these objects, then they can do this by setting the
Packit ea1746
   corresponding enums in the :class:`Problem::Options` struct.
Packit ea1746
Packit ea1746
   Note that even though the Problem takes ownership of ``cost_function``
Packit ea1746
   and ``loss_function``, it does not preclude the user from re-using
Packit ea1746
   them in another residual block. The destructor takes care to call
Packit ea1746
   delete on each ``cost_function`` or ``loss_function`` pointer only
Packit ea1746
   once, regardless of how many residual blocks refer to them.
Packit ea1746
Packit ea1746
.. function:: ResidualBlockId Problem::AddResidualBlock(CostFunction* cost_function, LossFunction* loss_function, const vector<double*> parameter_blocks)
Packit ea1746
Packit ea1746
   Add a residual block to the overall cost function. The cost
Packit ea1746
   function carries with it information about the sizes of the
Packit ea1746
   parameter blocks it expects. The function checks that these match
Packit ea1746
   the sizes of the parameter blocks listed in parameter_blocks. The
Packit ea1746
   program aborts if a mismatch is detected. loss_function can be
Packit ea1746
   NULL, in which case the cost of the term is just the squared norm
Packit ea1746
   of the residuals.
Packit ea1746
Packit ea1746
   The user has the option of explicitly adding the parameter blocks
Packit ea1746
   using AddParameterBlock. This causes additional correctness
Packit ea1746
   checking; however, AddResidualBlock implicitly adds the parameter
Packit ea1746
   blocks if they are not present, so calling AddParameterBlock
Packit ea1746
   explicitly is not required.
Packit ea1746
Packit ea1746
   The Problem object by default takes ownership of the
Packit ea1746
   cost_function and loss_function pointers. These objects remain
Packit ea1746
   live for the life of the Problem object. If the user wishes to
Packit ea1746
   keep control over the destruction of these objects, then they can
Packit ea1746
   do this by setting the corresponding enums in the Options struct.
Packit ea1746
Packit ea1746
   Note: Even though the Problem takes ownership of cost_function
Packit ea1746
   and loss_function, it does not preclude the user from re-using
Packit ea1746
   them in another residual block. The destructor takes care to call
Packit ea1746
   delete on each cost_function or loss_function pointer only once,
Packit ea1746
   regardless of how many residual blocks refer to them.
Packit ea1746
Packit ea1746
   Example usage:
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
      double x1[] = {1.0, 2.0, 3.0};
Packit ea1746
      double x2[] = {1.0, 2.0, 5.0, 6.0};
Packit ea1746
      double x3[] = {3.0, 6.0, 2.0, 5.0, 1.0};
Packit ea1746
Packit ea1746
      Problem problem;
Packit ea1746
Packit ea1746
      problem.AddResidualBlock(new MyUnaryCostFunction(...), NULL, x1);
Packit ea1746
      problem.AddResidualBlock(new MyBinaryCostFunction(...), NULL, x2, x1);
Packit ea1746
Packit ea1746
Packit ea1746
.. function:: void Problem::AddParameterBlock(double* values, int size, LocalParameterization* local_parameterization)
Packit ea1746
Packit ea1746
   Add a parameter block with appropriate size to the problem.
Packit ea1746
   Repeated calls with the same arguments are ignored. Repeated calls
Packit ea1746
   with the same double pointer but a different size results in
Packit ea1746
   undefined behavior.
Packit ea1746
Packit ea1746
.. function:: void Problem::AddParameterBlock(double* values, int size)
Packit ea1746
Packit ea1746
   Add a parameter block with appropriate size and parameterization to
Packit ea1746
   the problem. Repeated calls with the same arguments are
Packit ea1746
   ignored. Repeated calls with the same double pointer but a
Packit ea1746
   different size results in undefined behavior.
Packit ea1746
Packit ea1746
.. function:: void Problem::RemoveResidualBlock(ResidualBlockId residual_block)
Packit ea1746
Packit ea1746
   Remove a residual block from the problem. Any parameters that the residual
Packit ea1746
   block depends on are not removed. The cost and loss functions for the
Packit ea1746
   residual block will not get deleted immediately; won't happen until the
Packit ea1746
   problem itself is deleted.  If Problem::Options::enable_fast_removal is
Packit ea1746
   true, then the removal is fast (almost constant time). Otherwise, removing a
Packit ea1746
   residual block will incur a scan of the entire Problem object to verify that
Packit ea1746
   the residual_block represents a valid residual in the problem.
Packit ea1746
Packit ea1746
   **WARNING:** Removing a residual or parameter block will destroy
Packit ea1746
   the implicit ordering, rendering the jacobian or residuals returned
Packit ea1746
   from the solver uninterpretable. If you depend on the evaluated
Packit ea1746
   jacobian, do not use remove! This may change in a future release.
Packit ea1746
   Hold the indicated parameter block constant during optimization.
Packit ea1746
Packit ea1746
.. function:: void Problem::RemoveParameterBlock(double* values)
Packit ea1746
Packit ea1746
   Remove a parameter block from the problem. The parameterization of
Packit ea1746
   the parameter block, if it exists, will persist until the deletion
Packit ea1746
   of the problem (similar to cost/loss functions in residual block
Packit ea1746
   removal). Any residual blocks that depend on the parameter are also
Packit ea1746
   removed, as described above in RemoveResidualBlock().  If
Packit ea1746
   Problem::Options::enable_fast_removal is true, then
Packit ea1746
   the removal is fast (almost constant time). Otherwise, removing a
Packit ea1746
   parameter block will incur a scan of the entire Problem object.
Packit ea1746
Packit ea1746
   **WARNING:** Removing a residual or parameter block will destroy
Packit ea1746
   the implicit ordering, rendering the jacobian or residuals returned
Packit ea1746
   from the solver uninterpretable. If you depend on the evaluated
Packit ea1746
   jacobian, do not use remove! This may change in a future release.
Packit ea1746
Packit ea1746
.. function:: void Problem::SetParameterBlockConstant(double* values)
Packit ea1746
Packit ea1746
   Hold the indicated parameter block constant during optimization.
Packit ea1746
Packit ea1746
.. function:: void Problem::SetParameterBlockVariable(double* values)
Packit ea1746
Packit ea1746
   Allow the indicated parameter to vary during optimization.
Packit ea1746
Packit ea1746
.. function:: void Problem::SetParameterization(double* values, LocalParameterization* local_parameterization)
Packit ea1746
Packit ea1746
   Set the local parameterization for one of the parameter blocks.
Packit ea1746
   The local_parameterization is owned by the Problem by default. It
Packit ea1746
   is acceptable to set the same parameterization for multiple
Packit ea1746
   parameters; the destructor is careful to delete local
Packit ea1746
   parameterizations only once. The local parameterization can only be
Packit ea1746
   set once per parameter, and cannot be changed once set.
Packit ea1746
Packit ea1746
.. function:: LocalParameterization* Problem::GetParameterization(double* values) const
Packit ea1746
Packit ea1746
   Get the local parameterization object associated with this
Packit ea1746
   parameter block. If there is no parameterization object associated
Packit ea1746
   then `NULL` is returned
Packit ea1746
Packit ea1746
.. function:: void Problem::SetParameterLowerBound(double* values, int index, double lower_bound)
Packit ea1746
Packit ea1746
   Set the lower bound for the parameter at position `index` in the
Packit ea1746
   parameter block corresponding to `values`. By default the lower
Packit ea1746
   bound is :math:`-\infty`.
Packit ea1746
Packit ea1746
.. function:: void Problem::SetParameterUpperBound(double* values, int index, double upper_bound)
Packit ea1746
Packit ea1746
   Set the upper bound for the parameter at position `index` in the
Packit ea1746
   parameter block corresponding to `values`. By default the value is
Packit ea1746
   :math:`\infty`.
Packit ea1746
Packit ea1746
.. function:: int Problem::NumParameterBlocks() const
Packit ea1746
Packit ea1746
   Number of parameter blocks in the problem. Always equals
Packit ea1746
   parameter_blocks().size() and parameter_block_sizes().size().
Packit ea1746
Packit ea1746
.. function:: int Problem::NumParameters() const
Packit ea1746
Packit ea1746
   The size of the parameter vector obtained by summing over the sizes
Packit ea1746
   of all the parameter blocks.
Packit ea1746
Packit ea1746
.. function:: int Problem::NumResidualBlocks() const
Packit ea1746
Packit ea1746
   Number of residual blocks in the problem. Always equals
Packit ea1746
   residual_blocks().size().
Packit ea1746
Packit ea1746
.. function:: int Problem::NumResiduals() const
Packit ea1746
Packit ea1746
   The size of the residual vector obtained by summing over the sizes
Packit ea1746
   of all of the residual blocks.
Packit ea1746
Packit ea1746
.. function:: int Problem::ParameterBlockSize(const double* values) const
Packit ea1746
Packit ea1746
   The size of the parameter block.
Packit ea1746
Packit ea1746
.. function:: int Problem::ParameterBlockLocalSize(const double* values) const
Packit ea1746
Packit ea1746
   The size of local parameterization for the parameter block. If
Packit ea1746
   there is no local parameterization associated with this parameter
Packit ea1746
   block, then ``ParameterBlockLocalSize`` = ``ParameterBlockSize``.
Packit ea1746
Packit ea1746
.. function:: bool Problem::HasParameterBlock(const double* values) const
Packit ea1746
Packit ea1746
   Is the given parameter block present in the problem or not?
Packit ea1746
Packit ea1746
.. function:: void Problem::GetParameterBlocks(vector<double*>* parameter_blocks) const
Packit ea1746
Packit ea1746
   Fills the passed ``parameter_blocks`` vector with pointers to the
Packit ea1746
   parameter blocks currently in the problem. After this call,
Packit ea1746
   ``parameter_block.size() == NumParameterBlocks``.
Packit ea1746
Packit ea1746
.. function:: void Problem::GetResidualBlocks(vector<ResidualBlockId>* residual_blocks) const
Packit ea1746
Packit ea1746
   Fills the passed `residual_blocks` vector with pointers to the
Packit ea1746
   residual blocks currently in the problem. After this call,
Packit ea1746
   `residual_blocks.size() == NumResidualBlocks`.
Packit ea1746
Packit ea1746
.. function:: void Problem::GetParameterBlocksForResidualBlock(const ResidualBlockId residual_block, vector<double*>* parameter_blocks) const
Packit ea1746
Packit ea1746
   Get all the parameter blocks that depend on the given residual
Packit ea1746
   block.
Packit ea1746
Packit ea1746
.. function:: void Problem::GetResidualBlocksForParameterBlock(const double* values, vector<ResidualBlockId>* residual_blocks) const
Packit ea1746
Packit ea1746
   Get all the residual blocks that depend on the given parameter
Packit ea1746
   block.
Packit ea1746
Packit ea1746
   If `Problem::Options::enable_fast_removal` is
Packit ea1746
   `true`, then getting the residual blocks is fast and depends only
Packit ea1746
   on the number of residual blocks. Otherwise, getting the residual
Packit ea1746
   blocks for a parameter block will incur a scan of the entire
Packit ea1746
   :class:`Problem` object.
Packit ea1746
Packit ea1746
.. function:: const CostFunction* GetCostFunctionForResidualBlock(const ResidualBlockId residual_block) const
Packit ea1746
Packit ea1746
   Get the :class:`CostFunction` for the given residual block.
Packit ea1746
Packit ea1746
.. function:: const LossFunction* GetLossFunctionForResidualBlock(const ResidualBlockId residual_block) const
Packit ea1746
Packit ea1746
   Get the :class:`LossFunction` for the given residual block.
Packit ea1746
Packit ea1746
.. function:: bool Problem::Evaluate(const Problem::EvaluateOptions& options, double* cost, vector<double>* residuals, vector<double>* gradient, CRSMatrix* jacobian)
Packit ea1746
Packit ea1746
   Evaluate a :class:`Problem`. Any of the output pointers can be
Packit ea1746
   `NULL`. Which residual blocks and parameter blocks are used is
Packit ea1746
   controlled by the :class:`Problem::EvaluateOptions` struct below.
Packit ea1746
Packit ea1746
   .. NOTE::
Packit ea1746
Packit ea1746
      The evaluation will use the values stored in the memory
Packit ea1746
      locations pointed to by the parameter block pointers used at the
Packit ea1746
      time of the construction of the problem, for example in the
Packit ea1746
      following code:
Packit ea1746
Packit ea1746
      .. code-block:: c++
Packit ea1746
Packit ea1746
        Problem problem;
Packit ea1746
        double x = 1;
Packit ea1746
        problem.Add(new MyCostFunction, NULL, &x);
Packit ea1746
Packit ea1746
        double cost = 0.0;
Packit ea1746
        problem.Evaluate(Problem::EvaluateOptions(), &cost, NULL, NULL, NULL);
Packit ea1746
Packit ea1746
      The cost is evaluated at `x = 1`. If you wish to evaluate the
Packit ea1746
      problem at `x = 2`, then
Packit ea1746
Packit ea1746
      .. code-block:: c++
Packit ea1746
Packit ea1746
         x = 2;
Packit ea1746
         problem.Evaluate(Problem::EvaluateOptions(), &cost, NULL, NULL, NULL);
Packit ea1746
Packit ea1746
      is the way to do so.
Packit ea1746
Packit ea1746
   .. NOTE::
Packit ea1746
Packit ea1746
      If no local parameterizations are used, then the size of
Packit ea1746
      the gradient vector is the sum of the sizes of all the parameter
Packit ea1746
      blocks. If a parameter block has a local parameterization, then
Packit ea1746
      it contributes "LocalSize" entries to the gradient vector.
Packit ea1746
Packit ea1746
   .. NOTE::
Packit ea1746
Packit ea1746
      This function cannot be called while the problem is being
Packit ea1746
      solved, for example it cannot be called from an
Packit ea1746
      :class:`IterationCallback` at the end of an iteration during a
Packit ea1746
      solve.
Packit ea1746
Packit ea1746
.. class:: Problem::EvaluateOptions
Packit ea1746
Packit ea1746
   Options struct that is used to control :func:`Problem::Evaluate`.
Packit ea1746
Packit ea1746
.. member:: vector<double*> Problem::EvaluateOptions::parameter_blocks
Packit ea1746
Packit ea1746
   The set of parameter blocks for which evaluation should be
Packit ea1746
   performed. This vector determines the order in which parameter
Packit ea1746
   blocks occur in the gradient vector and in the columns of the
Packit ea1746
   jacobian matrix. If parameter_blocks is empty, then it is assumed
Packit ea1746
   to be equal to a vector containing ALL the parameter
Packit ea1746
   blocks. Generally speaking the ordering of the parameter blocks in
Packit ea1746
   this case depends on the order in which they were added to the
Packit ea1746
   problem and whether or not the user removed any parameter blocks.
Packit ea1746
Packit ea1746
   **NOTE** This vector should contain the same pointers as the ones
Packit ea1746
   used to add parameter blocks to the Problem. These parameter block
Packit ea1746
   should NOT point to new memory locations. Bad things will happen if
Packit ea1746
   you do.
Packit ea1746
Packit ea1746
.. member:: vector<ResidualBlockId> Problem::EvaluateOptions::residual_blocks
Packit ea1746
Packit ea1746
   The set of residual blocks for which evaluation should be
Packit ea1746
   performed. This vector determines the order in which the residuals
Packit ea1746
   occur, and how the rows of the jacobian are ordered. If
Packit ea1746
   residual_blocks is empty, then it is assumed to be equal to the
Packit ea1746
   vector containing all the parameter blocks.
Packit ea1746
Packit ea1746
.. member:: bool Problem::EvaluateOptions::apply_loss_function
Packit ea1746
Packit ea1746
   Even though the residual blocks in the problem may contain loss
Packit ea1746
   functions, setting apply_loss_function to false will turn off the
Packit ea1746
   application of the loss function to the output of the cost
Packit ea1746
   function. This is of use for example if the user wishes to analyse
Packit ea1746
   the solution quality by studying the distribution of residuals
Packit ea1746
   before and after the solve.
Packit ea1746
Packit ea1746
.. member:: int Problem::EvaluateOptions::num_threads
Packit ea1746
Packit ea1746
   Number of threads to use. (Requires OpenMP).
Packit ea1746
Packit ea1746
``rotation.h``
Packit ea1746
==============
Packit ea1746
Packit ea1746
Many applications of Ceres Solver involve optimization problems where
Packit ea1746
some of the variables correspond to rotations. To ease the pain of
Packit ea1746
work with the various representations of rotations (angle-axis,
Packit ea1746
quaternion and matrix) we provide a handy set of templated
Packit ea1746
functions. These functions are templated so that the user can use them
Packit ea1746
within Ceres Solver's automatic differentiation framework.
Packit ea1746
Packit ea1746
.. function:: template <typename T> void AngleAxisToQuaternion(T const* angle_axis, T* quaternion)
Packit ea1746
Packit ea1746
   Convert a value in combined axis-angle representation to a
Packit ea1746
   quaternion.
Packit ea1746
Packit ea1746
   The value ``angle_axis`` is a triple whose norm is an angle in radians,
Packit ea1746
   and whose direction is aligned with the axis of rotation, and
Packit ea1746
   ``quaternion`` is a 4-tuple that will contain the resulting quaternion.
Packit ea1746
Packit ea1746
.. function::  template <typename T> void QuaternionToAngleAxis(T const* quaternion, T* angle_axis)
Packit ea1746
Packit ea1746
   Convert a quaternion to the equivalent combined axis-angle
Packit ea1746
   representation.
Packit ea1746
Packit ea1746
   The value ``quaternion`` must be a unit quaternion - it is not
Packit ea1746
   normalized first, and ``angle_axis`` will be filled with a value
Packit ea1746
   whose norm is the angle of rotation in radians, and whose direction
Packit ea1746
   is the axis of rotation.
Packit ea1746
Packit ea1746
.. function:: template <typename T, int row_stride, int col_stride> void RotationMatrixToAngleAxis(const MatrixAdapter<const T, row_stride, col_stride>& R, T * angle_axis)
Packit ea1746
.. function:: template <typename T, int row_stride, int col_stride> void AngleAxisToRotationMatrix(T const * angle_axis, const MatrixAdapter<T, row_stride, col_stride>& R)
Packit ea1746
.. function:: template <typename T> void RotationMatrixToAngleAxis(T const * R, T * angle_axis)
Packit ea1746
.. function:: template <typename T> void AngleAxisToRotationMatrix(T const * angle_axis, T * R)
Packit ea1746
Packit ea1746
   Conversions between 3x3 rotation matrix with given column and row strides and
Packit ea1746
   axis-angle rotation representations. The functions that take a pointer to T instead
Packit ea1746
   of a MatrixAdapter assume a column major representation with unit row stride and a column stride of 3.
Packit ea1746
Packit ea1746
.. function:: template <typename T, int row_stride, int col_stride> void EulerAnglesToRotationMatrix(const T* euler, const MatrixAdapter<T, row_stride, col_stride>& R)
Packit ea1746
.. function:: template <typename T> void EulerAnglesToRotationMatrix(const T* euler, int row_stride, T* R)
Packit ea1746
Packit ea1746
   Conversions between 3x3 rotation matrix with given column and row strides and
Packit ea1746
   Euler angle (in degrees) rotation representations.
Packit ea1746
Packit ea1746
   The {pitch,roll,yaw} Euler angles are rotations around the {x,y,z}
Packit ea1746
   axes, respectively.  They are applied in that same order, so the
Packit ea1746
   total rotation R is Rz * Ry * Rx.
Packit ea1746
Packit ea1746
   The function that takes a pointer to T as the rotation matrix assumes a row
Packit ea1746
   major representation with unit column stride and a row stride of 3.
Packit ea1746
   The additional parameter row_stride is required to be 3.
Packit ea1746
Packit ea1746
.. function:: template <typename T, int row_stride, int col_stride> void QuaternionToScaledRotation(const T q[4], const MatrixAdapter<T, row_stride, col_stride>& R)
Packit ea1746
.. function:: template <typename T> void QuaternionToScaledRotation(const T q[4], T R[3 * 3])
Packit ea1746
Packit ea1746
   Convert a 4-vector to a 3x3 scaled rotation matrix.
Packit ea1746
Packit ea1746
   The choice of rotation is such that the quaternion
Packit ea1746
   :math:`\begin{bmatrix} 1 &0 &0 &0\end{bmatrix}` goes to an identity
Packit ea1746
   matrix and for small :math:`a, b, c` the quaternion
Packit ea1746
   :math:`\begin{bmatrix}1 &a &b &c\end{bmatrix}` goes to the matrix
Packit ea1746
Packit ea1746
   .. math::
Packit ea1746
Packit ea1746
     I + 2 \begin{bmatrix} 0 & -c & b \\ c & 0 & -a\\ -b & a & 0
Packit ea1746
           \end{bmatrix} + O(q^2)
Packit ea1746
Packit ea1746
   which corresponds to a Rodrigues approximation, the last matrix
Packit ea1746
   being the cross-product matrix of :math:`\begin{bmatrix} a& b&
Packit ea1746
   c\end{bmatrix}`. Together with the property that :math:`R(q1 * q2)
Packit ea1746
   = R(q1) * R(q2)` this uniquely defines the mapping from :math:`q` to
Packit ea1746
   :math:`R`.
Packit ea1746
Packit ea1746
   In the function that accepts a pointer to T instead of a MatrixAdapter,
Packit ea1746
   the rotation matrix ``R`` is a row-major matrix with unit column stride
Packit ea1746
   and a row stride of 3.
Packit ea1746
Packit ea1746
   No normalization of the quaternion is performed, i.e.
Packit ea1746
   :math:`R = \|q\|^2  Q`, where :math:`Q` is an orthonormal matrix
Packit ea1746
   such that :math:`\det(Q) = 1` and :math:`Q*Q' = I`.
Packit ea1746
Packit ea1746
Packit ea1746
.. function:: template <typename T> void QuaternionToRotation(const T q[4], const MatrixAdapter<T, row_stride, col_stride>& R)
Packit ea1746
.. function:: template <typename T> void QuaternionToRotation(const T q[4], T R[3 * 3])
Packit ea1746
Packit ea1746
   Same as above except that the rotation matrix is normalized by the
Packit ea1746
   Frobenius norm, so that :math:`R R' = I` (and :math:`\det(R) = 1`).
Packit ea1746
Packit ea1746
.. function:: template <typename T> void UnitQuaternionRotatePoint(const T q[4], const T pt[3], T result[3])
Packit ea1746
Packit ea1746
   Rotates a point pt by a quaternion q:
Packit ea1746
Packit ea1746
   .. math:: \text{result} = R(q)  \text{pt}
Packit ea1746
Packit ea1746
   Assumes the quaternion is unit norm. If you pass in a quaternion
Packit ea1746
   with :math:`|q|^2 = 2` then you WILL NOT get back 2 times the
Packit ea1746
   result you get for a unit quaternion.
Packit ea1746
Packit ea1746
Packit ea1746
.. function:: template <typename T> void QuaternionRotatePoint(const T q[4], const T pt[3], T result[3])
Packit ea1746
Packit ea1746
   With this function you do not need to assume that :math:`q` has unit norm.
Packit ea1746
   It does assume that the norm is non-zero.
Packit ea1746
Packit ea1746
.. function:: template <typename T> void QuaternionProduct(const T z[4], const T w[4], T zw[4])
Packit ea1746
Packit ea1746
   .. math:: zw = z * w
Packit ea1746
Packit ea1746
   where :math:`*` is the Quaternion product between 4-vectors.
Packit ea1746
Packit ea1746
Packit ea1746
.. function:: template <typename T> void CrossProduct(const T x[3], const T y[3], T x_cross_y[3])
Packit ea1746
Packit ea1746
   .. math:: \text{x_cross_y} = x \times y
Packit ea1746
Packit ea1746
.. function:: template <typename T> void AngleAxisRotatePoint(const T angle_axis[3], const T pt[3], T result[3])
Packit ea1746
Packit ea1746
   .. math:: y = R(\text{angle_axis}) x
Packit ea1746
Packit ea1746
Packit ea1746
Cubic Interpolation
Packit ea1746
===================
Packit ea1746
Packit ea1746
Optimization problems often involve functions that are given in the
Packit ea1746
form of a table of values, for example an image. Evaluating these
Packit ea1746
functions and their derivatives requires interpolating these
Packit ea1746
values. Interpolating tabulated functions is a vast area of research
Packit ea1746
and there are a lot of libraries which implement a variety of
Packit ea1746
interpolation schemes. However, using them within the automatic
Packit ea1746
differentiation framework in Ceres is quite painful. To this end,
Packit ea1746
Ceres provides the ability to interpolate one dimensional and two
Packit ea1746
dimensional tabular functions.
Packit ea1746
Packit ea1746
The one dimensional interpolation is based on the Cubic Hermite
Packit ea1746
Spline, also known as the Catmull-Rom Spline. This produces a first
Packit ea1746
order differentiable interpolating function. The two dimensional
Packit ea1746
interpolation scheme is a generalization of the one dimensional scheme
Packit ea1746
where the interpolating function is assumed to be separable in the two
Packit ea1746
dimensions,
Packit ea1746
Packit ea1746
More details of the construction can be found `Linear Methods for
Packit ea1746
Image Interpolation <http://www.ipol.im/pub/art/2011/g_lmii/>`_ by
Packit ea1746
Pascal Getreuer.
Packit ea1746
Packit ea1746
.. class:: CubicInterpolator
Packit ea1746
Packit ea1746
Given as input an infinite one dimensional grid, which provides the
Packit ea1746
following interface.
Packit ea1746
Packit ea1746
.. code::
Packit ea1746
Packit ea1746
  struct Grid1D {
Packit ea1746
    enum { DATA_DIMENSION = 2; };
Packit ea1746
    void GetValue(int n, double* f) const;
Packit ea1746
  };
Packit ea1746
Packit ea1746
Where, ``GetValue`` gives us the value of a function :math:`f`
Packit ea1746
(possibly vector valued) for any integer :math:`n` and the enum
Packit ea1746
``DATA_DIMENSION`` indicates the dimensionality of the function being
Packit ea1746
interpolated. For example if you are interpolating rotations in
Packit ea1746
axis-angle format over time, then ``DATA_DIMENSION = 3``.
Packit ea1746
Packit ea1746
:class:`CubicInterpolator` uses Cubic Hermite splines to produce a
Packit ea1746
smooth approximation to it that can be used to evaluate the
Packit ea1746
:math:`f(x)` and :math:`f'(x)` at any point on the real number
Packit ea1746
line. For example, the following code interpolates an array of four
Packit ea1746
numbers.
Packit ea1746
Packit ea1746
.. code::
Packit ea1746
Packit ea1746
  const double data[] = {1.0, 2.0, 5.0, 6.0};
Packit ea1746
  Grid1D<double, 1> array(x, 0, 4);
Packit ea1746
  CubicInterpolator interpolator(array);
Packit ea1746
  double f, dfdx;
Packit ea1746
  interpolator.Evaluate(1.5, &f, &dfdx);
Packit ea1746
Packit ea1746
Packit ea1746
In the above code we use ``Grid1D`` a templated helper class that
Packit ea1746
allows easy interfacing between ``C++`` arrays and
Packit ea1746
:class:`CubicInterpolator`.
Packit ea1746
Packit ea1746
``Grid1D`` supports vector valued functions where the various
Packit ea1746
coordinates of the function can be interleaved or stacked. It also
Packit ea1746
allows the use of any numeric type as input, as long as it can be
Packit ea1746
safely cast to a double.
Packit ea1746
Packit ea1746
.. class:: BiCubicInterpolator
Packit ea1746
Packit ea1746
Given as input an infinite two dimensional grid, which provides the
Packit ea1746
following interface:
Packit ea1746
Packit ea1746
.. code::
Packit ea1746
Packit ea1746
  struct Grid2D {
Packit ea1746
    enum { DATA_DIMENSION = 2 };
Packit ea1746
    void GetValue(int row, int col, double* f) const;
Packit ea1746
  };
Packit ea1746
Packit ea1746
Where, ``GetValue`` gives us the value of a function :math:`f`
Packit ea1746
(possibly vector valued) for any pair of integers :code:`row` and
Packit ea1746
:code:`col` and the enum ``DATA_DIMENSION`` indicates the
Packit ea1746
dimensionality of the function being interpolated. For example if you
Packit ea1746
are interpolating a color image with three channels (Red, Green &
Packit ea1746
Blue), then ``DATA_DIMENSION = 3``.
Packit ea1746
Packit ea1746
:class:`BiCubicInterpolator` uses the cubic convolution interpolation
Packit ea1746
algorithm of R. Keys [Keys]_, to produce a smooth approximation to it
Packit ea1746
that can be used to evaluate the :math:`f(r,c)`, :math:`\frac{\partial
Packit ea1746
f(r,c)}{\partial r}` and :math:`\frac{\partial f(r,c)}{\partial c}` at
Packit ea1746
any any point in the real plane.
Packit ea1746
Packit ea1746
For example the following code interpolates a two dimensional array.
Packit ea1746
Packit ea1746
.. code::
Packit ea1746
Packit ea1746
   const double data[] = {1.0, 3.0, -1.0, 4.0,
Packit ea1746
                          3.6, 2.1,  4.2, 2.0,
Packit ea1746
                          2.0, 1.0,  3.1, 5.2};
Packit ea1746
   Grid2D<double, 1>  array(data, 0, 3, 0, 4);
Packit ea1746
   BiCubicInterpolator interpolator(array);
Packit ea1746
   double f, dfdr, dfdc;
Packit ea1746
   interpolator.Evaluate(1.2, 2.5, &f, &dfdr, &dfdc);
Packit ea1746
Packit ea1746
In the above code, the templated helper class ``Grid2D`` is used to
Packit ea1746
make a ``C++`` array look like a two dimensional table to
Packit ea1746
:class:`BiCubicInterpolator`.
Packit ea1746
Packit ea1746
``Grid2D`` supports row or column major layouts. It also supports
Packit ea1746
vector valued functions where the individual coordinates of the
Packit ea1746
function may be interleaved or stacked. It also allows the use of any
Packit ea1746
numeric type as input, as long as it can be safely cast to double.