Blame docs/source/modeling_faqs.rst

Packit ea1746
.. _chapter-modeling_faqs:
Packit ea1746
Packit ea1746
.. default-domain:: cpp
Packit ea1746
Packit ea1746
.. cpp:namespace:: ceres
Packit ea1746
Packit ea1746
========
Packit ea1746
Modeling
Packit ea1746
========
Packit ea1746
Packit ea1746
#. Use analytical/automatic derivatives.
Packit ea1746
Packit ea1746
   This is the single most important piece of advice we can give to
Packit ea1746
   you. It is tempting to take the easy way out and use numeric
Packit ea1746
   differentiation. This is a bad idea. Numeric differentiation is
Packit ea1746
   slow, ill-behaved, hard to get right, and results in poor
Packit ea1746
   convergence behaviour.
Packit ea1746
Packit ea1746
   Ceres allows the user to define templated functors which will
Packit ea1746
   be automatically differentiated. For most situations this is enough
Packit ea1746
   and we recommend using this facility. In some cases the derivatives
Packit ea1746
   are simple enough or the performance considerations are such that
Packit ea1746
   the overhead of automatic differentiation is too much. In such
Packit ea1746
   cases, analytic derivatives are recommended.
Packit ea1746
Packit ea1746
   The use of numerical derivatives should be a measure of last
Packit ea1746
   resort, where it is simply not possible to write a templated
Packit ea1746
   implementation of the cost function.
Packit ea1746
Packit ea1746
   In many cases it is not possible to do analytic or automatic
Packit ea1746
   differentiation of the entire cost function, but it is generally
Packit ea1746
   the case that it is possible to decompose the cost function into
Packit ea1746
   parts that need to be numerically differentiated and parts that can
Packit ea1746
   be automatically or analytically differentiated.
Packit ea1746
Packit ea1746
   To this end, Ceres has extensive support for mixing analytic,
Packit ea1746
   automatic and numeric differentiation. See
Packit ea1746
   :class:`CostFunctionToFunctor`.
Packit ea1746
Packit ea1746
#. When using Quaternions,  consider using :class:`QuaternionParameterization`.
Packit ea1746
Packit ea1746
   `Quaternions <https://en.wikipedia.org/wiki/Quaternion>`_ are a
Packit ea1746
   four dimensional parameterization of the space of three dimensional
Packit ea1746
   rotations :math:`SO(3)`.  However, the :math:`SO(3)` is a three
Packit ea1746
   dimensional set, and so is the tangent space of a
Packit ea1746
   Quaternion. Therefore, it is sometimes (not always) benefecial to
Packit ea1746
   associate a local parameterization with parameter blocks
Packit ea1746
   representing a Quaternion. Assuming that the order of entries in
Packit ea1746
   your parameter block is :math:`w,x,y,z`, you can use
Packit ea1746
   :class:`QuaternionParameterization`.
Packit ea1746
Packit ea1746
   .. NOTE::
Packit ea1746
Packit ea1746
     If you are using `Eigen's Quaternion
Packit ea1746
     <http://eigen.tuxfamily.org/dox/classEigen_1_1Quaternion.html>`_
Packit ea1746
     object, whose layout is :math:`x,y,z,w`, then you should use
Packit ea1746
     :class:`EigenQuaternionParameterization`.
Packit ea1746
Packit ea1746
Packit ea1746
#. How do I solve problems with general linear & non-linear
Packit ea1746
   **inequality** constraints with Ceres Solver?
Packit ea1746
Packit ea1746
   Currently, Ceres Solver only supports upper and lower bounds
Packit ea1746
   constraints on the parameter blocks.
Packit ea1746
Packit ea1746
   A crude way of dealing with inequality constraints is have one or
Packit ea1746
   more of your cost functions check if the inequalities you are
Packit ea1746
   interested in are satisfied, and if not return false instead of
Packit ea1746
   true. This will prevent the solver from ever stepping into an
Packit ea1746
   infeasible region.
Packit ea1746
Packit ea1746
   This requires that the starting point for the optimization be a
Packit ea1746
   feasible point.  You also risk pre-mature convergence using this
Packit ea1746
   method.
Packit ea1746
Packit ea1746
#. How do I solve problems with general linear & non-linear **equality**
Packit ea1746
   constraints with Ceres Solver?
Packit ea1746
Packit ea1746
   There is no built in support in ceres for solving problems with
Packit ea1746
   equality constraints.  Currently, Ceres Solver only supports upper
Packit ea1746
   and lower bounds constraints on the parameter blocks.
Packit ea1746
Packit ea1746
   The trick described above for dealing with inequality
Packit ea1746
   constraints will **not** work for equality constraints.
Packit ea1746
Packit ea1746
#. How do I set one or more components of a parameter block constant?
Packit ea1746
Packit ea1746
   Using :class:`SubsetParameterization`.
Packit ea1746
Packit ea1746
#. Putting `Inverse Function Theorem
Packit ea1746
   <http://en.wikipedia.org/wiki/Inverse_function_theorem>`_ to use.
Packit ea1746
Packit ea1746
   Every now and then we have to deal with functions which cannot be
Packit ea1746
   evaluated analytically. Computing the Jacobian in such cases is
Packit ea1746
   tricky. A particularly interesting case is where the inverse of the
Packit ea1746
   function is easy to compute analytically. An example of such a
Packit ea1746
   function is the Coordinate transformation between the `ECEF
Packit ea1746
   <http://en.wikipedia.org/wiki/ECEF>`_ and the `WGS84
Packit ea1746
   <http://en.wikipedia.org/wiki/World_Geodetic_System>`_ where the
Packit ea1746
   conversion from WGS84 to ECEF is analytic, but the conversion
Packit ea1746
   back to WGS84 uses an iterative algorithm. So how do you compute the
Packit ea1746
   derivative of the ECEF to WGS84 transformation?
Packit ea1746
Packit ea1746
   One obvious approach would be to numerically
Packit ea1746
   differentiate the conversion function. This is not a good idea. For
Packit ea1746
   one, it will be slow, but it will also be numerically quite
Packit ea1746
   bad.
Packit ea1746
Packit ea1746
   Turns out you can use the `Inverse Function Theorem
Packit ea1746
   <http://en.wikipedia.org/wiki/Inverse_function_theorem>`_ in this
Packit ea1746
   case to compute the derivatives more or less analytically.
Packit ea1746
Packit ea1746
   The key result here is. If :math:`x = f^{-1}(y)`, and :math:`Df(x)`
Packit ea1746
   is the invertible Jacobian of :math:`f` at :math:`x`. Then the
Packit ea1746
   Jacobian :math:`Df^{-1}(y) = [Df(x)]^{-1}`, i.e., the Jacobian of
Packit ea1746
   the :math:`f^{-1}` is the inverse of the Jacobian of :math:`f`.
Packit ea1746
Packit ea1746
   Algorithmically this means that given :math:`y`, compute :math:`x =
Packit ea1746
   f^{-1}(y)` by whatever means you can. Evaluate the Jacobian of
Packit ea1746
   :math:`f` at :math:`x`. If the Jacobian matrix is invertible, then
Packit ea1746
   its inverse is the Jacobian of :math:`f^{-1}(y)` at  :math:`y`.
Packit ea1746
Packit ea1746
   One can put this into practice with the following code fragment.
Packit ea1746
Packit ea1746
   .. code-block:: c++
Packit ea1746
Packit ea1746
      Eigen::Vector3d ecef; // Fill some values
Packit ea1746
      // Iterative computation.
Packit ea1746
      Eigen::Vector3d lla = ECEFToLLA(ecef);
Packit ea1746
      // Analytic derivatives
Packit ea1746
      Eigen::Matrix3d lla_to_ecef_jacobian = LLAToECEFJacobian(lla);
Packit ea1746
      bool invertible;
Packit ea1746
      Eigen::Matrix3d ecef_to_lla_jacobian;
Packit ea1746
      lla_to_ecef_jacobian.computeInverseWithCheck(ecef_to_lla_jacobian, invertible);