.. 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::
       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 :math:`3\times3` rotation
matrices. :math:`SO(3)` is a three dimensional manifold embedded in
:math:`\mathbb{R}^9` or :math:`\mathbb{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:`\boxminus` 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)) \leq |\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<QuaternionManifold, EuclideanManifold<3>> se3{QuaternionManifold{}, EuclideanManifold<3>{}};


In C++17, the template parameters can be left out as they are automatically
deduced making the initialization much simpler:

.. code-block:: c++

   ProductManifold se3{QuaternionManifold{}, 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], \quad \|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::
   \begin{align*}
   \boxplus(x, \Delta) &= \exp\left(\Delta\right) \otimes  x \\
   \boxminus(y,x) &= \log\left(y \otimes x^{-1}\right)
   \end{align*}

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 :class:`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 :class:`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:`\mathbb{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 :math:`3\times3` rotation
  matrices. :math:`SO(3)` is a three dimensional manifold embedded in
  :math:`\mathbb{R}^9` or :math:`\mathbb{R}^{3\times 3}`.

  :math:`\boxplus` on :math:`SO(3)` is defined using the *Exponential*
  map, from the tangent space (:math:`\mathbb{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() = default;
       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] \otimes x

The multiplication :math:`\otimes` 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 :member:`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 :member:`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 :member:`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
   :func:`RemoveResidualBlock()`.

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

   If :member:`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 :member:`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() = default;
        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 :math:`3\times3` 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 :math:`3\times3` 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 :math:`3\times3` 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(q_1 \otimes q_2)
   = R(q_1) R(q_2)` 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:`QQ' = 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 \otimes w

   where :math:`\otimes` 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.
