.. default-domain:: cpp

.. highlight:: c++

.. cpp:namespace:: ceres

.. _`chapter-nnls_modeling`:

=================================
Modeling Non-linear Least Squares
=================================

Introduction
============

Ceres solver consists of two distinct parts. A modeling API which
provides a rich set of tools to construct an optimization problem one
term at a time and a solver API that controls the minimization
algorithm. This chapter is devoted to the task of modeling
optimization problems using Ceres. :ref:`chapter-nnls_solving` discusses
the various ways in which an optimization problem can be solved using
Ceres.

Ceres solves robustified bounds constrained non-linear least squares
problems of the form:

.. math:: :label: ceresproblem_modeling

   \min_{\mathbf{x}} &\quad \frac{1}{2}\sum_{i}
   \rho_i\left(\left\|f_i\left(x_{i_1},
   ... ,x_{i_k}\right)\right\|^2\right)  \\
   \text{s.t.} &\quad l_j \le x_j \le u_j

In Ceres parlance, the expression
:math:`\rho_i\left(\left\|f_i\left(x_{i_1},...,x_{i_k}\right)\right\|^2\right)`
is known as a **residual block**, where :math:`f_i(\cdot)` is a
:class:`CostFunction` that depends on the **parameter blocks**
:math:`\left\{x_{i_1},... , x_{i_k}\right\}`.

In most optimization problems small groups of scalars occur
together. For example the three components of a translation vector and
the four components of the quaternion that define the pose of a
camera. We refer to such a group of scalars as a **parameter block**. Of
course a parameter block can be just a single scalar too.

:math:`\rho_i` is a :class:`LossFunction`. A :class:`LossFunction` is
a scalar valued function that is used to reduce the influence of
outliers on the solution of non-linear least squares problems.

:math:`l_j` and :math:`u_j` are lower and upper bounds on the
parameter block :math:`x_j`.

As a special case, when :math:`\rho_i(x) = x`, i.e., the identity
function, and :math:`l_j = -\infty` and :math:`u_j = \infty` we get
the usual unconstrained `non-linear least squares problem
<http://en.wikipedia.org/wiki/Non-linear_least_squares>`_.

.. math:: :label: ceresproblemunconstrained

   \frac{1}{2}\sum_{i} \left\|f_i\left(x_{i_1}, ... ,x_{i_k}\right)\right\|^2.

:class:`CostFunction`
=====================

For each term in the objective function, a :class:`CostFunction` is
responsible for computing a vector of residuals and Jacobian
matrices. Concretely, consider a function
:math:`f\left(x_{1},...,x_{k}\right)` that depends on parameter blocks
:math:`\left[x_{1}, ... , x_{k}\right]`.

Then, given :math:`\left[x_{1}, ... , x_{k}\right]`,
:class:`CostFunction` is responsible for computing the vector
:math:`f\left(x_{1},...,x_{k}\right)` and the Jacobian matrices

.. math:: J_i =  D_i f(x_1, ..., x_k) \quad \forall i \in \{1, \ldots, k\}

.. class:: CostFunction

   .. code-block:: c++

    class CostFunction {
     public:
      virtual bool Evaluate(double const* const* parameters,
                            double* residuals,
                            double** jacobians) = 0;
      const vector<int32>& parameter_block_sizes();
      int num_residuals() const;

     protected:
      vector<int32>* mutable_parameter_block_sizes();
      void set_num_residuals(int num_residuals);
    };


The signature of the :class:`CostFunction` (number and sizes of input
parameter blocks and number of outputs) is stored in
:member:`CostFunction::parameter_block_sizes_` and
:member:`CostFunction::num_residuals_` respectively. User code
inheriting from this class is expected to set these two members with
the corresponding accessors. This information will be verified by the
:class:`Problem` when added with :func:`Problem::AddResidualBlock`.

.. function:: bool CostFunction::Evaluate(double const* const* parameters, double* residuals, double** jacobians)

   Compute the residual vector and the Jacobian matrices.

   ``parameters`` is an array of arrays of size
   ``CostFunction::parameter_block_sizes_.size()`` and
   ``parameters[i]`` is an array of size ``parameter_block_sizes_[i]``
   that contains the :math:`i^{\text{th}}` parameter block that the
   ``CostFunction`` depends on.

   ``parameters`` is never ``nullptr``.

   ``residuals`` is an array of size ``num_residuals_``.

   ``residuals`` is never ``nullptr``.

   ``jacobians`` is an array of arrays of size
   ``CostFunction::parameter_block_sizes_.size()``.

   If ``jacobians`` is ``nullptr``, the user is only expected to compute
   the residuals.

   ``jacobians[i]`` is a row-major array of size ``num_residuals x
   parameter_block_sizes_[i]``.

   If ``jacobians[i]`` is **not** ``nullptr``, the user is required to
   compute the Jacobian of the residual vector with respect to
   ``parameters[i]`` and store it in this array, i.e.

   ``jacobians[i][r * parameter_block_sizes_[i] + c]`` =
   :math:`\frac{\displaystyle \partial \text{residual}[r]}{\displaystyle \partial \text{parameters}[i][c]}`

   If ``jacobians[i]`` is ``nullptr``, then this computation can be
   skipped. This is the case when the corresponding parameter block is
   marked constant.

   The return value indicates whether the computation of the residuals
   and/or jacobians was successful or not. This can be used to
   communicate numerical failures in Jacobian computations for
   instance.

:class:`SizedCostFunction`
==========================

.. class:: SizedCostFunction

   If the size of the parameter blocks and the size of the residual
   vector is known at compile time (this is the common case),
   :class:`SizeCostFunction` can be used where these values can be
   specified as template parameters and the user only needs to
   implement :func:`CostFunction::Evaluate`.

   .. code-block:: c++

    template<int kNumResiduals, int... Ns>
    class SizedCostFunction : public CostFunction {
     public:
      virtual bool Evaluate(double const* const* parameters,
                            double* residuals,
                            double** jacobians) const = 0;
    };


:class:`AutoDiffCostFunction`
=============================

.. class:: AutoDiffCostFunction

   Defining a :class:`CostFunction` or a :class:`SizedCostFunction`
   can be a tedious and error prone especially when computing
   derivatives.  To this end Ceres provides `automatic differentiation
   <http://en.wikipedia.org/wiki/Automatic_differentiation>`_.

   .. code-block:: c++

     template <typename CostFunctor,
            int kNumResiduals,  // Number of residuals, or ceres::DYNAMIC.
            int... Ns>          // Size of each parameter block
     class AutoDiffCostFunction : public
     SizedCostFunction<kNumResiduals, Ns> {
      public:
       AutoDiffCostFunction(CostFunctor* functor, ownership = TAKE_OWNERSHIP);
       // Ignore the template parameter kNumResiduals and use
       // num_residuals instead.
       AutoDiffCostFunction(CostFunctor* functor,
                            int num_residuals,
                            ownership = TAKE_OWNERSHIP);
     };

   To get an auto differentiated cost function, you must define a
   class with a templated ``operator()`` (a functor) that computes the
   cost function in terms of the template parameter ``T``. The
   autodiff framework substitutes appropriate ``Jet`` objects for
   ``T`` in order to compute the derivative when necessary, but this
   is hidden, and you should write the function as if ``T`` were a
   scalar type (e.g. a double-precision floating point number).

   The function must write the computed value in the last argument
   (the only non-``const`` one) and return true to indicate success.

   For example, consider a scalar error :math:`e = k - x^\top y`,
   where both :math:`x` and :math:`y` are two-dimensional vector
   parameters and :math:`k` is a constant. The form of this error,
   which is the difference between a constant and an expression, is a
   common pattern in least squares problems. For example, the value
   :math:`x^\top y` might be the model expectation for a series of
   measurements, where there is an instance of the cost function for
   each measurement :math:`k`.

   The actual cost added to the total problem is :math:`e^2`, or
   :math:`(k - x^\top y)^2`; however, the squaring is implicitly done
   by the optimization framework.

   To write an auto-differentiable cost function for the above model,
   first define the object

   .. code-block:: c++

    class MyScalarCostFunctor {
      MyScalarCostFunctor(double k): k_(k) {}

      template <typename T>
      bool operator()(const T* const x , const T* const y, T* e) const {
        e[0] = k_ - x[0] * y[0] - x[1] * y[1];
        return true;
      }

     private:
      double k_;
    };


   Note that in the declaration of ``operator()`` the input parameters
   ``x`` and ``y`` come first, and are passed as const pointers to arrays
   of ``T``. If there were three input parameters, then the third input
   parameter would come after ``y``. The output is always the last
   parameter, and is also a pointer to an array. In the example above,
   ``e`` is a scalar, so only ``e[0]`` is set.

   Then given this class definition, the auto differentiated cost
   function for it can be constructed as follows.

   .. code-block:: c++

    CostFunction* cost_function
        = new AutoDiffCostFunction<MyScalarCostFunctor, 1, 2, 2>(
            new MyScalarCostFunctor(1.0));              ^  ^  ^
                                                        |  |  |
                            Dimension of residual ------+  |  |
                            Dimension of x ----------------+  |
                            Dimension of y -------------------+


   In this example, there is usually an instance for each measurement
   of ``k``.

   In the instantiation above, the template parameters following
   ``MyScalarCostFunction``, ``<1, 2, 2>`` describe the functor as
   computing a 1-dimensional output from two arguments, both
   2-dimensional.

   By default :class:`AutoDiffCostFunction` will take ownership of the cost
   functor pointer passed to it, ie. will call `delete` on the cost functor
   when the :class:`AutoDiffCostFunction` itself is deleted. However, this may
   be undesirable in certain cases, therefore it is also possible to specify
   :class:`DO_NOT_TAKE_OWNERSHIP` as a second argument in the constructor,
   while passing a pointer to a cost functor which does not need to be deleted
   by the AutoDiffCostFunction. For example:

   .. code-block:: c++

    MyScalarCostFunctor functor(1.0)
    CostFunction* cost_function
        = new AutoDiffCostFunction<MyScalarCostFunctor, 1, 2, 2>(
            &functor, DO_NOT_TAKE_OWNERSHIP);

   :class:`AutoDiffCostFunction` also supports cost functions with a
   runtime-determined number of residuals. For example:

   .. code-block:: c++

     CostFunction* cost_function
         = new AutoDiffCostFunction<MyScalarCostFunctor, DYNAMIC, 2, 2>(
             new CostFunctorWithDynamicNumResiduals(1.0),   ^     ^  ^
             runtime_number_of_residuals); <----+           |     |  |
                                                |           |     |  |
                                                |           |     |  |
               Actual number of residuals ------+           |     |  |
               Indicate dynamic number of residuals --------+     |  |
               Dimension of x ------------------------------------+  |
               Dimension of y ---------------------------------------+

   **WARNING 1** A common beginner's error when first using
   :class:`AutoDiffCostFunction` is to get the sizing wrong. In particular,
   there is a tendency to set the template parameters to (dimension of
   residual, number of parameters) instead of passing a dimension
   parameter for *every parameter block*. In the example above, that
   would be ``<MyScalarCostFunction, 1, 2>``, which is missing the 2
   as the last template argument.


:class:`DynamicAutoDiffCostFunction`
====================================

.. class:: DynamicAutoDiffCostFunction

   :class:`AutoDiffCostFunction` requires that the number of parameter
   blocks and their sizes be known at compile time. In a number of
   applications, this is not enough e.g., Bezier curve fitting, Neural
   Network training etc.

     .. code-block:: c++

      template <typename CostFunctor, int Stride = 4>
      class DynamicAutoDiffCostFunction : public CostFunction {
      };

   In such cases :class:`DynamicAutoDiffCostFunction` can be
   used. Like :class:`AutoDiffCostFunction` the user must define a
   templated functor, but the signature of the functor differs
   slightly. The expected interface for the cost functors is:

     .. code-block:: c++

       struct MyCostFunctor {
         template<typename T>
         bool operator()(T const* const* parameters, T* residuals) const {
         }
       }

   Since the sizing of the parameters is done at runtime, you must
   also specify the sizes after creating the dynamic autodiff cost
   function. For example:

     .. code-block:: c++

       DynamicAutoDiffCostFunction<MyCostFunctor, 4>* cost_function =
         new DynamicAutoDiffCostFunction<MyCostFunctor, 4>(
           new MyCostFunctor());
       cost_function->AddParameterBlock(5);
       cost_function->AddParameterBlock(10);
       cost_function->SetNumResiduals(21);

   Under the hood, the implementation evaluates the cost function
   multiple times, computing a small set of the derivatives (four by
   default, controlled by the ``Stride`` template parameter) with each
   pass. There is a performance tradeoff with the size of the passes;
   Smaller sizes are more cache efficient but result in larger number
   of passes, and larger stride lengths can destroy cache-locality
   while reducing the number of passes over the cost function. The
   optimal value depends on the number and sizes of the various
   parameter blocks.

   As a rule of thumb, try using :class:`AutoDiffCostFunction` before
   you use :class:`DynamicAutoDiffCostFunction`.

:class:`NumericDiffCostFunction`
================================

.. class:: NumericDiffCostFunction

  In some cases, its not possible to define a templated cost functor,
  for example when the evaluation of the residual involves a call to a
  library function that you do not have control over.  In such a
  situation, `numerical differentiation
  <http://en.wikipedia.org/wiki/Numerical_differentiation>`_ can be
  used.

  .. NOTE ::

    TODO(sameeragarwal): Add documentation for the constructor and for
    NumericDiffOptions. Update DynamicNumericDiffOptions in a similar
    manner.

  .. code-block:: c++

      template <typename CostFunctor,
                NumericDiffMethodType method = CENTRAL,
                int kNumResiduals,  // Number of residuals, or ceres::DYNAMIC.
                int... Ns>          // Size of each parameter block.
      class NumericDiffCostFunction : public
      SizedCostFunction<kNumResiduals, Ns> {
      };

  To get a numerically differentiated :class:`CostFunction`, you must
  define a class with a ``operator()`` (a functor) that computes the
  residuals. The functor must write the computed value in the last
  argument (the only non-``const`` one) and return ``true`` to
  indicate success.  Please see :class:`CostFunction` for details on
  how the return value may be used to impose simple constraints on the
  parameter block. e.g., an object of the form

  .. code-block:: c++

     struct ScalarFunctor {
      public:
       bool operator()(const double* const x1,
                       const double* const x2,
                       double* residuals) const;
     }

  For example, consider a scalar error :math:`e = k - x'y`, where both
  :math:`x` and :math:`y` are two-dimensional column vector
  parameters, the prime sign indicates transposition, and :math:`k` is
  a constant. The form of this error, which is the difference between
  a constant and an expression, is a common pattern in least squares
  problems. For example, the value :math:`x'y` might be the model
  expectation for a series of measurements, where there is an instance
  of the cost function for each measurement :math:`k`.

  To write an numerically-differentiable class:`CostFunction` for the
  above model, first define the object

  .. code-block::  c++

     class MyScalarCostFunctor {
       MyScalarCostFunctor(double k): k_(k) {}

       bool operator()(const double* const x,
                       const double* const y,
                       double* residuals) const {
         residuals[0] = k_ - x[0] * y[0] + x[1] * y[1];
         return true;
       }

      private:
       double k_;
     };

  Note that in the declaration of ``operator()`` the input parameters
  ``x`` and ``y`` come first, and are passed as const pointers to
  arrays of ``double`` s. If there were three input parameters, then
  the third input parameter would come after ``y``. The output is
  always the last parameter, and is also a pointer to an array. In the
  example above, the residual is a scalar, so only ``residuals[0]`` is
  set.

  Then given this class definition, the numerically differentiated
  :class:`CostFunction` with central differences used for computing
  the derivative can be constructed as follows.

  .. code-block:: c++

    CostFunction* cost_function
        = new NumericDiffCostFunction<MyScalarCostFunctor, CENTRAL, 1, 2, 2>(
            new MyScalarCostFunctor(1.0));                    ^     ^  ^  ^
                                                              |     |  |  |
                                  Finite Differencing Scheme -+     |  |  |
                                  Dimension of residual ------------+  |  |
                                  Dimension of x ----------------------+  |
                                  Dimension of y -------------------------+

  In this example, there is usually an instance for each measurement
  of `k`.

  In the instantiation above, the template parameters following
  ``MyScalarCostFunctor``, ``1, 2, 2``, describe the functor as
  computing a 1-dimensional output from two arguments, both
  2-dimensional.

  NumericDiffCostFunction also supports cost functions with a
  runtime-determined number of residuals. For example:

   .. code-block:: c++

     CostFunction* cost_function
         = new NumericDiffCostFunction<MyScalarCostFunctor, CENTRAL, DYNAMIC, 2, 2>(
             new CostFunctorWithDynamicNumResiduals(1.0),               ^     ^  ^
             TAKE_OWNERSHIP,                                            |     |  |
             runtime_number_of_residuals); <----+                       |     |  |
                                                |                       |     |  |
                                                |                       |     |  |
               Actual number of residuals ------+                       |     |  |
               Indicate dynamic number of residuals --------------------+     |  |
               Dimension of x ------------------------------------------------+  |
               Dimension of y ---------------------------------------------------+


  There are three available numeric differentiation schemes in ceres-solver:

  The ``FORWARD`` difference method, which approximates :math:`f'(x)`
  by computing :math:`\frac{f(x+h)-f(x)}{h}`, computes the cost
  function one additional time at :math:`x+h`. It is the fastest but
  least accurate method.

  The ``CENTRAL`` difference method is more accurate at the cost of
  twice as many function evaluations than forward difference,
  estimating :math:`f'(x)` by computing
  :math:`\frac{f(x+h)-f(x-h)}{2h}`.

  The ``RIDDERS`` difference method[Ridders]_ is an adaptive scheme
  that estimates derivatives by performing multiple central
  differences at varying scales. Specifically, the algorithm starts at
  a certain :math:`h` and as the derivative is estimated, this step
  size decreases.  To conserve function evaluations and estimate the
  derivative error, the method performs Richardson extrapolations
  between the tested step sizes.  The algorithm exhibits considerably
  higher accuracy, but does so by additional evaluations of the cost
  function.

  Consider using ``CENTRAL`` differences to begin with. Based on the
  results, either try forward difference to improve performance or
  Ridders' method to improve accuracy.

  **WARNING** A common beginner's error when first using
  :class:`NumericDiffCostFunction` is to get the sizing wrong. In
  particular, there is a tendency to set the template parameters to
  (dimension of residual, number of parameters) instead of passing a
  dimension parameter for *every parameter*. In the example above,
  that would be ``<MyScalarCostFunctor, 1, 2>``, which is missing the
  last ``2`` argument. Please be careful when setting the size
  parameters.


Numeric Differentiation & Manifolds
-----------------------------------

   If your cost function depends on a parameter block that must lie on
   a manifold and the functor cannot be evaluated for values of that
   parameter block not on the manifold then you may have problems
   numerically differentiating such functors.

   This is because numeric differentiation in Ceres is performed by
   perturbing the individual coordinates of the parameter blocks that
   a cost functor depends on. This perturbation assumes that the
   parameter block lives on a Euclidean Manifold rather than the
   actual manifold associated with the parameter block. As a result
   some of the perturbed points may not lie on the manifold anymore.

   For example consider a four dimensional parameter block that is
   interpreted as a unit Quaternion. Perturbing the coordinates of
   this parameter block will violate the unit norm property of the
   parameter block.

   Fixing this problem requires that :class:`NumericDiffCostFunction`
   be aware of the :class:`Manifold` associated with each
   parameter block and only generate perturbations in the local
   tangent space of each parameter block.

   For now this is not considered to be a serious enough problem to
   warrant changing the :class:`NumericDiffCostFunction` API. Further,
   in most cases it is relatively straightforward to project a point
   off the manifold back onto the manifold before using it in the
   functor. For example in case of the Quaternion, normalizing the
   4-vector before using it does the trick.

   **Alternate Interface**

   For a variety of reasons, including compatibility with legacy code,
   :class:`NumericDiffCostFunction` can also take
   :class:`CostFunction` objects as input. The following describes
   how.

   To get a numerically differentiated cost function, define a
   subclass of :class:`CostFunction` such that the
   :func:`CostFunction::Evaluate` function ignores the ``jacobians``
   parameter. The numeric differentiation wrapper will fill in the
   jacobian parameter if necessary by repeatedly calling the
   :func:`CostFunction::Evaluate` with small changes to the
   appropriate parameters, and computing the slope. For performance,
   the numeric differentiation wrapper class is templated on the
   concrete cost function, even though it could be implemented only in
   terms of the :class:`CostFunction` interface.

   The numerically differentiated version of a cost function for a
   cost function can be constructed as follows:

   .. code-block:: c++

     CostFunction* cost_function
         = new NumericDiffCostFunction<MyCostFunction, CENTRAL, 1, 4, 8>(
             new MyCostFunction(...), TAKE_OWNERSHIP);

   where ``MyCostFunction`` has 1 residual and 2 parameter blocks with
   sizes 4 and 8 respectively. Look at the tests for a more detailed
   example.

:class:`DynamicNumericDiffCostFunction`
=======================================

.. class:: DynamicNumericDiffCostFunction

   Like :class:`AutoDiffCostFunction` :class:`NumericDiffCostFunction`
   requires that the number of parameter blocks and their sizes be
   known at compile time. In a number of applications, this is not enough.

     .. code-block:: c++

      template <typename CostFunctor, NumericDiffMethodType method = CENTRAL>
      class DynamicNumericDiffCostFunction : public CostFunction {
      };

   In such cases when numeric differentiation is desired,
   :class:`DynamicNumericDiffCostFunction` can be used.

   Like :class:`NumericDiffCostFunction` the user must define a
   functor, but the signature of the functor differs slightly. The
   expected interface for the cost functors is:

     .. code-block:: c++

       struct MyCostFunctor {
         bool operator()(double const* const* parameters, double* residuals) const {
         }
       }

   Since the sizing of the parameters is done at runtime, you must
   also specify the sizes after creating the dynamic numeric diff cost
   function. For example:

     .. code-block:: c++

       DynamicNumericDiffCostFunction<MyCostFunctor>* cost_function =
         new DynamicNumericDiffCostFunction<MyCostFunctor>(new MyCostFunctor);
       cost_function->AddParameterBlock(5);
       cost_function->AddParameterBlock(10);
       cost_function->SetNumResiduals(21);

   As a rule of thumb, try using :class:`NumericDiffCostFunction` before
   you use :class:`DynamicNumericDiffCostFunction`.

   **WARNING** The same caution about mixing manifolds with numeric
   differentiation applies as is the case with
   :class:`NumericDiffCostFunction`.

:class:`CostFunctionToFunctor`
==============================

.. class:: CostFunctionToFunctor

   :class:`CostFunctionToFunctor` is an adapter class that allows
   users to use :class:`CostFunction` objects in templated functors
   which are to be used for automatic differentiation. This allows
   the user to seamlessly mix analytic, numeric and automatic
   differentiation.

   For example, let us assume that

   .. code-block:: c++

     class IntrinsicProjection : public SizedCostFunction<2, 5, 3> {
       public:
         IntrinsicProjection(const double* observation);
         virtual bool Evaluate(double const* const* parameters,
                               double* residuals,
                               double** jacobians) const;
     };

   is a :class:`CostFunction` that implements the projection of a
   point in its local coordinate system onto its image plane and
   subtracts it from the observed point projection. It can compute its
   residual and either via analytic or numerical differentiation can
   compute its jacobians.

   Now we would like to compose the action of this
   :class:`CostFunction` with the action of camera extrinsics, i.e.,
   rotation and translation. Say we have a templated function

   .. code-block:: c++

      template<typename T>
      void RotateAndTranslatePoint(const T* rotation,
                                   const T* translation,
                                   const T* point,
                                   T* result);


   Then we can now do the following,

   .. code-block:: c++

    struct CameraProjection {
      CameraProjection(double* observation)
      : intrinsic_projection_(new IntrinsicProjection(observation)) {
      }

      template <typename T>
      bool operator()(const T* rotation,
                      const T* translation,
                      const T* intrinsics,
                      const T* point,
                      T* residual) const {
        T transformed_point[3];
        RotateAndTranslatePoint(rotation, translation, point, transformed_point);

        // Note that we call intrinsic_projection_, just like it was
        // any other templated functor.
        return intrinsic_projection_(intrinsics, transformed_point, residual);
      }

     private:
      CostFunctionToFunctor<2,5,3> intrinsic_projection_;
    };

   Note that :class:`CostFunctionToFunctor` takes ownership of the
   :class:`CostFunction` that was passed in to the constructor.

   In the above example, we assumed that ``IntrinsicProjection`` is a
   ``CostFunction`` capable of evaluating its value and its
   derivatives. Suppose, if that were not the case and
   ``IntrinsicProjection`` was defined as follows:

   .. code-block:: c++

    struct IntrinsicProjection {
      IntrinsicProjection(const double* observation) {
        observation_[0] = observation[0];
        observation_[1] = observation[1];
      }

      bool operator()(const double* calibration,
                      const double* point,
                      double* residuals) const {
        double projection[2];
        ThirdPartyProjectionFunction(calibration, point, projection);
        residuals[0] = observation_[0] - projection[0];
        residuals[1] = observation_[1] - projection[1];
        return true;
      }
      double observation_[2];
    };


  Here ``ThirdPartyProjectionFunction`` is some third party library
  function that we have no control over. So this function can compute
  its value and we would like to use numeric differentiation to
  compute its derivatives. In this case we can use a combination of
  ``NumericDiffCostFunction`` and ``CostFunctionToFunctor`` to get the
  job done.

  .. code-block:: c++

   struct CameraProjection {
     CameraProjection(double* observation)
        : intrinsic_projection_(
              new NumericDiffCostFunction<IntrinsicProjection, CENTRAL, 2, 5, 3>(
                  new IntrinsicProjection(observation))) {}

     template <typename T>
     bool operator()(const T* rotation,
                     const T* translation,
                     const T* intrinsics,
                     const T* point,
                     T* residuals) const {
       T transformed_point[3];
       RotateAndTranslatePoint(rotation, translation, point, transformed_point);
       return intrinsic_projection_(intrinsics, transformed_point, residuals);
     }

    private:
     CostFunctionToFunctor<2, 5, 3> intrinsic_projection_;
   };


:class:`DynamicCostFunctionToFunctor`
=====================================

.. class:: DynamicCostFunctionToFunctor

   :class:`DynamicCostFunctionToFunctor` provides the same functionality as
   :class:`CostFunctionToFunctor` for cases where the number and size of the
   parameter vectors and residuals are not known at compile-time. The API
   provided by :class:`DynamicCostFunctionToFunctor` matches what would be
   expected by :class:`DynamicAutoDiffCostFunction`, i.e. it provides a
   templated functor of this form:

   .. code-block:: c++

    template<typename T>
    bool operator()(T const* const* parameters, T* residuals) const;

   Similar to the example given for :class:`CostFunctionToFunctor`, let us
   assume that

   .. code-block:: c++

     class IntrinsicProjection : public CostFunction {
       public:
         IntrinsicProjection(const double* observation);
         virtual bool Evaluate(double const* const* parameters,
                               double* residuals,
                               double** jacobians) const;
     };

   is a :class:`CostFunction` that projects a point in its local coordinate
   system onto its image plane and subtracts it from the observed point
   projection.

   Using this :class:`CostFunction` in a templated functor would then look like
   this:

   .. code-block:: c++

    struct CameraProjection {
      CameraProjection(double* observation)
          : intrinsic_projection_(new IntrinsicProjection(observation)) {
      }

      template <typename T>
      bool operator()(T const* const* parameters,
                      T* residual) const {
        const T* rotation = parameters[0];
        const T* translation = parameters[1];
        const T* intrinsics = parameters[2];
        const T* point = parameters[3];

        T transformed_point[3];
        RotateAndTranslatePoint(rotation, translation, point, transformed_point);

        const T* projection_parameters[2];
        projection_parameters[0] = intrinsics;
        projection_parameters[1] = transformed_point;
        return intrinsic_projection_(projection_parameters, residual);
      }

     private:
      DynamicCostFunctionToFunctor intrinsic_projection_;
    };

   Like :class:`CostFunctionToFunctor`, :class:`DynamicCostFunctionToFunctor`
   takes ownership of the :class:`CostFunction` that was passed in to the
   constructor.

:class:`ConditionedCostFunction`
================================

.. class:: ConditionedCostFunction

   This class allows you to apply different conditioning to the residual
   values of a wrapped cost function. An example where this is useful is
   where you have an existing cost function that produces N values, but you
   want the total cost to be something other than just the sum of these
   squared values - maybe you want to apply a different scaling to some
   values, to change their contribution to the cost.

   Usage:

   .. code-block:: c++

       //  my_cost_function produces N residuals
       CostFunction* my_cost_function = ...
       CHECK_EQ(N, my_cost_function->num_residuals());
       vector<CostFunction*> conditioners;

       //  Make N 1x1 cost functions (1 parameter, 1 residual)
       CostFunction* f_1 = ...
       conditioners.push_back(f_1);

       CostFunction* f_N = ...
       conditioners.push_back(f_N);
       ConditionedCostFunction* ccf =
         new ConditionedCostFunction(my_cost_function, conditioners);


   Now ``ccf`` 's ``residual[i]`` (i=0..N-1) will be passed though the
   :math:`i^{\text{th}}` conditioner.

   .. code-block:: c++

      ccf_residual[i] = f_i(my_cost_function_residual[i])

   and the Jacobian will be affected appropriately.


:class:`GradientChecker`
========================

.. class:: GradientChecker

    This class compares the Jacobians returned by a cost function
    against derivatives estimated using finite differencing. It is
    meant as a tool for unit testing, giving you more fine-grained
    control than the check_gradients option in the solver options.

    The condition enforced is that

    .. math:: \forall{i,j}: \frac{J_{ij} - J'_{ij}}{max_{ij}(J_{ij} - J'_{ij})} < r

    where :math:`J_{ij}` is the jacobian as computed by the supplied
    cost function multiplied by the `Manifold::PlusJacobian`,
    :math:`J'_{ij}` is the jacobian as computed by finite differences,
    multiplied by the `Manifold::PlusJacobian` as well, and :math:`r`
    is the relative precision.

   Usage:

   .. code-block:: c++

       // my_cost_function takes two parameter blocks. The first has a
       // manifold associated with it.

       CostFunction* my_cost_function = ...
       Manifold* my_manifold = ...
       NumericDiffOptions numeric_diff_options;

       std::vector<Manifold*> manifolds;
       manifolds.push_back(my_manifold);
       manifolds.push_back(nullptr);

       std::vector parameter1;
       std::vector parameter2;
       // Fill parameter 1 & 2 with test data...

       std::vector<double*> parameter_blocks;
       parameter_blocks.push_back(parameter1.data());
       parameter_blocks.push_back(parameter2.data());

       GradientChecker gradient_checker(my_cost_function,
                                        manifolds,
                                        numeric_diff_options);
       GradientCheckResults results;
       if (!gradient_checker.Probe(parameter_blocks.data(), 1e-9, &results) {
         LOG(ERROR) << "An error has occurred:\n" << results.error_log;
       }


:class:`NormalPrior`
====================

.. class:: NormalPrior

   .. code-block:: c++

     class NormalPrior: public CostFunction {
      public:
       // Check that the number of rows in the vector b are the same as the
       // number of columns in the matrix A, crash otherwise.
       NormalPrior(const Matrix& A, const Vector& b);

       virtual bool Evaluate(double const* const* parameters,
                             double* residuals,
                             double** jacobians) const;
      };

   Implements a cost function of the form

   .. math::  cost(x) = ||A(x - b)||^2

   where, the matrix :math:`A` and the vector :math:`b` are fixed and :math:`x`
   is the variable. In case the user is interested in implementing a cost
   function of the form

  .. math::  cost(x) = (x - \mu)^T S^{-1} (x - \mu)

  where, :math:`\mu` is a vector and :math:`S` is a covariance matrix,
  then, :math:`A = S^{-1/2}`, i.e the matrix :math:`A` is the square
  root of the inverse of the covariance, also known as the stiffness
  matrix. There are however no restrictions on the shape of
  :math:`A`. It is free to be rectangular, which would be the case if
  the covariance matrix :math:`S` is rank deficient.



.. _`section-loss_function`:

:class:`LossFunction`
=====================

.. class:: LossFunction

   For least squares problems where the minimization may encounter
   input terms that contain outliers, that is, completely bogus
   measurements, it is important to use a loss function that reduces
   their influence.

   Consider a structure from motion problem. The unknowns are 3D
   points and camera parameters, and the measurements are image
   coordinates describing the expected reprojected position for a
   point in a camera. For example, we want to model the geometry of a
   street scene with fire hydrants and cars, observed by a moving
   camera with unknown parameters, and the only 3D points we care
   about are the pointy tippy-tops of the fire hydrants. Our magic
   image processing algorithm, which is responsible for producing the
   measurements that are input to Ceres, has found and matched all
   such tippy-tops in all image frames, except that in one of the
   frame it mistook a car's headlight for a hydrant. If we didn't do
   anything special the residual for the erroneous measurement will
   result in the entire solution getting pulled away from the optimum
   to reduce the large error that would otherwise be attributed to the
   wrong measurement.

   Using a robust loss function, the cost for large residuals is
   reduced. In the example above, this leads to outlier terms getting
   down-weighted so they do not overly influence the final solution.

   .. code-block:: c++

    class LossFunction {
     public:
      virtual void Evaluate(double s, double out[3]) const = 0;
    };


   The key method is :func:`LossFunction::Evaluate`, which given a
   non-negative scalar ``s``, computes

   .. math:: out = \begin{bmatrix}\rho(s), & \rho'(s), & \rho''(s)\end{bmatrix}

   Here the convention is that the contribution of a term to the cost
   function is given by :math:`\frac{1}{2}\rho(s)`, where :math:`s
   =\|f_i\|^2`. Calling the method with a negative value of :math:`s`
   is an error and the implementations are not required to handle that
   case.

   Most sane choices of :math:`\rho` satisfy:

   .. math::

      \rho(0) &= 0\\
      \rho'(0) &= 1\\
      \rho'(s) &< 1 \text{ in the outlier region}\\
      \rho''(s) &< 0 \text{ in the outlier region}

   so that they mimic the squared cost for small residuals.

   **Scaling**

   Given one robustifier :math:`\rho(s)` one can change the length
   scale at which robustification takes place, by adding a scale
   factor :math:`a > 0` which gives us :math:`\rho(s,a) = a^2 \rho(s /
   a^2)` and the first and second derivatives as :math:`\rho'(s /
   a^2)` and :math:`(1 / a^2) \rho''(s / a^2)` respectively.


   The reason for the appearance of squaring is that :math:`a` is in
   the units of the residual vector norm whereas :math:`s` is a squared
   norm. For applications it is more convenient to specify :math:`a` than
   its square.

Instances
---------

Ceres includes a number of predefined loss functions. For simplicity
we described their unscaled versions. The figure below illustrates
their shape graphically. More details can be found in
``include/ceres/loss_function.h``.

.. figure:: loss.png
   :figwidth: 500px
   :height: 400px
   :align: center

   Shape of the various common loss functions.

.. class:: TrivialLoss

      .. math:: \rho(s) = s

.. class:: HuberLoss

   .. math:: \rho(s) = \begin{cases} s & s \le 1\\ 2 \sqrt{s} - 1 & s > 1 \end{cases}

.. class:: SoftLOneLoss

   .. math:: \rho(s) = 2 (\sqrt{1+s} - 1)

.. class:: CauchyLoss

   .. math:: \rho(s) = \log(1 + s)

.. class:: ArctanLoss

   .. math:: \rho(s) = \arctan(s)

.. class:: TolerantLoss

   .. math:: \rho(s,a,b) = b \log(1 + e^{(s - a) / b}) - b \log(1 + e^{-a / b})

.. class:: ComposedLoss

   Given two loss functions ``f`` and ``g``, implements the loss
   function ``h(s) = f(g(s))``.

   .. code-block:: c++

      class ComposedLoss : public LossFunction {
       public:
        explicit ComposedLoss(const LossFunction* f,
                              Ownership ownership_f,
                              const LossFunction* g,
                              Ownership ownership_g);
      };

.. class:: ScaledLoss

   Sometimes you want to simply scale the output value of the
   robustifier. For example, you might want to weight different error
   terms differently (e.g., weight pixel reprojection errors
   differently from terrain errors).

   Given a loss function :math:`\rho(s)` and a scalar :math:`a`, :class:`ScaledLoss`
   implements the function :math:`a \rho(s)`.

   Since we treat a ``nullptr`` Loss function as the Identity loss
   function, :math:`rho` = ``nullptr``: is a valid input and will result
   in the input being scaled by :math:`a`. This provides a simple way
   of implementing a scaled ResidualBlock.

.. class:: LossFunctionWrapper

   Sometimes after the optimization problem has been constructed, we
   wish to mutate the scale of the loss function. For example, when
   performing estimation from data which has substantial outliers,
   convergence can be improved by starting out with a large scale,
   optimizing the problem and then reducing the scale. This can have
   better convergence behavior than just using a loss function with a
   small scale.

   This templated class allows the user to implement a loss function
   whose scale can be mutated after an optimization problem has been
   constructed, e.g,

   .. code-block:: c++

     Problem problem;

     // Add parameter blocks

     CostFunction* cost_function =
         new AutoDiffCostFunction < UW_Camera_Mapper, 2, 9, 3>(
             new UW_Camera_Mapper(feature_x, feature_y));

     LossFunctionWrapper* loss_function(new HuberLoss(1.0), TAKE_OWNERSHIP);
     problem.AddResidualBlock(cost_function, loss_function, parameters);

     Solver::Options options;
     Solver::Summary summary;
     Solve(options, &problem, &summary);

     loss_function->Reset(new HuberLoss(1.0), TAKE_OWNERSHIP);
     Solve(options, &problem, &summary);


Theory
------

Let us consider a problem with a single parameter block.

.. math::

 \min_x \frac{1}{2}\rho(f^2(x))


Then, the robustified gradient and the Gauss-Newton Hessian are

.. math::

        g(x) &= \rho'J^\top(x)f(x)\\
        H(x) &= J^\top(x)\left(\rho' + 2 \rho''f(x)f^\top(x)\right)J(x)

where the terms involving the second derivatives of :math:`f(x)` have
been ignored. Note that :math:`H(x)` is indefinite if
:math:`\rho''f(x)^\top f(x) + \frac{1}{2}\rho' < 0`. If this is not
the case, then its possible to re-weight the residual and the Jacobian
matrix such that the robustified Gauss-Newton step corresponds to an
ordinary linear least squares problem.

Let :math:`\alpha` be a root of

.. math:: \frac{1}{2}\alpha^2 - \alpha - \frac{\rho''}{\rho'}\|f(x)\|^2 = 0.


Then, define the rescaled residual and Jacobian as

.. math::

        \tilde{f}(x) &= \frac{\sqrt{\rho'}}{1 - \alpha} f(x)\\
        \tilde{J}(x) &= \sqrt{\rho'}\left(1 - \alpha
                        \frac{f(x)f^\top(x)}{\left\|f(x)\right\|^2} \right)J(x)


In the case :math:`2 \rho''\left\|f(x)\right\|^2 + \rho' \lesssim 0`,
we limit :math:`\alpha \le 1- \epsilon` for some small
:math:`\epsilon`. For more details see [Triggs]_.

With this simple rescaling, one can apply any Jacobian based non-linear
least squares algorithm to robustified non-linear least squares
problems.


While the theory described above is elegant, in practice we observe
that using the Triggs correction when :math:`\rho'' > 0` leads to poor
performance, so we upper bound it by zero. For more details see
`corrector.cc <https://github.com/ceres-solver/ceres-solver/blob/master/internal/ceres/corrector.cc#L51>`_


:class:`Manifolds`
==================

.. class:: Manifold

In sensor fusion problems, we often have to model quantities that live
in spaces known as `Manifolds
<https://en.wikipedia.org/wiki/Manifold>`_, for example the
rotation/orientation of a sensor that is represented by a `Quaternion
<https://en.wikipedia.org/wiki/Quaternion>`_.

Manifolds are spaces which locally look like Euclidean spaces. More
precisely, at each point on the manifold there is a linear space that
is tangent to the manifold. It has dimension equal to the intrinsic
dimension of the manifold itself, which is less than or equal to the
ambient space in which the manifold is embedded.

For example, the tangent space to a point on a sphere in three
dimensions is the two dimensional plane that is tangent to the sphere
at that point. There are two reasons tangent spaces are interesting:

1. They are Eucliean spaces so the usual vector space operations apply
   there, which makes numerical operations easy.

2. Movements in the tangent space translate into movements along the
   manifold.  Movements perpendicular to the tangent space do not
   translate into movements on the manifold.

However, moving along the 2 dimensional plane tangent to the sphere
and projecting back onto the sphere will move you away from the point
you started from but moving along the normal at the same point and the
projecting back onto the sphere brings you back to the point.

Besides the mathematical niceness, modeling manifold valued
quantities correctly and paying attention to their geometry has
practical benefits too:

1. It naturally constrains the quantity to the manifold throughout the
   optimization, freeing the user from hacks like *quaternion
   normalization*.

2. It reduces the dimension of the optimization problem to its
   *natural* size. For example, a quantity restricted to a line is a
   one dimensional object regardless of the dimension of the ambient
   space in which this line lives.

   Working in the tangent space reduces not just the computational
   complexity of the optimization algorithm, but also improves the
   numerical behaviour of the algorithm.

A basic operation one can perform on a manifold is the
:math:`\boxplus` operation that computes the result of moving along
:math:`\delta` in the tangent space at :math:`x`, and then projecting
back onto the manifold that :math:`x` belongs to. Also known as a
*Retraction*, :math:`\boxplus` is a generalization of vector addition
in Euclidean spaces.

The inverse of :math:`\boxplus` is :math:`\boxminus`, which given two
points :math:`y` and :math:`x` on the manifold computes the tangent
vector :math:`\Delta` at :math:`x` s.t. :math:`\boxplus(x, \Delta) =
y`.

Let us now consider two examples.

The `Euclidean space <https://en.wikipedia.org/wiki/Euclidean_space>`_
:math:`\mathbb{R}^n` is the simplest example of a manifold. It has
dimension :math:`n` (and so does its tangent space) and
:math:`\boxplus` and :math:`\boxminus` are the familiar vector sum and
difference operations.

.. math::
   \begin{align*}
   \boxplus(x, \Delta) &= x + \Delta = y\\
   \boxminus(y, x) &= y - x = \Delta.
   \end{align*}

A more interesting case is the case :math:`SO(3)`, the `special
orthogonal group <https://en.wikipedia.org/wiki/3D_rotation_group>`_
in three dimensions - the space of 3x3 rotation
matrices. :math:`SO(3)` is a three dimensional manifold embedded in
:math:`R^9` or :math:`R^{3\times 3}`.  So points on :math:`SO(3)` are
represented using 9 dimensional vectors or :math:`3\times 3` matrices,
and points in its tangent spaces are represented by 3 dimensional
vectors.

For :math:`SO(3)`, :math:`\boxplus` and :math:`\boxminus` are defined
in terms of the matrix :math:`\exp` and :math:`\log` operations as
follows:

Given a 3-vector :math:`\Delta = [\begin{matrix}p,&q,&r\end{matrix}]`, we have

.. math::

   \exp(\Delta) & = \left [ \begin{matrix}
   \cos \theta + cp^2 & -sr + cpq        &  sq + cpr \\
   sr + cpq         & \cos \theta + cq^2& -sp + cqr \\
   -sq + cpr        & sp + cqr         & \cos \theta + cr^2
   \end{matrix} \right ]

where,

.. math::
     \begin{align}
     \theta &= \sqrt{p^2 + q^2 + r^2},\\
     s &= \frac{\sin \theta}{\theta},\\
     c &= \frac{1 - \cos \theta}{\theta^2}.
     \end{align}

Given :math:`x \in SO(3)`, we have

.. math::

   \log(x) = 1/(2 \sin(\theta)/\theta)\left[\begin{matrix} x_{32} - x_{23},& x_{13} - x_{31},& x_{21} - x_{12}\end{matrix} \right]


where,

.. math:: \theta = cos^{-1}((\operatorname{Trace}(x) - 1)/2)

Then,

.. math::
   \begin{align*}
   \boxplus(x, \Delta) &= x \exp(\Delta)
   \boxminus(y, x) &= \log(x^T y)
   \end{align*}

For :math:`\boxplus` and :math:`\boxplus` to be mathematically
consistent, the following identities must be satisfied at all points
:math:`x` on the manifold:

1. :math:`\boxplus(x, 0) = x`. This ensures that the tangent space is
   *centered* at :math:`x`, and the zero vector is the identity
   element.
2. For all :math:`y` on the manifold, :math:`\boxplus(x,
   \boxminus(y,x)) = y`. This ensures that any :math:`y` can be
   reached from math:`x`.
3. For all :math:`\Delta`, :math:`\boxminus(\boxplus(x, \Delta), x) =
   \Delta`. This ensures that :math:`\boxplus` is an injective
   (one-to-one) map.
4. For all :math:`\Delta_1, \Delta_2\ |\boxminus(\boxplus(x, \Delta_1),
   \boxplus(x, \Delta_2)) <= |\Delta_1 - \Delta_2|`. Allows us to define
   a metric on the manifold.

Additionally we require that :math:`\boxplus` and :math:`\boxminus` be
sufficiently smooth. In particular they need to be differentiable
everywhere on the manifold.

For more details, please see `Integrating Generic Sensor Fusion
Algorithms with Sound State Representations through Encapsulation of
Manifolds <https://arxiv.org/pdf/1107.1119.pdf>`_
By C. Hertzberg, R. Wagner, U. Frese and L. Schroder

The :class:`Manifold` interface allows the user to define a manifold
for the purposes optimization by implementing ``Plus`` and ``Minus``
operations and their derivatives (corresponding naturally to
:math:`\boxplus` and :math:`boxminus`).

..code-block c++::

  class Manifold {
   public:
    virtual ~Manifold();
    virtual int AmbientSize() const = 0;
    virtual int TangentSize() const = 0;
    virtual bool Plus(const double* x,
                      const double* delta,
                      double* x_plus_delta) const = 0;
    virtual bool PlusJacobian(const double* x, double* jacobian) const = 0;
    virtual bool RightMultiplyByPlusJacobian(const double* x,
                                             const int num_rows,
                                             const double* ambient_matrix,
                                             double* tangent_matrix) const;
    virtual bool Minus(const double* y,
                       const double* x,
                       double* y_minus_x) const = 0;
    virtual bool MinusJacobian(const double* x, double* jacobian) const = 0;
  };


.. function:: int Manifold::AmbientSize() const;

   Dimension of the ambient space in which the manifold is embedded.

.. function:: int Manifold::TangentSize() const;

   Dimension of the manifold/tangent space.

.. function:: bool Plus(const double* x, const double* delta, double* x_plus_delta) const;

   Implements the :math:`\boxplus(x,\Delta)` operation for the manifold.

   A generalization of vector addition in Euclidean space, ``Plus``
   computes the result of moving along ``delta`` in the tangent space
   at ``x``, and then projecting back onto the manifold that ``x``
   belongs to.

   ``x`` and ``x_plus_delta`` are :func:`Manifold::AmbientSize` vectors.
   ``delta`` is a :func:`Manifold::TangentSize` vector.

   Return value indicates if the operation was successful or not.

.. function:: bool PlusJacobian(const double* x, double* jacobian) const;

   Compute the derivative of :math:`\boxplus(x, \Delta)` w.r.t
   :math:`\Delta` at :\math:`\Delta = 0`, i.e. :math:`(D_2
   \boxplus)(x, 0)`.

   ``jacobian`` is a row-major :func:`Manifold::AmbientSize`
   :math:`\times` :func:`Manifold::TangentSize` matrix.

   Return value indicates whether the operation was successful or not.

.. function:: bool RightMultiplyByPlusJacobian(const double* x, const int num_rows, const double* ambient_matrix, double* tangent_matrix) const;

   ``tangent_matrix`` = ``ambient_matrix`` :math:`\times` plus_jacobian.


   ``ambient_matrix`` is a row-major ``num_rows`` :math:`\times`
   :func:`Manifold::AmbientSize` matrix.

   ``tangent_matrix`` is a row-major ``num_rows`` :math:`\times`
   :func:`Manifold::TangentSize` matrix.

   Return value indicates whether the operation was successful or not.

   This function is only used by the :class:`GradientProblemSolver`,
   where the dimension of the parameter block can be large and it may
   be more efficient to compute this product directly rather than
   first evaluating the Jacobian into a matrix and then doing a matrix
   vector product.

   Because this is not an often used function, we provide a default
   implementation for convenience. If performance becomes an issue
   then the user should consider implementing a specialization.

.. function:: bool Minus(const double* y, const double* x, double* y_minus_x) const;

   Implements :math:`\boxminus(y,x)` operation for the manifold.

   A generalization of vector subtraction in Euclidean spaces, given
   two points ``x`` and ``y`` on the manifold, ``Minus`` computes the
   change to ``x`` in the tangent space at ``x``, that will take it to
   ``y``.

   ``x`` and ``y`` are :func:`Manifold::AmbientSize` vectors.
   ``y_minus_x`` is a ::func:`Manifold::TangentSize` vector.

   Return value indicates if the operation was successful or not.

.. function:: bool MinusJacobian(const double* x, double* jacobian) const = 0;

   Compute the derivative of :math:`\boxminus(y, x)` w.r.t :math:`y`
   at :math:`y = x`, i.e :math:`(D_1 \boxminus) (x, x)`.

   ``jacobian`` is a row-major :func:`Manifold::TangentSize`
   :math:`\times` :func:`Manifold::AmbientSize` matrix.

   Return value indicates whether the operation was successful or not.

Ceres Solver ships with a number of commonly used instances of
:class:`Manifold`.

For `Lie Groups <https://en.wikipedia.org/wiki/Lie_group>`_, a great
place to find high quality implementations is the `Sophus
<https://github.com/strasdat/Sophus>`_ library developed by Hauke
Strasdat and his collaborators.

:class:`EuclideanManifold`
--------------------------

.. class:: EuclideanManifold

:class:`EuclideanManifold` as the name implies represents a Euclidean
space, where the :math:`\boxplus` and :math:`\boxminus` operations are
the usual vector addition and subtraction.

.. math::

   \begin{align*}
     \boxplus(x, \Delta) &= x + \Delta\\
      \boxminus(y,x) &= y - x
   \end{align*}

By default parameter blocks are assumed to be Euclidean, so there is
no need to use this manifold on its own. It is provided for the
purpose of testing and for use in combination with other manifolds
using :class:`ProductManifold`.

The class works with dynamic and static ambient space dimensions. If
the ambient space dimensions is known at compile time use

.. code-block:: c++

   EuclideanManifold<3> manifold;

If the ambient space dimensions is not known at compile time the
template parameter needs to be set to `ceres::DYNAMIC` and the actual
dimension needs to be provided as a constructor argument:

.. code-block:: c++

   EuclideanManifold<ceres::DYNAMIC> manifold(ambient_dim);

:class:`SubsetManifold`
-----------------------

.. class:: SubsetManifold

Suppose :math:`x` is a two dimensional vector, and the user wishes to
hold the first coordinate constant. Then, :math:`\Delta` is a scalar
and :math:`\boxplus` is defined as

.. math::
   \boxplus(x, \Delta) = x + \left[ \begin{array}{c} 0 \\ 1 \end{array} \right] \Delta

and given two, two-dimensional vectors :math:`x` and :math:`y` with
the same first coordinate, :math:`\boxminus` is defined as:

.. math::
   \boxminus(y, x) = y[1] - x[1]

:class:`SubsetManifold` generalizes this construction to hold
any part of a parameter block constant by specifying the set of
coordinates that are held constant.

.. NOTE::

   It is legal to hold *all* coordinates of a parameter block to
   constant using a :class:`SubsetManifold`. It is the same as calling
   :func:`Problem::SetParameterBlockConstant` on that parameter block.


:class:`ProductManifold`
------------------------

.. class:: ProductManifold

In cases, where a parameter block is the Cartesian product of a number
of manifolds and you have the manifold of the individual
parameter blocks available, :class:`ProductManifold` can be used to
construct a :class:`Manifold` of the cartesian product.

For the case of the rigid transformation, where say you have a
parameter block of size 7, where the first four entries represent the
rotation as a quaternion, and the next three the translation, a
manifold can be constructed as:

.. code-block:: c++

   ProductManifold se3(new QuaternionManifold, new EuclideanManifold<3>);


:class:`QuaternionManifold`
---------------------------

.. class:: QuaternionManifold

.. NOTE::

   If you are using ``Eigen`` quaternions, then you should use
   :class:`EigenQuaternionManifold` instead because ``Eigen`` uses a
   different memory layout for its Quaternions.

Manifold for a Hamilton `Quaternion
<https://en.wikipedia.org/wiki/Quaternion>`_. Quaternions are a three
dimensional manifold represented as unit norm 4-vectors, i.e.

.. math:: q = \left [\begin{matrix}q_0,& q_1,& q_2,& q_3\end{matrix}\right], \|q\| = 1

is the ambient space representation. Here :math:`q_0` is the scalar
part. :math:`q_1` is the coefficient of :math:`i`, :math:`q_2` is the
coefficient of :math:`j`, and :math:`q_3` is the coeffcient of
:math:`k`. Where:

.. math::

   \begin{align*}
   i\times j &= k,\\
   j\times k &= i,\\
   k\times i &= j,\\
   i\times i &= -1,\\
   j\times j &= -1,\\
   k\times k &= -1.
   \end{align*}

The tangent space is three dimensional and the :math:`\boxplus` and
:math:`\boxminus` operators are defined in term of :math:`\exp` and
:math:`\log` operations.

.. math::

   \boxplus(x, \Delta) = \exp\left(\Delta\right) \otimes  x \\
   \boxminus(y,x) = \log\left(y \otimes x^{-1}\right)

Where :math:`\otimes` is the `Quaternion product
<https://en.wikipedia.org/wiki/Quaternion#Hamilton_product>`_ and
since :math:`x` is a unit quaternion, :math:`x^{-1} = [\begin{matrix}
q_0,& -q_1,& -q_2,& -q_3\end{matrix}]`. Given a vector :math:`\Delta
\in \mathbb{R}^3`,

.. math::
   \exp(\Delta) = \left[ \begin{matrix}
                         \cos\left(\|\Delta\|\right)\\
			 \frac{\displaystyle \sin\left(|\Delta\|\right)}{\displaystyle \|\Delta\|} \Delta
    	                 \end{matrix} \right]

and given a unit quaternion :math:`q = \left [\begin{matrix}q_0,& q_1,& q_2,& q_3\end{matrix}\right]`

.. math::

   \log(q) =  \frac{\operatorname{atan2}\left(\sqrt{1-q_0^2},q_0\right)}{\sqrt{1-q_0^2}} \left [\begin{matrix}q_1,& q_2,& q_3\end{matrix}\right]


:class:`EigenQuaternionManifold`
--------------------------------

.. class:: EigenQuaternionManifold

Implements the quaternion manifold for `Eigen's
<http://eigen.tuxfamily.org/index.php?title=Main_Page>`_
representation of the Hamilton quaternion. Geometrically it is exactly
the same as the :class:`QuaternionManifold` defined above. However,
Eigen uses a different internal memory layout for the elements of the
quaternion than what is commonly used. It stores the quaternion in
memory as :math:`[q_1, q_2, q_3, q_0]` or :math:`[x, y, z, w]` where
the real (scalar) part is last.

Since Ceres operates on parameter blocks which are raw double pointers
this difference is important and requires a different manifold.

:class:`SphereManifold`
-----------------------

.. class:: SphereManifold

This provides a manifold on a sphere meaning that the norm of the
vector stays the same. Such cases often arises in Structure for Motion
problems. One example where they are used is in representing points
whose triangulation is ill-conditioned. Here it is advantageous to use
an over-parameterization since homogeneous vectors can represent
points at infinity.

The ambient space dimension is required to be greater than 1.

The class works with dynamic and static ambient space dimensions. If
the ambient space dimensions is known at compile time use

.. code-block:: c++

   SphereManifold<3> manifold;

If the ambient space dimensions is not known at compile time the
template parameter needs to be set to `ceres::DYNAMIC` and the actual
dimension needs to be provided as a constructor argument:

.. code-block:: c++

   SphereManifold<ceres::DYNAMIC> manifold(ambient_dim);

For more details, please see Section B.2 (p.25) in `Integrating
Generic Sensor Fusion Algorithms with Sound State Representations
through Encapsulation of Manifolds
<https://arxiv.org/pdf/1107.1119.pdf>`_
By C. Hertzberg, R. Wagner, U. Frese and L. Schroder


:class:`LineManifold`
---------------------

.. class:: LineManifold

This class provides a manifold for lines, where the line is defined
using an origin point and a direction vector. So the ambient size
needs to be two times the dimension of the space in which the line
lives.  The first half of the parameter block is interpreted as the
origin point and the second half as the direction. This manifold is a
special case of the `Affine Grassmannian manifold
<https://en.wikipedia.org/wiki/Affine_Grassmannian_(manifold))>`_ for
the case :math:`\operatorname{Graff}_1(R^n)`.

Note that this is a manifold for a line, rather than a point
constrained to lie on a line. It is useful when one wants to optimize
over the space of lines. For example, given :math:`n` distinct points
in 3D (measurements) we want to find the line that minimizes the sum
of squared distances to all the points.

:class:`AutoDiffManifold`
=========================

.. class:: AutoDiffManifold

Create a :math:`Manifold` with Jacobians computed via automatic
differentiation.

To get an auto differentiated manifold, you must define a Functor with
templated ``Plus`` and ``Minus`` functions that compute:

.. code-block:: c++

  x_plus_delta = Plus(x, delta);
  y_minus_x    = Minus(y, x);

Where, ``x``, ``y`` and ``x_plus_y`` are vectors on the manifold in
the ambient space (so they are ``kAmbientSize`` vectors) and
``delta``, ``y_minus_x`` are vectors in the tangent space (so they are
``kTangentSize`` vectors).

The Functor should have the signature:

.. code-block:: c++

   struct Functor {
    template <typename T>
    bool Plus(const T* x, const T* delta, T* x_plus_delta) const;

    template <typename T>
    bool Minus(const T* y, const T* x, T* y_minus_x) const;
   };


Observe that  the ``Plus`` and  ``Minus`` operations are  templated on
the parameter  ``T``.  The autodiff framework  substitutes appropriate
``Jet``  objects for  ``T`` in  order to  compute the  derivative when
necessary.  This  is  the  same  mechanism that  is  used  to  compute
derivatives when using :class:`AutoDiffCostFunction`.

``Plus`` and ``Minus`` should return true if the computation is
successful and false otherwise, in which case the result will not be
used.

Given this Functor, the corresponding :class:`Manifold` can be constructed as:

.. code-block:: c++

   AutoDiffManifold<Functor, kAmbientSize, kTangentSize> manifold;

.. NOTE::

   The following is only used for illustration purposes. Ceres Solver
   ships with an optimized, production grade :math:`QuaternionManifold`
   implementation.

As a concrete example consider the case of `Quaternions
<https://en.wikipedia.org/wiki/Quaternion>`_. Quaternions form a three
dimensional manifold embedded in :math:`\mathbb{R}^4`, i.e. they have
an ambient dimension of 4 and their tangent space has dimension 3. The
following Functor defines the ``Plus`` and ``Minus`` operations on the
Quaternion manifold. It assumes that the quaternions are laid out as
``[w,x,y,z]`` in memory, i.e. the real or scalar part is the first
coordinate.

.. code-block:: c++

   struct QuaternionFunctor {
     template <typename T>
     bool Plus(const T* x, const T* delta, T* x_plus_delta) const {
       const T squared_norm_delta =
           delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2];

       T q_delta[4];
       if (squared_norm_delta > T(0.0)) {
         T norm_delta = sqrt(squared_norm_delta);
         const T sin_delta_by_delta = sin(norm_delta) / norm_delta;
         q_delta[0] = cos(norm_delta);
         q_delta[1] = sin_delta_by_delta * delta[0];
         q_delta[2] = sin_delta_by_delta * delta[1];
         q_delta[3] = sin_delta_by_delta * delta[2];
       } else {
         // We do not just use q_delta = [1,0,0,0] here because that is a
         // constant and when used for automatic differentiation will
         // lead to a zero derivative. Instead we take a first order
         // approximation and evaluate it at zero.
         q_delta[0] = T(1.0);
         q_delta[1] = delta[0];
         q_delta[2] = delta[1];
         q_delta[3] = delta[2];
       }

       QuaternionProduct(q_delta, x, x_plus_delta);
       return true;
     }

     template <typename T>
     bool Minus(const T* y, const T* x, T* y_minus_x) const {
       T minus_x[4] = {x[0], -x[1], -x[2], -x[3]};
       T ambient_y_minus_x[4];
       QuaternionProduct(y, minus_x, ambient_y_minus_x);
       T u_norm = sqrt(ambient_y_minus_x[1] * ambient_y_minus_x[1] +
		       ambient_y_minus_x[2] * ambient_y_minus_x[2] +
		       ambient_y_minus_x[3] * ambient_y_minus_x[3]);
       if (u_norm > 0.0) {
	 T theta = atan2(u_norm, ambient_y_minus_x[0]);
	 y_minus_x[0] = theta * ambient_y_minus_x[1] / u_norm;
	 y_minus_x[1] = theta * ambient_y_minus_x[2] / u_norm;
	 y_minus_x[2] = theta * ambient_y_minus_x[3] / u_norm;
       } else {
	 We do not use [0,0,0] here because even though the value part is
	 a constant, the derivative part is not.
	 y_minus_x[0] = ambient_y_minus_x[1];
	 y_minus_x[1] = ambient_y_minus_x[2];
	 y_minus_x[2] = ambient_y_minus_x[3];
       }
       return true;
     }
   };


Then given this struct, the auto differentiated Quaternion Manifold can now
be constructed as

.. code-block:: c++

   Manifold* manifold = new AutoDiffManifold<QuaternionFunctor, 4, 3>;


:class:`LocalParameterization`
==============================

.. NOTE::

   The :class:`LocalParameterization` interface and associated classes
   are deprecated. They will be removed in the version 2.2.0. Please use
   :class:`Manifold` instead.

.. class:: LocalParameterization

  In many optimization problems, especially sensor fusion problems,
  one has to model quantities that live in spaces known as `Manifolds
  <https://en.wikipedia.org/wiki/Manifold>`_ , for example the
  rotation/orientation of a sensor that is represented by a
  `Quaternion
  <https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation>`_.

  Manifolds are spaces, which locally look like Euclidean spaces. More
  precisely, at each point on the manifold there is a linear space
  that is tangent to the manifold. It has dimension equal to the
  intrinsic dimension of the manifold itself, which is less than or
  equal to the ambient space in which the manifold is embedded.

  For example, the tangent space to a point on a sphere in three
  dimensions is the two dimensional plane that is tangent to the
  sphere at that point. There are two reasons tangent spaces are
  interesting:

  1. They are Euclidean spaces, so the usual vector space operations
     apply there, which makes numerical operations easy.

  2. Movement in the tangent space translate into movements along the
     manifold.  Movements perpendicular to the tangent space do not
     translate into movements on the manifold.

  Moving along the 2 dimensional plane tangent to the sphere and
  projecting back onto the sphere will move you away from the point
  you started from but moving along the normal at the same point and
  the projecting back onto the sphere brings you back to the point.

  Besides the mathematical niceness, modeling manifold valued
  quantities correctly and paying attention to their geometry has
  practical benefits too:

  1. It naturally constrains the quantity to the manifold throughout
     the optimization, freeing the user from hacks like *quaternion
     normalization*.

  2. It reduces the dimension of the optimization problem to its
     *natural* size. For example, a quantity restricted to a line, is a
     one dimensional object regardless of the dimension of the ambient
     space in which this line lives.

     Working in the tangent space reduces not just the computational
     complexity of the optimization algorithm, but also improves its
     numerical behaviour of the algorithm.

  A basic operation one can perform on a manifold is the
  :math:`\boxplus` operation that computes the result of moving along
  delta in the tangent space at x, and then projecting back onto the
  manifold that x belongs to. Also known as a *Retraction*,
  :math:`\boxplus` is a generalization of vector addition in Euclidean
  spaces. Formally, :math:`\boxplus` is a smooth map from a
  manifold :math:`\mathcal{M}` and its tangent space
  :math:`T_\mathcal{M}` to the manifold :math:`\mathcal{M}` that
  obeys the identity

  .. math::  \boxplus(x, 0) = x,\quad \forall x.

  That is, it ensures that the tangent space is *centered* at :math:`x`
  and the zero vector is the identity element. For more see
  [Hertzberg]_ and section A.6.9 of [HartleyZisserman]_.

  Let us consider two examples:

  The Euclidean space :math:`R^n` is the simplest example of a
  manifold. It has dimension :math:`n` (and so does its tangent space)
  and :math:`\boxplus` is the familiar vector sum operation.

    .. math:: \boxplus(x, \Delta) = x + \Delta

  A more interesting case is :math:`SO(3)`, the special orthogonal
  group in three dimensions - the space of 3x3 rotation
  matrices. :math:`SO(3)` is a three dimensional manifold embedded in
  :math:`R^9` or :math:`R^{3\times 3}`.

  :math:`\boxplus` on :math:`SO(3)` is defined using the *Exponential*
  map, from the tangent space (:math:`R^3`) to the manifold. The
  Exponential map :math:`\operatorname{Exp}` is defined as:

  .. math::

     \operatorname{Exp}([p,q,r]) = \left [ \begin{matrix}
     \cos \theta + cp^2 & -sr + cpq        &  sq + cpr \\
     sr + cpq         & \cos \theta + cq^2& -sp + cqr \\
     -sq + cpr        & sp + cqr         & \cos \theta + cr^2
     \end{matrix} \right ]

  where,

  .. math::
     \theta = \sqrt{p^2 + q^2 + r^2}, s = \frac{\sin \theta}{\theta},
     c = \frac{1 - \cos \theta}{\theta^2}.

  Then,

  .. math::

     \boxplus(x, \Delta) = x \operatorname{Exp}(\Delta)

  The ``LocalParameterization`` interface allows the user to define
  and associate with parameter blocks the manifold that they belong
  to. It does so by defining the ``Plus`` (:math:`\boxplus`) operation
  and its derivative with respect to :math:`\Delta` at :math:`\Delta =
  0`.

   .. code-block:: c++

     class LocalParameterization {
      public:
       virtual ~LocalParameterization() {}
       virtual bool Plus(const double* x,
                         const double* delta,
                         double* x_plus_delta) const = 0;
       virtual bool ComputeJacobian(const double* x, double* jacobian) const = 0;
       virtual bool MultiplyByJacobian(const double* x,
                                       const int num_rows,
                                       const double* global_matrix,
                                       double* local_matrix) const;
       virtual int GlobalSize() const = 0;
       virtual int LocalSize() const = 0;
     };


.. function:: int LocalParameterization::GlobalSize()

   The dimension of the ambient space in which the parameter block
   :math:`x` lives.

.. function:: int LocalParameterization::LocalSize()

   The size of the tangent space that :math:`\Delta` lives in.

.. function:: bool LocalParameterization::Plus(const double* x, const double* delta, double* x_plus_delta) const

    :func:`LocalParameterization::Plus` implements :math:`\boxplus(x,\Delta)`.

.. function:: bool LocalParameterization::ComputeJacobian(const double* x, double* jacobian) const

   Computes the Jacobian matrix

   .. math:: J = D_2 \boxplus(x, 0)

   in row major form.

.. function:: bool MultiplyByJacobian(const double* x, const int num_rows, const double* global_matrix, double* local_matrix) const

   ``local_matrix = global_matrix * jacobian``

   ``global_matrix`` is a ``num_rows x GlobalSize``  row major matrix.
   ``local_matrix`` is a ``num_rows x LocalSize`` row major matrix.
   ``jacobian`` is the matrix returned by :func:`LocalParameterization::ComputeJacobian` at :math:`x`.

   This is only used by :class:`GradientProblem`. For most normal
   uses, it is okay to use the default implementation.

Ceres Solver ships with a number of commonly used instances of
:class:`LocalParameterization`. Another great place to find high
quality implementations of :math:`\boxplus` operations on a variety of
manifolds is the `Sophus <https://github.com/strasdat/Sophus>`_
library developed by Hauke Strasdat and his collaborators.

:class:`IdentityParameterization`
---------------------------------

.. NOTE::

   :class:`IdentityParameterization` is deprecated. It will be removed
   in version 2.2.0 of Ceres Solver. Please use
   :class:`EuclideanManifold` instead.

.. class:: IdentityParameterization

A trivial version of :math:`\boxplus` is when :math:`\Delta` is of the
same size as :math:`x` and

.. math::  \boxplus(x, \Delta) = x + \Delta

This is the same as :math:`x` living in a Euclidean manifold.

:class:`QuaternionParameterization`
-----------------------------------

.. NOTE::

   :class:`QuaternionParameterization` is deprecated. It will be
   removed in version 2.2.0 of Ceres Solver. Please use
   :class:`QuaternionManifold` instead.

.. class:: QuaternionParameterization

Another example that occurs commonly in Structure from Motion problems
is when camera rotations are parameterized using a quaternion. This is
a 3-dimensional manifold that lives in 4-dimensional space.

.. math:: \boxplus(x, \Delta) = \left[ \cos(|\Delta|), \frac{\sin\left(|\Delta|\right)}{|\Delta|} \Delta \right] * x

The multiplication :math:`*` between the two 4-vectors on the right
hand side is the standard quaternion product.

:class:`EigenQuaternionParameterization`
----------------------------------------

.. NOTE::

   :class:`EigenQuaternionParameterization` is deprecated. It will be
   removed in version 2.2.0 of Ceres Solver. Please use
   :class:`EigenQuaternionManifold` instead.

.. class:: EigenQuaternionParameterization

`Eigen <http://eigen.tuxfamily.org/index.php?title=Main_Page>`_ uses a
different internal memory layout for the elements of the quaternion
than what is commonly used. Specifically, Eigen stores the elements in
memory as :math:`(x, y, z, w)`, i.e., the *real* part (:math:`w`) is
stored as the last element. Note, when creating an Eigen quaternion
through the constructor the elements are accepted in :math:`w, x, y,
z` order.

Since Ceres operates on parameter blocks which are raw ``double``
pointers this difference is important and requires a different
parameterization. :class:`EigenQuaternionParameterization` uses the
same ``Plus`` operation as :class:`QuaternionParameterization` but
takes into account Eigen's internal memory element ordering.

:class:`SubsetParameterization`
-------------------------------

.. NOTE::

   :class:`SubsetParameterization` is deprecated. It will be removed
   in version 2.2.0 of Ceres Solver. Please use
   :class:`SubsetManifold` instead.

.. class:: SubsetParameterization

Suppose :math:`x` is a two dimensional vector, and the user wishes to
hold the first coordinate constant. Then, :math:`\Delta` is a scalar
and :math:`\boxplus` is defined as

.. math:: \boxplus(x, \Delta) = x + \left[ \begin{array}{c} 0 \\ 1 \end{array} \right] \Delta

:class:`SubsetParameterization` generalizes this construction to hold
any part of a parameter block constant by specifying the set of
coordinates that are held constant.

.. NOTE::
   It is legal to hold all coordinates of a parameter block to constant
   using a :class:`SubsetParameterization`. It is the same as calling
   :func:`Problem::SetParameterBlockConstant` on that parameter block.

:class:`HomogeneousVectorParameterization`
------------------------------------------

.. NOTE::

   :class:`HomogeneousVectorParameterization` is deprecated. It will
   be removed in version 2.2.0 of Ceres Solver. Please use
   :class:`SphereManifold` instead.

.. class:: HomogeneousVectorParameterization

In computer vision, homogeneous vectors are commonly used to represent
objects in projective geometry such as points in projective space. One
example where it is useful to use this over-parameterization is in
representing points whose triangulation is ill-conditioned. Here it is
advantageous to use homogeneous vectors, instead of an Euclidean
vector, because it can represent points at and near infinity.

:class:`HomogeneousVectorParameterization` defines a
:class:`LocalParameterization` for an :math:`n-1` dimensional
manifold that embedded in :math:`n` dimensional space where the
scale of the vector does not matter, i.e., elements of the
projective space :math:`\mathbb{P}^{n-1}`. It assumes that the last
coordinate of the :math:`n`-vector is the *scalar* component of the
homogenous vector, i.e., *finite* points in this representation are
those for which the *scalar* component is non-zero.

Further, ``HomogeneousVectorParameterization::Plus`` preserves the
scale of :math:`x`.

:class:`LineParameterization`
-----------------------------

.. NOTE::

   :class:`LineParameterization` is deprecated. It will be removed in
   version 2.2.0 of Ceres Solver. Please use :class:`LineManifold`
   instead.

.. class:: LineParameterization

This class provides a parameterization for lines, where the line is
defined using an origin point and a direction vector. So the
parameter vector size needs to be two times the ambient space
dimension, where the first half is interpreted as the origin point
and the second half as the direction. This local parameterization is
a special case of the `Affine Grassmannian manifold
<https://en.wikipedia.org/wiki/Affine_Grassmannian_(manifold))>`_
for the case :math:`\operatorname{Graff}_1(R^n)`.

Note that this is a parameterization for a line, rather than a point
constrained to lie on a line. It is useful when one wants to optimize
over the space of lines. For example, :math:`n` distinct points in 3D
(measurements) we want to find the line that minimizes the sum of
squared distances to all the points.

:class:`ProductParameterization`
--------------------------------

.. NOTE::

   :class:`ProductParameterization` is deprecated. It will be removed
   in version 2.2.0 of Ceres Solver. Please use
   :class:`ProductManifold` instead.

.. class:: ProductParameterization

Consider an optimization problem over the space of rigid
transformations :math:`SE(3)`, which is the Cartesian product of
:math:`SO(3)` and :math:`\mathbb{R}^3`. Suppose you are using
Quaternions to represent the rotation, Ceres ships with a local
parameterization for that and :math:`\mathbb{R}^3` requires no, or
:class:`IdentityParameterization` parameterization. So how do we
construct a local parameterization for a parameter block a rigid
transformation?

In cases, where a parameter block is the Cartesian product of a number
of manifolds and you have the local parameterization of the individual
manifolds available, :class:`ProductParameterization` can be used to
construct a local parameterization of the cartesian product. For the
case of the rigid transformation, where say you have a parameter block
of size 7, where the first four entries represent the rotation as a
quaternion, a local parameterization can be constructed as

.. code-block:: c++

   ProductParameterization se3_param(new QuaternionParameterization(),
                                     new IdentityParameterization(3));


:class:`AutoDiffLocalParameterization`
======================================

.. NOTE::

   :class:`AutoDiffParameterization` is deprecated. It will be removed
   in version 2.2.0 of Ceres Solver. Please use
   :class:`AutoDiffManifold` instead.

.. class:: AutoDiffLocalParameterization

  :class:`AutoDiffLocalParameterization` does for
  :class:`LocalParameterization` what :class:`AutoDiffCostFunction`
  does for :class:`CostFunction`. It allows the user to define a
  templated functor that implements the
  :func:`LocalParameterization::Plus` operation and it uses automatic
  differentiation to implement the computation of the Jacobian.

  To get an auto differentiated local parameterization, you must
  define a class with a templated operator() (a functor) that computes

     .. math:: x' = \boxplus(x, \Delta x),

  For example, Quaternions have a three dimensional local
  parameterization. Its plus operation can be implemented as (taken
  from `internal/ceres/autodiff_local_parameterization_test.cc
  <https://ceres-solver.googlesource.com/ceres-solver/+/master/internal/ceres/autodiff_local_parameterization_test.cc>`_
  )

    .. code-block:: c++

      struct QuaternionPlus {
        template<typename T>
        bool operator()(const T* x, const T* delta, T* x_plus_delta) const {
          const T squared_norm_delta =
              delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2];

          T q_delta[4];
          if (squared_norm_delta > 0.0) {
            T norm_delta = sqrt(squared_norm_delta);
            const T sin_delta_by_delta = sin(norm_delta) / norm_delta;
            q_delta[0] = cos(norm_delta);
            q_delta[1] = sin_delta_by_delta * delta[0];
            q_delta[2] = sin_delta_by_delta * delta[1];
            q_delta[3] = sin_delta_by_delta * delta[2];
          } else {
            // We do not just use q_delta = [1,0,0,0] here because that is a
            // constant and when used for automatic differentiation will
            // lead to a zero derivative. Instead we take a first order
            // approximation and evaluate it at zero.
            q_delta[0] = T(1.0);
            q_delta[1] = delta[0];
            q_delta[2] = delta[1];
            q_delta[3] = delta[2];
          }

          Quaternionproduct(q_delta, x, x_plus_delta);
          return true;
        }
      };

  Given this struct, the auto differentiated local
  parameterization can now be constructed as

  .. code-block:: c++

     LocalParameterization* local_parameterization =
         new AutoDiffLocalParameterization<QuaternionPlus, 4, 3>;
                                                           |  |
                                Global Size ---------------+  |
                                Local Size -------------------+



:class:`Problem`
================

.. class:: Problem

   .. NOTE:: We are currently in the process of transitioning from
      :class:`LocalParameterization` to :class:`Manifolds` in the
      Ceres Solver API. During this period, :class:`Problem` will
      support using both :class:`Manifold` and
      :class:`LocalParameterization` objects interchangably. In
      particular, adding a :class:`LocalParameterization` to a
      parameter block is the same as adding a :class:`Manifold` to
      that parameter block. For methods in the API affected by this
      change, see their documentation below.

   :class:`Problem` holds the robustified bounds constrained
   non-linear least squares problem :eq:`ceresproblem_modeling`. To
   create a least squares problem, use the
   :func:`Problem::AddResidalBlock` and
   :func:`Problem::AddParameterBlock` methods.

   For example a problem containing 3 parameter blocks of sizes 3, 4
   and 5 respectively and two residual blocks of size 2 and 6:

   .. code-block:: c++

     double x1[] = { 1.0, 2.0, 3.0 };
     double x2[] = { 1.0, 2.0, 3.0, 5.0 };
     double x3[] = { 1.0, 2.0, 3.0, 6.0, 7.0 };

     Problem problem;
     problem.AddResidualBlock(new MyUnaryCostFunction(...), x1);
     problem.AddResidualBlock(new MyBinaryCostFunction(...), x2, x3);

   :func:`Problem::AddResidualBlock` as the name implies, adds a
   residual block to the problem. It adds a :class:`CostFunction`, an
   optional :class:`LossFunction` and connects the
   :class:`CostFunction` to a set of parameter block.

   The cost function carries with it information about the sizes of
   the parameter blocks it expects. The function checks that these
   match the sizes of the parameter blocks listed in
   ``parameter_blocks``. The program aborts if a mismatch is
   detected. ``loss_function`` can be ``nullptr``, in which case the cost
   of the term is just the squared norm of the residuals.

   The user has the option of explicitly adding the parameter blocks
   using :func:`Problem::AddParameterBlock`. This causes additional
   correctness checking; however, :func:`Problem::AddResidualBlock`
   implicitly adds the parameter blocks if they are not present, so
   calling :func:`Problem::AddParameterBlock` explicitly is not
   required.

   :func:`Problem::AddParameterBlock` explicitly adds a parameter
   block to the :class:`Problem`. Optionally it allows the user to
   associate a :class:`Manifold` object with the parameter block
   too. Repeated calls with the same arguments are ignored. Repeated
   calls with the same double pointer but a different size results in
   undefined behavior.

   You can set any parameter block to be constant using
   :func:`Problem::SetParameterBlockConstant` and undo this using
   :func:`SetParameterBlockVariable`.

   In fact you can set any number of parameter blocks to be constant,
   and Ceres is smart enough to figure out what part of the problem
   you have constructed depends on the parameter blocks that are free
   to change and only spends time solving it. So for example if you
   constructed a problem with a million parameter blocks and 2 million
   residual blocks, but then set all but one parameter blocks to be
   constant and say only 10 residual blocks depend on this one
   non-constant parameter block. Then the computational effort Ceres
   spends in solving this problem will be the same if you had defined
   a problem with one parameter block and 10 residual blocks.

   **Ownership**

   :class:`Problem` by default takes ownership of the
   ``cost_function``, ``loss_function``, ``local_parameterization``,
   and ``manifold`` pointers. These objects remain live for the life
   of the :class:`Problem`. If the user wishes to keep control over
   the destruction of these objects, then they can do this by setting
   the corresponding enums in the :class:`Problem::Options` struct.

   Note that even though the Problem takes ownership of objects,
   ``cost_function`` and ``loss_function``, it does not preclude the
   user from re-using them in another residual block. Similarly the
   same ``local_parameterization`` or ``manifold`` object can be used
   with multiple parameter blocks. The destructor takes care to call
   delete on each owned object exactly once.

.. class:: Problem::Options

   Options struct that is used to control :class:`Problem`.

.. member:: Ownership Problem::Options::cost_function_ownership

   Default: ``TAKE_OWNERSHIP``

   This option controls whether the Problem object owns the cost
   functions.

   If set to TAKE_OWNERSHIP, then the problem object will delete the
   cost functions on destruction. The destructor is careful to delete
   the pointers only once, since sharing cost functions is allowed.

.. member:: Ownership Problem::Options::loss_function_ownership

   Default: ``TAKE_OWNERSHIP``

   This option controls whether the Problem object owns the loss
   functions.

   If set to TAKE_OWNERSHIP, then the problem object will delete the
   loss functions on destruction. The destructor is careful to delete
   the pointers only once, since sharing loss functions is allowed.

.. member:: Ownership Problem::Options::local_parameterization_ownership

   .. NOTE::

      `Problem::Options::local_parameterization_ownership` is
      deprecated. It will be removed in Ceres Solver version
      2.2.0. Please move to using Manifolds and use
      `Problem::Options::manifold_ownership` instead.

   Default: ``TAKE_OWNERSHIP``

   This option controls whether the Problem object owns the local
   parameterizations.

   If set to TAKE_OWNERSHIP, then the problem object will delete the
   local parameterizations on destruction. The destructor is careful
   to delete the pointers only once, since sharing local
   parameterizations is allowed.

.. member:: Ownership Problem::Options::manifold_ownership

   Default: ``TAKE_OWNERSHIP``

   This option controls whether the Problem object owns the manifolds.

   If set to TAKE_OWNERSHIP, then the problem object will delete the
   manifolds on destruction. The destructor is careful to delete the
   pointers only once, since sharing manifolds is allowed.

.. member:: bool Problem::Options::enable_fast_removal

    Default: ``false``

    If true, trades memory for faster
    :func:`Problem::RemoveResidualBlock` and
    :func:`Problem::RemoveParameterBlock` operations.

    By default, :func:`Problem::RemoveParameterBlock` and
    :func:`Problem::RemoveResidualBlock` take time proportional to
    the size of the entire problem.  If you only ever remove
    parameters or residuals from the problem occasionally, this might
    be acceptable.  However, if you have memory to spare, enable this
    option to make :func:`Problem::RemoveParameterBlock` take time
    proportional to the number of residual blocks that depend on it,
    and :func:`Problem::RemoveResidualBlock` take (on average)
    constant time.

    The increase in memory usage is twofold: an additional hash set
    per parameter block containing all the residuals that depend on
    the parameter block; and a hash set in the problem containing all
    residuals.

.. member:: bool Problem::Options::disable_all_safety_checks

    Default: `false`

    By default, Ceres performs a variety of safety checks when
    constructing the problem. There is a small but measurable
    performance penalty to these checks, typically around 5% of
    construction time. If you are sure your problem construction is
    correct, and 5% of the problem construction time is truly an
    overhead you want to avoid, then you can set
    disable_all_safety_checks to true.

    **WARNING** Do not set this to true, unless you are absolutely
    sure of what you are doing.

.. member:: Context* Problem::Options::context

    Default: `nullptr`

    A Ceres global context to use for solving this problem. This may
    help to reduce computation time as Ceres can reuse expensive
    objects to create.  The context object can be `nullptr`, in which
    case Ceres may create one.

    Ceres does NOT take ownership of the pointer.

.. member:: EvaluationCallback* Problem::Options::evaluation_callback

    Default: `nullptr`

    Using this callback interface, Ceres will notify you when it is
    about to evaluate the residuals or Jacobians.

    If an ``evaluation_callback`` is present, Ceres will update the
    user's parameter blocks to the values that will be used when
    calling :func:`CostFunction::Evaluate` before calling
    :func:`EvaluationCallback::PrepareForEvaluation`. One can then use
    this callback to share (or cache) computation between cost
    functions by doing the shared computation in
    :func:`EvaluationCallback::PrepareForEvaluation` before Ceres
    calls :func:`CostFunction::Evaluate`.

    Problem does NOT take ownership of the callback.

    .. NOTE::

       Evaluation callbacks are incompatible with inner iterations. So
       calling Solve with
       :member:`Solver::Options::use_inner_iterations` set to `true`
       on a :class:`Problem` with a non-null evaluation callback is an
       error.

.. function:: ResidualBlockId Problem::AddResidualBlock(CostFunction* cost_function, LossFunction* loss_function, const vector<double*> parameter_blocks)

.. function:: template <typename Ts...> ResidualBlockId Problem::AddResidualBlock(CostFunction* cost_function, LossFunction* loss_function, double* x0, Ts... xs)

   Add a residual block to the overall cost function. The cost
   function carries with it information about the sizes of the
   parameter blocks it expects. The function checks that these match
   the sizes of the parameter blocks listed in parameter_blocks. The
   program aborts if a mismatch is detected. loss_function can be
   `nullptr`, in which case the cost of the term is just the squared
   norm of the residuals.

   The parameter blocks may be passed together as a
   ``vector<double*>``, or ``double*`` pointers.

   The user has the option of explicitly adding the parameter blocks
   using AddParameterBlock. This causes additional correctness
   checking; however, AddResidualBlock implicitly adds the parameter
   blocks if they are not present, so calling AddParameterBlock
   explicitly is not required.

   The Problem object by default takes ownership of the
   cost_function and loss_function pointers. These objects remain
   live for the life of the Problem object. If the user wishes to
   keep control over the destruction of these objects, then they can
   do this by setting the corresponding enums in the Options struct.

   Note: Even though the Problem takes ownership of cost_function
   and loss_function, it does not preclude the user from re-using
   them in another residual block. The destructor takes care to call
   delete on each cost_function or loss_function pointer only once,
   regardless of how many residual blocks refer to them.

   Example usage:

   .. code-block:: c++

      double x1[] = {1.0, 2.0, 3.0};
      double x2[] = {1.0, 2.0, 5.0, 6.0};
      double x3[] = {3.0, 6.0, 2.0, 5.0, 1.0};
      vector<double*> v1;
      v1.push_back(x1);
      vector<double*> v2;
      v2.push_back(x2);
      v2.push_back(x1);

      Problem problem;

      problem.AddResidualBlock(new MyUnaryCostFunction(...), nullptr, x1);
      problem.AddResidualBlock(new MyBinaryCostFunction(...), nullptr, x2, x1);
      problem.AddResidualBlock(new MyUnaryCostFunction(...), nullptr, v1);
      problem.AddResidualBlock(new MyBinaryCostFunction(...), nullptr, v2);

.. function:: void Problem::AddParameterBlock(double* values, int size, LocalParameterization* local_parameterization)

   .. NOTE::

       This method is deprecated and will be removed in Ceres Solver
       version 2.2.0. Please move to using the :class:`Manifold` based version
       of `AddParameterBlock`.

       During the transition from :class:`LocalParameterization` to
       :class:`Manifold`, internally the
       :class:`LocalParameterization` is treated as a
       :class:`Manifold` by wrapping it using a `ManifoldAdapter`
       object. So :func:`Problem::HasManifold` will return true,
       :func:`Problem::GetManifold` will return the wrapped object and
       :func:`Problem::ParameterBlockTangentSize` will return the value of
       :func:`LocalParameterization::LocalSize`.

   Add a parameter block with appropriate size and parameterization to the
   problem. It is okay for `local_parameterization` to be `nullptr`.

   Repeated calls with the same arguments are ignored. Repeated calls
   with the same double pointer but a different size results in a crash
   (unless `Solver::Options::diable_all_safety_checks` is set to true).

   Repeated calls with the same double pointer and size but different
   :class:`LocalParameterization` is equivalent to calling
   `SetParameterization(local_parameterization)`, i.e., any previously
   associated :class:`LocalParameterization` or :class:`Manifold`
   object will be replaced with the `local_parameterization`.


.. function:: void Problem::AddParameterBlock(double* values, int size, Manifold* manifold)

   .. NOTE::

      During the transition from :class:`LocalParameterization` to
      :class:`Manifold`, calling `AddParameterBlock` with a
      :class:`Manifold` when a :class:`LocalParameterization` is
      already associated with the parameter block is okay. It is
      equivalent to calling `SetManifold(manifold)`, i.e., any
      previously associated :class:`LocalParameterization` or
      :class:`Manifold` object will be replaced with the manifold.

   Add a parameter block with appropriate size and Manifold to the
   problem. It is okay for `manifold` to be `nullptr`.

   Repeated calls with the same arguments are ignored. Repeated calls
   with the same double pointer but a different size results in a crash
   (unless `Solver::Options::diable_all_safety_checks` is set to true).

   Repeated calls with the same double pointer and size but different
   :class:`Manifold` is equivalent to calling `SetManifold(manifold)`,
   i.e., any previously associated :class:`LocalParameterization` or
   :class:`Manifold` object will be replaced with the `manifold`.

.. function:: void Problem::AddParameterBlock(double* values, int size)

   Add a parameter block with appropriate size and parameterization to
   the problem. Repeated calls with the same arguments are
   ignored. Repeated calls with the same double pointer but a
   different size results in undefined behavior.

.. function:: void Problem::RemoveResidualBlock(ResidualBlockId residual_block)

   Remove a residual block from the problem.

   Since residual blocks are allowed to share cost function and loss
   function objects, Ceres Solver uses a reference counting
   mechanism. So when a residual block is deleted, the reference count
   for the corresponding cost function and loss function objects are
   decreased and when this count reaches zero, they are deleted.

   If Problem::Options::enable_fast_removal is true, then the removal
   is fast (almost constant time). Otherwise it is linear, requiring a
   scan of the entire problem.

   Removing a residual block has no effect on the parameter blocks
   that the problem depends on.

   **WARNING:** Removing a residual or parameter block will destroy
   the implicit ordering, rendering the jacobian or residuals returned
   from the solver uninterpretable. If you depend on the evaluated
   jacobian, do not use remove! This may change in a future release.
   Hold the indicated parameter block constant during optimization.

.. function:: void Problem::RemoveParameterBlock(const double* values)

   Remove a parameter block from the problem. Any residual blocks that
   depend on the parameter are also removed, as described above in
   RemoveResidualBlock().

   The parameterization of the parameter block, if it exists, will
   persist until the deletion of the problem.

   If Problem::Options::enable_fast_removal is true, then the removal
   is fast (almost constant time). Otherwise, removing a parameter
   block will scan the entire Problem.

   **WARNING:** Removing a residual or parameter block will destroy
   the implicit ordering, rendering the jacobian or residuals returned
   from the solver uninterpretable. If you depend on the evaluated
   jacobian, do not use remove! This may change in a future release.

.. function:: void Problem::SetParameterBlockConstant(const double* values)

   Hold the indicated parameter block constant during optimization.

.. function:: void Problem::SetParameterBlockVariable(double* values)

   Allow the indicated parameter to vary during optimization.

.. function:: bool Problem::IsParameterBlockConstant(const double* values) const

   Returns ``true`` if a parameter block is set constant, and false
   otherwise. A parameter block may be set constant in two ways:
   either by calling ``SetParameterBlockConstant`` or by associating a
   :class:`LocalParameterization` or :class:`Manifold` with a zero
   dimensional tangent space with it.

.. function:: void Problem::SetParameterization(double* values, LocalParameterization* local_parameterization)

   .. NOTE::

      This method is deprecated and will be removed in Ceres Solver
      version 2.2.0. Please move to using the SetManifold instead.

      During the transition from :class:`LocalParameterization` to
      :class:`Manifold`, calling `AddParameterBlock` with a
      :class:`Manifold` when a :class:`LocalParameterization` is
      already associated with the parameter block is okay. It is
      equivalent to calling `SetManifold(manifold)`, i.e., any
      previously associated :class:`LocalParameterization` or
      :class:`Manifold` object will be replaced with the manifold.

   Set the :class:`LocalParameterization` for the parameter
   block. Calling :func:`Problem::SetParameterization` with
   ``nullptr`` will clear any previously set
   :class:`LocalParameterization` or :class:`Manifold` for the
   parameter block.

   Repeated calls will cause any previously associated
   :class:`LocalParameterization` or :class:`Manifold` object to be
   replaced with the ``local_parameterization``.

   The ``local_parameterization`` is owned by the :class:`Problem` by
   default (See :class:`Problem::Options` to override this behaviour).

   It is acceptable to set the same :class:`LocalParameterization` for
   multiple parameter blocks; the Problem destructor is careful to
   delete :class:`LocalParamaterizations` only once.

.. function:: LocalParameterization* Problem::GetParameterization(const double* values) const

   Get the local parameterization object associated with this
   parameter block. If there is no parameterization object associated
   then `nullptr` is returned

   .. NOTE::

       This method is deprecated and will be removed in Ceres Solver
       version 2.2.0. Please move to using the
       :func:`Problem::GetParameterization` instead.

       Note also that if a :class:`LocalParameterization` is
       associated with a parameter block, :func:`Problem::HasManifold`
       will return true and :func:`Problem::GetManifold` will return
       the :class:`LocalParameterization` wrapped in a
       ``ManifoldAdapter``.

       The converse is NOT true, i.e., if a :class:`Manifold` is
       associated with a parameter block,
       :func:`Problem::HasParameterization` will return ``false`` and
       :func:`Problem::GetParameterization` will return a
       ``nullptr``.

.. function:: bool HasParameterization(const double* values) const;

   Returns ``true`` if a :class:`LocalParameterization` is associated
   with this parameter block, ``false`` otherwise.

   .. NOTE::

      This method is deprecated and will be removed in the next public
      release of Ceres Solver. Use :func:`Problem::HasManifold` instead.

      Note also that if a ::class::`Manifold` is associated with the
      parameter block, this method will return ``false``.

.. function:: void SetManifold(double* values, Manifold* manifold);

   Set the :class:`Manifold` for the parameter block. Calling
   :func:`Problem::SetManifold` with ``nullptr`` will clear any
   previously set :class:`LocalParameterization` or :class:`Manifold`
   for the parameter block.

   Repeated calls will result in any previously associated
   :class:`LocalParameterization` or :class:`Manifold` object to be
   replaced with ``manifold``.

   ``manifold`` is owned by :class:`Problem` by default (See
   :class:`Problem::Options` to override this behaviour).

   It is acceptable to set the same :class:`Manifold` for multiple
   parameter blocks.

.. function:: const Manifold* GetManifold(const double* values) const;

   Get the :class:`Manifold` object associated with this parameter block.

   If there is no :class:`Manifold` Or :class:`LocalParameterization`
   object associated then ``nullptr`` is returned.

   .. NOTE::

      During the transition from :class:`LocalParameterization` to
      :class:`Manifold`, internally the :class:`LocalParameterization` is
      treated as a :class:`Manifold` by wrapping it using a ``ManifoldAdapter``
      object. So calling :func:`Problem::GetManifold` on a parameter block with a
      :class:`LocalParameterization` associated with it will return the
      :class:`LocalParameterization` wrapped in a ManifoldAdapter.

.. function:: bool HasManifold(const double* values) const;

   Returns ``true`` if a :class:`Manifold` or a
   :class:`LocalParameterization` is associated with this parameter
   block, ``false`` otherwise.

.. function:: void Problem::SetParameterLowerBound(double* values, int index, double lower_bound)

   Set the lower bound for the parameter at position `index` in the
   parameter block corresponding to `values`. By default the lower
   bound is ``-std::numeric_limits<double>::max()``, which is treated
   by the solver as the same as :math:`-\infty`.

.. function:: void Problem::SetParameterUpperBound(double* values, int index, double upper_bound)

   Set the upper bound for the parameter at position `index` in the
   parameter block corresponding to `values`. By default the value is
   ``std::numeric_limits<double>::max()``, which is treated by the
   solver as the same as :math:`\infty`.

.. function:: double Problem::GetParameterLowerBound(const double* values, int index)

   Get the lower bound for the parameter with position `index`. If the
   parameter is not bounded by the user, then its lower bound is
   ``-std::numeric_limits<double>::max()``.

.. function:: double Problem::GetParameterUpperBound(const double* values, int index)

   Get the upper bound for the parameter with position `index`. If the
   parameter is not bounded by the user, then its upper bound is
   ``std::numeric_limits<double>::max()``.

.. function:: int Problem::NumParameterBlocks() const

   Number of parameter blocks in the problem. Always equals
   parameter_blocks().size() and parameter_block_sizes().size().

.. function:: int Problem::NumParameters() const

   The size of the parameter vector obtained by summing over the sizes
   of all the parameter blocks.

.. function:: int Problem::NumResidualBlocks() const

   Number of residual blocks in the problem. Always equals
   residual_blocks().size().

.. function:: int Problem::NumResiduals() const

   The size of the residual vector obtained by summing over the sizes
   of all of the residual blocks.

.. function:: int Problem::ParameterBlockSize(const double* values) const

   The size of the parameter block.

.. function:: int Problem::ParameterBlockLocalSize(const double* values) const

   The dimension of the tangent space of the
   :class:`LocalParameterization` or :class:`Manifold` for the
   parameter block. If there is no :class:`LocalParameterization` or
   :class:`Manifold` associated with this parameter block, then
   ``ParameterBlockLocalSize = ParameterBlockSize``.

   .. NOTE::

      This method is deprecated and will be removed in Ceres Solver
      Version 2.2.0. Use :func:`Problem::ParameterBlockTangentSize`
      instead.

.. function:: int Problem::ParameterBlockTangentSize(const double* values) const

   The dimension of the tangent space of the
   :class:`LocalParameterization` or :class:`Manifold` for the
   parameter block. If there is no :class:`LocalParameterization` or
   :class:`Manifold` associated with this parameter block, then
   ``ParameterBlockLocalSize = ParameterBlockSize``.

.. function:: bool Problem::HasParameterBlock(const double* values) const

   Is the given parameter block present in the problem or not?

.. function:: void Problem::GetParameterBlocks(vector<double*>* parameter_blocks) const

   Fills the passed ``parameter_blocks`` vector with pointers to the
   parameter blocks currently in the problem. After this call,
   ``parameter_block.size() == NumParameterBlocks``.

.. function:: void Problem::GetResidualBlocks(vector<ResidualBlockId>* residual_blocks) const

   Fills the passed `residual_blocks` vector with pointers to the
   residual blocks currently in the problem. After this call,
   `residual_blocks.size() == NumResidualBlocks`.

.. function:: void Problem::GetParameterBlocksForResidualBlock(const ResidualBlockId residual_block, vector<double*>* parameter_blocks) const

   Get all the parameter blocks that depend on the given residual
   block.

.. function:: void Problem::GetResidualBlocksForParameterBlock(const double* values, vector<ResidualBlockId>* residual_blocks) const

   Get all the residual blocks that depend on the given parameter
   block.

   If `Problem::Options::enable_fast_removal` is
   `true`, then getting the residual blocks is fast and depends only
   on the number of residual blocks. Otherwise, getting the residual
   blocks for a parameter block will scan the entire problem.

.. function:: const CostFunction* Problem::GetCostFunctionForResidualBlock(const ResidualBlockId residual_block) const

   Get the :class:`CostFunction` for the given residual block.

.. function:: const LossFunction* Problem::GetLossFunctionForResidualBlock(const ResidualBlockId residual_block) const

   Get the :class:`LossFunction` for the given residual block.

.. function::  bool EvaluateResidualBlock(ResidualBlockId residual_block_id, bool apply_loss_function, double* cost,double* residuals, double** jacobians) const

   Evaluates the residual block, storing the scalar cost in ``cost``, the
   residual components in ``residuals``, and the jacobians between the
   parameters and residuals in ``jacobians[i]``, in row-major order.

   If ``residuals`` is ``nullptr``, the residuals are not computed.

   If ``jacobians`` is ``nullptr``, no Jacobians are computed. If
   ``jacobians[i]`` is ``nullptr``, then the Jacobian for that
   parameter block is not computed.

   It is not okay to request the Jacobian w.r.t a parameter block
   that is constant.

   The return value indicates the success or failure. Even if the
   function returns false, the caller should expect the output
   memory locations to have been modified.

   The returned cost and jacobians have had robustification and
   :class:`LocalParameterization`/:class:`Manifold` applied already;
   for example, the jacobian for a 4-dimensional quaternion parameter
   using the :class:`QuaternionManifold` is ``num_residuals x 3``
   instead of ``num_residuals x 4``.

   ``apply_loss_function`` as the name implies allows the user to
   switch the application of the loss function on and off.

   .. NOTE:: If an :class:`EvaluationCallback` is associated with the
      problem, then its
      :func:`EvaluationCallback::PrepareForEvaluation` method will be
      called every time this method is called with `new_point =
      true`. This conservatively assumes that the user may have
      changed the parameter values since the previous call to evaluate
      / solve.  For improved efficiency, and only if you know that the
      parameter values have not changed between calls, see
      :func:`Problem::EvaluateResidualBlockAssumingParametersUnchanged`.


.. function::  bool EvaluateResidualBlockAssumingParametersUnchanged(ResidualBlockId residual_block_id, bool apply_loss_function, double* cost,double* residuals, double** jacobians) const

    Same as :func:`Problem::EvaluateResidualBlock` except that if an
    :class:`EvaluationCallback` is associated with the problem, then
    its :func:`EvaluationCallback::PrepareForEvaluation` method will
    be called every time this method is called with new_point = false.

    This means, if an :class:`EvaluationCallback` is associated with
    the problem then it is the user's responsibility to call
    :func:`EvaluationCallback::PrepareForEvaluation` before calling
    this method if necessary, i.e. iff the parameter values have been
    changed since the last call to evaluate / solve.'

    This is because, as the name implies, we assume that the parameter
    blocks did not change since the last time
    :func:`EvaluationCallback::PrepareForEvaluation` was called (via
    :func:`Solve`, :func:`Problem::Evaluate` or
    :func:`Problem::EvaluateResidualBlock`).


.. function:: bool Problem::Evaluate(const Problem::EvaluateOptions& options, double* cost, vector<double>* residuals, vector<double>* gradient, CRSMatrix* jacobian)

   Evaluate a :class:`Problem`. Any of the output pointers can be
   `nullptr`. Which residual blocks and parameter blocks are used is
   controlled by the :class:`Problem::EvaluateOptions` struct below.

   .. NOTE::

      The evaluation will use the values stored in the memory
      locations pointed to by the parameter block pointers used at the
      time of the construction of the problem, for example in the
      following code:

      .. code-block:: c++

        Problem problem;
        double x = 1;
        problem.Add(new MyCostFunction, nullptr, &x);

        double cost = 0.0;
        problem.Evaluate(Problem::EvaluateOptions(), &cost, nullptr, nullptr, nullptr);

      The cost is evaluated at `x = 1`. If you wish to evaluate the
      problem at `x = 2`, then

      .. code-block:: c++

         x = 2;
         problem.Evaluate(Problem::EvaluateOptions(), &cost, nullptr, nullptr, nullptr);

      is the way to do so.

   .. NOTE::

      If no :class:`LocalParameterization`/:class:`Manifold` are used,
      then the size of the gradient vector is the sum of the sizes of
      all the parameter blocks. If a parameter block has a local
      parameterization, then it contributes "LocalSize" entries to the
      gradient vector.

   .. NOTE::

      This function cannot be called while the problem is being
      solved, for example it cannot be called from an
      :class:`IterationCallback` at the end of an iteration during a
      solve.

   .. NOTE::

      If an EvaluationCallback is associated with the problem, then
      its PrepareForEvaluation method will be called everytime this
      method is called with ``new_point = true``.

.. class:: Problem::EvaluateOptions

   Options struct that is used to control :func:`Problem::Evaluate`.

.. member:: vector<double*> Problem::EvaluateOptions::parameter_blocks

   The set of parameter blocks for which evaluation should be
   performed. This vector determines the order in which parameter
   blocks occur in the gradient vector and in the columns of the
   jacobian matrix. If parameter_blocks is empty, then it is assumed
   to be equal to a vector containing ALL the parameter
   blocks. Generally speaking the ordering of the parameter blocks in
   this case depends on the order in which they were added to the
   problem and whether or not the user removed any parameter blocks.

   **NOTE** This vector should contain the same pointers as the ones
   used to add parameter blocks to the Problem. These parameter block
   should NOT point to new memory locations. Bad things will happen if
   you do.

.. member:: vector<ResidualBlockId> Problem::EvaluateOptions::residual_blocks

   The set of residual blocks for which evaluation should be
   performed. This vector determines the order in which the residuals
   occur, and how the rows of the jacobian are ordered. If
   residual_blocks is empty, then it is assumed to be equal to the
   vector containing all the residual blocks.

.. member:: bool Problem::EvaluateOptions::apply_loss_function

   Even though the residual blocks in the problem may contain loss
   functions, setting apply_loss_function to false will turn off the
   application of the loss function to the output of the cost
   function. This is of use for example if the user wishes to analyse
   the solution quality by studying the distribution of residuals
   before and after the solve.

.. member:: int Problem::EvaluateOptions::num_threads

   Number of threads to use.


:class:`EvaluationCallback`
===========================

.. class:: EvaluationCallback

   Interface for receiving callbacks before Ceres evaluates residuals or
   Jacobians:

   .. code-block:: c++

      class EvaluationCallback {
       public:
        virtual ~EvaluationCallback() {}
        virtual void PrepareForEvaluation()(bool evaluate_jacobians
                                            bool new_evaluation_point) = 0;
      };

.. function:: void EvaluationCallback::PrepareForEvaluation(bool evaluate_jacobians, bool new_evaluation_point)

   Ceres will call :func:`EvaluationCallback::PrepareForEvaluation`
   every time, and once before it computes the residuals and/or the
   Jacobians.

   User parameters (the double* values provided by the user) are fixed
   until the next call to
   :func:`EvaluationCallback::PrepareForEvaluation`. If
   ``new_evaluation_point == true``, then this is a new point that is
   different from the last evaluated point. Otherwise, it is the same
   point that was evaluated previously (either Jacobian or residual)
   and the user can use cached results from previous evaluations. If
   ``evaluate_jacobians`` is true, then Ceres will request Jacobians
   in the upcoming cost evaluation.

   Using this callback interface, Ceres can notify you when it is
   about to evaluate the residuals or Jacobians. With the callback,
   you can share computation between residual blocks by doing the
   shared computation in
   :func:`EvaluationCallback::PrepareForEvaluation` before Ceres calls
   :func:`CostFunction::Evaluate` on all the residuals. It also
   enables caching results between a pure residual evaluation and a
   residual & Jacobian evaluation, via the ``new_evaluation_point``
   argument.

   One use case for this callback is if the cost function compute is
   moved to the GPU. In that case, the prepare call does the actual
   cost function evaluation, and subsequent calls from Ceres to the
   actual cost functions merely copy the results from the GPU onto the
   corresponding blocks for Ceres to plug into the solver.

   **Note**: Ceres provides no mechanism to share data other than the
   notification from the callback. Users must provide access to
   pre-computed shared data to their cost functions behind the scenes;
   this all happens without Ceres knowing. One approach is to put a
   pointer to the shared data in each cost function (recommended) or
   to use a global shared variable (discouraged; bug-prone).  As far
   as Ceres is concerned, it is evaluating cost functions like any
   other; it just so happens that behind the scenes the cost functions
   reuse pre-computed data to execute faster.

   See ``evaluation_callback_test.cc`` for code that explicitly
   verifies the preconditions between
   :func:`EvaluationCallback::PrepareForEvaluation` and
   :func:`CostFunction::Evaluate`.


``rotation.h``
==============

Many applications of Ceres Solver involve optimization problems where
some of the variables correspond to rotations. To ease the pain of
work with the various representations of rotations (angle-axis,
quaternion and matrix) we provide a handy set of templated
functions. These functions are templated so that the user can use them
within Ceres Solver's automatic differentiation framework.

.. function:: template <typename T> void AngleAxisToQuaternion(T const* angle_axis, T* quaternion)

   Convert a value in combined axis-angle representation to a
   quaternion.

   The value ``angle_axis`` is a triple whose norm is an angle in radians,
   and whose direction is aligned with the axis of rotation, and
   ``quaternion`` is a 4-tuple that will contain the resulting quaternion.

.. function::  template <typename T> void QuaternionToAngleAxis(T const* quaternion, T* angle_axis)

   Convert a quaternion to the equivalent combined axis-angle
   representation.

   The value ``quaternion`` must be a unit quaternion - it is not
   normalized first, and ``angle_axis`` will be filled with a value
   whose norm is the angle of rotation in radians, and whose direction
   is the axis of rotation.

.. function:: template <typename T, int row_stride, int col_stride> void RotationMatrixToAngleAxis(const MatrixAdapter<const T, row_stride, col_stride>& R, T * angle_axis)
.. function:: template <typename T, int row_stride, int col_stride> void AngleAxisToRotationMatrix(T const * angle_axis, const MatrixAdapter<T, row_stride, col_stride>& R)
.. function:: template <typename T> void RotationMatrixToAngleAxis(T const * R, T * angle_axis)
.. function:: template <typename T> void AngleAxisToRotationMatrix(T const * angle_axis, T * R)

   Conversions between 3x3 rotation matrix with given column and row strides and
   axis-angle rotation representations. The functions that take a pointer to T instead
   of a MatrixAdapter assume a column major representation with unit row stride and a column stride of 3.

.. function:: template <typename T, int row_stride, int col_stride> void EulerAnglesToRotationMatrix(const T* euler, const MatrixAdapter<T, row_stride, col_stride>& R)
.. function:: template <typename T> void EulerAnglesToRotationMatrix(const T* euler, int row_stride, T* R)

   Conversions between 3x3 rotation matrix with given column and row strides and
   Euler angle (in degrees) rotation representations.

   The {pitch,roll,yaw} Euler angles are rotations around the {x,y,z}
   axes, respectively.  They are applied in that same order, so the
   total rotation R is Rz * Ry * Rx.

   The function that takes a pointer to T as the rotation matrix assumes a row
   major representation with unit column stride and a row stride of 3.
   The additional parameter row_stride is required to be 3.

.. function:: template <typename T, int row_stride, int col_stride> void QuaternionToScaledRotation(const T q[4], const MatrixAdapter<T, row_stride, col_stride>& R)
.. function:: template <typename T> void QuaternionToScaledRotation(const T q[4], T R[3 * 3])

   Convert a 4-vector to a 3x3 scaled rotation matrix.

   The choice of rotation is such that the quaternion
   :math:`\begin{bmatrix} 1 &0 &0 &0\end{bmatrix}` goes to an identity
   matrix and for small :math:`a, b, c` the quaternion
   :math:`\begin{bmatrix}1 &a &b &c\end{bmatrix}` goes to the matrix

   .. math::

     I + 2 \begin{bmatrix} 0 & -c & b \\ c & 0 & -a\\ -b & a & 0
           \end{bmatrix} + O(q^2)

   which corresponds to a Rodrigues approximation, the last matrix
   being the cross-product matrix of :math:`\begin{bmatrix} a& b&
   c\end{bmatrix}`. Together with the property that :math:`R(q1 * q2)
   = R(q1) * R(q2)` this uniquely defines the mapping from :math:`q` to
   :math:`R`.

   In the function that accepts a pointer to T instead of a MatrixAdapter,
   the rotation matrix ``R`` is a row-major matrix with unit column stride
   and a row stride of 3.

   No normalization of the quaternion is performed, i.e.
   :math:`R = \|q\|^2  Q`, where :math:`Q` is an orthonormal matrix
   such that :math:`\det(Q) = 1` and :math:`Q*Q' = I`.


.. function:: template <typename T> void QuaternionToRotation(const T q[4], const MatrixAdapter<T, row_stride, col_stride>& R)
.. function:: template <typename T> void QuaternionToRotation(const T q[4], T R[3 * 3])

   Same as above except that the rotation matrix is normalized by the
   Frobenius norm, so that :math:`R R' = I` (and :math:`\det(R) = 1`).

.. function:: template <typename T> void UnitQuaternionRotatePoint(const T q[4], const T pt[3], T result[3])

   Rotates a point pt by a quaternion q:

   .. math:: \text{result} = R(q)  \text{pt}

   Assumes the quaternion is unit norm. If you pass in a quaternion
   with :math:`|q|^2 = 2` then you WILL NOT get back 2 times the
   result you get for a unit quaternion.


.. function:: template <typename T> void QuaternionRotatePoint(const T q[4], const T pt[3], T result[3])

   With this function you do not need to assume that :math:`q` has unit norm.
   It does assume that the norm is non-zero.

.. function:: template <typename T> void QuaternionProduct(const T z[4], const T w[4], T zw[4])

   .. math:: zw = z * w

   where :math:`*` is the Quaternion product between 4-vectors.


.. function:: template <typename T> void CrossProduct(const T x[3], const T y[3], T x_cross_y[3])

   .. math:: \text{x_cross_y} = x \times y

.. function:: template <typename T> void AngleAxisRotatePoint(const T angle_axis[3], const T pt[3], T result[3])

   .. math:: y = R(\text{angle_axis}) x


Cubic Interpolation
===================

Optimization problems often involve functions that are given in the
form of a table of values, for example an image. Evaluating these
functions and their derivatives requires interpolating these
values. Interpolating tabulated functions is a vast area of research
and there are a lot of libraries which implement a variety of
interpolation schemes. However, using them within the automatic
differentiation framework in Ceres is quite painful. To this end,
Ceres provides the ability to interpolate one dimensional and two
dimensional tabular functions.

The one dimensional interpolation is based on the Cubic Hermite
Spline, also known as the Catmull-Rom Spline. This produces a first
order differentiable interpolating function. The two dimensional
interpolation scheme is a generalization of the one dimensional scheme
where the interpolating function is assumed to be separable in the two
dimensions,

More details of the construction can be found `Linear Methods for
Image Interpolation <http://www.ipol.im/pub/art/2011/g_lmii/>`_ by
Pascal Getreuer.

.. class:: CubicInterpolator

Given as input an infinite one dimensional grid, which provides the
following interface.

.. code::

  struct Grid1D {
    enum { DATA_DIMENSION = 2; };
    void GetValue(int n, double* f) const;
  };

Where, ``GetValue`` gives us the value of a function :math:`f`
(possibly vector valued) for any integer :math:`n` and the enum
``DATA_DIMENSION`` indicates the dimensionality of the function being
interpolated. For example if you are interpolating rotations in
axis-angle format over time, then ``DATA_DIMENSION = 3``.

:class:`CubicInterpolator` uses Cubic Hermite splines to produce a
smooth approximation to it that can be used to evaluate the
:math:`f(x)` and :math:`f'(x)` at any point on the real number
line. For example, the following code interpolates an array of four
numbers.

.. code::

  const double x[] = {1.0, 2.0, 5.0, 6.0};
  Grid1D<double, 1> array(x, 0, 4);
  CubicInterpolator interpolator(array);
  double f, dfdx;
  interpolator.Evaluate(1.5, &f, &dfdx);


In the above code we use ``Grid1D`` a templated helper class that
allows easy interfacing between ``C++`` arrays and
:class:`CubicInterpolator`.

``Grid1D`` supports vector valued functions where the various
coordinates of the function can be interleaved or stacked. It also
allows the use of any numeric type as input, as long as it can be
safely cast to a double.

.. class:: BiCubicInterpolator

Given as input an infinite two dimensional grid, which provides the
following interface:

.. code::

  struct Grid2D {
    enum { DATA_DIMENSION = 2 };
    void GetValue(int row, int col, double* f) const;
  };

Where, ``GetValue`` gives us the value of a function :math:`f`
(possibly vector valued) for any pair of integers :code:`row` and
:code:`col` and the enum ``DATA_DIMENSION`` indicates the
dimensionality of the function being interpolated. For example if you
are interpolating a color image with three channels (Red, Green &
Blue), then ``DATA_DIMENSION = 3``.

:class:`BiCubicInterpolator` uses the cubic convolution interpolation
algorithm of R. Keys [Keys]_, to produce a smooth approximation to it
that can be used to evaluate the :math:`f(r,c)`, :math:`\frac{\partial
f(r,c)}{\partial r}` and :math:`\frac{\partial f(r,c)}{\partial c}` at
any any point in the real plane.

For example the following code interpolates a two dimensional array.

.. code::

   const double data[] = {1.0, 3.0, -1.0, 4.0,
                          3.6, 2.1,  4.2, 2.0,
                          2.0, 1.0,  3.1, 5.2};
   Grid2D<double, 1>  array(data, 0, 3, 0, 4);
   BiCubicInterpolator interpolator(array);
   double f, dfdr, dfdc;
   interpolator.Evaluate(1.2, 2.5, &f, &dfdr, &dfdc);

In the above code, the templated helper class ``Grid2D`` is used to
make a ``C++`` array look like a two dimensional table to
:class:`BiCubicInterpolator`.

``Grid2D`` supports row or column major layouts. It also supports
vector valued functions where the individual coordinates of the
function may be interleaved or stacked. It also allows the use of any
numeric type as input, as long as it can be safely cast to double.
