docs: Revise faqs.rst and modeling_faqs.rst Replace legacy LocalParameterization references with Manifold, eliminate sentence fragments, and tighten modeling FAQ answers. Change-Id: Ief25eafbc4f5ef379a809a13c76ce556a2695a7d
diff --git a/docs/source/faqs.rst b/docs/source/faqs.rst index 71dc27b..f1c7228 100644 --- a/docs/source/faqs.rst +++ b/docs/source/faqs.rst
@@ -8,8 +8,8 @@ FAQs, Tips & Tricks =================== -Answers to frequently asked questions, tricks of the trade and general -wisdom. +This chapter collects answers to frequently asked questions and practical advice +for modeling and solving optimization problems with Ceres Solver. .. toctree:: :maxdepth: 2
diff --git a/docs/source/modeling_faqs.rst b/docs/source/modeling_faqs.rst index 5f6891a..abddd55 100644 --- a/docs/source/modeling_faqs.rst +++ b/docs/source/modeling_faqs.rst
@@ -8,31 +8,23 @@ Modeling ======== -Use analytical/automatic derivatives -==================================== +Use analytical or automatic derivatives +======================================= -This is the single most important piece of advice we can give to you. It is -tempting to take the easy way out and use numeric differentiation. This is a bad -idea. Numeric differentiation is slow, ill-behaved, hard to get right, and -results in poor convergence behaviour. +Avoid numeric differentiation whenever possible. Numeric differentiation is slow, +sensitive to step-size choices and floating-point roundoff, and prone to poor +convergence. -Ceres allows the user to define templated functors which will be automatically -differentiated. For most situations this is enough and we recommend using this -facility. In some cases the derivatives are simple enough or the performance -considerations are such that the overhead of automatic differentiation is too -much. In such cases, analytic derivatives are recommended. +Ceres can automatically differentiate templated cost functors, which is the +recommended approach for most problems. When the derivatives have a simple +closed form or the performance overhead of automatic differentiation is too +high, analytic derivatives are worth implementing directly. -The use of numerical derivatives should be a measure of last resort, where it is -simply not possible to write a templated implementation of the cost function. - -In many cases it is not possible to do analytic or automatic differentiation of -the entire cost function, but it is generally the case that it is possible to -decompose the cost function into parts that need to be numerically -differentiated and parts that can be automatically or analytically -differentiated. - -To this end, Ceres has extensive support for mixing analytic, automatic and -numeric differentiation. See :class:`CostFunctionToFunctor`. +Reserve numerical derivatives for cases where a templated implementation of the +cost function is impossible, such as when calling an external library. Even +then, you can often isolate the non-templated evaluation in a helper and +combine numeric differentiation of that part with automatic or analytic +differentiation of the rest using :class:`CostFunctionToFunctor`. Do not return the norm or squared norm of a residual vector from a :class:`CostFunction` ======================================================================================== @@ -77,47 +69,45 @@ When using Quaternions, consider using :class:`QuaternionManifold` ================================================================== -`Quaternions <https://en.wikipedia.org/wiki/Quaternion>`_ are a four dimensional -parameterization of the space of three dimensional rotations :math:`SO(3)`. -However, the :math:`SO(3)` is a three dimensional set, and so is the tangent -space of a Quaternion. Therefore, it is sometimes (not always) beneficial to -associate a local parameterization with parameter blocks representing a -Quaternion. Assuming that the order of entries in your parameter block is -:math:`w,x,y,z`, you can use :class:`QuaternionManifold`. +`Quaternions <https://en.wikipedia.org/wiki/Quaternion>`_ are a +four-dimensional parameterization of the three-dimensional rotation group +:math:`SO(3)`. Because :math:`SO(3)` is three-dimensional, the tangent space of +a unit quaternion is also three-dimensional, so it is often beneficial to +attach a :class:`Manifold` to quaternion parameter blocks. For parameter blocks +stored in :math:`w, x, y, z` order, use :class:`QuaternionManifold`. .. NOTE:: If you are using `Eigen's Quaternion - <https://libeigen.gitlab.io/eigen/docs-nightly/classEigen_1_1Quaternion.html>`_ - object, whose layout is :math:`x,y,z,w`, then you should use - :class:`EigenQuaternionManifold`. + <https://libeigen.gitlab.io/eigen/docs-nightly/classEigen_1_1Quaternion.html>`_, + whose memory layout is :math:`x, y, z, w`, use + :class:`EigenQuaternionManifold` instead. How do I solve problems with general linear & non-linear **inequality** constraints with Ceres Solver? ====================================================================================================== -Currently, Ceres Solver only supports upper and lower bounds constraints on the +Ceres Solver directly supports only lower and upper bound constraints on parameter blocks. -A crude way of dealing with inequality constraints is have one or more of your -cost functions check if the inequalities you are interested in are satisfied, -and if not return false instead of true. This will prevent the solver from ever -stepping into an infeasible region. - -This requires that the starting point for the optimization be a feasible point. -You also risk pre-mature convergence using this method. +A crude workaround for general inequality constraints is to have one or more +cost functions check whether the inequalities are satisfied and return ``false`` +when they are violated. Returning ``false`` rejects the candidate step and +prevents the solver from entering the infeasible region, provided the initial +parameter values are feasible. Because the solver cannot see the constraint +boundary until a step crosses it, however, this approach can cause premature +convergence. How do I solve problems with general linear & non-linear **equality** constraints with Ceres Solver? ==================================================================================================== -There is no built in support in ceres for solving problems with equality -constraints. Currently, Ceres Solver only supports upper and lower bounds -constraints on the parameter blocks. - -The trick described above for dealing with inequality constraints will **not** -work for equality constraints. +Ceres Solver does not support general equality constraints directly; it supports +only lower and upper bound constraints on parameter blocks. The step-rejection +workaround described above for inequality constraints does **not** work for +equality constraints. How do I set one or more components of a parameter block constant? ================================================================== -Using :class:`SubsetManifold`. +Attach a :class:`SubsetManifold` to the parameter block to hold the desired +coordinates constant during optimization.