Use subsections instead of an enumeration in solving FAQ
This is a follow-up to related changes made in 018bb49e80ae3d1584fcb343fc31d513cbeb958c.
Change-Id: Ife3befe85d7cea5dad5185a424508d590c0d77f7
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 09f6137..470bde3 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -36,7 +36,7 @@
# General information about the project.
project = u'Ceres Solver'
-copyright = u'2024 Google Inc'
+copyright = u'2025 Google Inc'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
diff --git a/docs/source/solving_faqs.rst b/docs/source/solving_faqs.rst
index a021cbb..17373f2 100644
--- a/docs/source/solving_faqs.rst
+++ b/docs/source/solving_faqs.rst
@@ -8,158 +8,161 @@
Solving
=======
-#. How do I evaluate the Jacobian for a solved problem?
+How do I evaluate the Jacobian for a solved problem?
+====================================================
- Using :func:`Problem::Evaluate`.
+Using :func:`Problem::Evaluate`.
-#. How do I choose the right linear solver?
+How do I choose the right linear solver?
+========================================
- When using the ``TRUST_REGION`` minimizer, the choice of linear
- solver is an important decision. It affects solution quality and
- runtime. Here is a simple way to reason about it.
+When using the ``TRUST_REGION`` minimizer, the choice of linear solver is an
+important decision. It affects solution quality and runtime. Here is a simple
+way to reason about it.
- 1. For small (a few hundred parameters) or dense problems use
- ``DENSE_QR``.
+1. For small (a few hundred parameters) or dense problems use
+ ``DENSE_QR``.
- 2. For general sparse problems (i.e., the Jacobian matrix has a
- substantial number of zeros) use
- ``SPARSE_NORMAL_CHOLESKY``.
+2. For general sparse problems (i.e., the Jacobian matrix has a
+ substantial number of zeros) use
+ ``SPARSE_NORMAL_CHOLESKY``.
- 3. For bundle adjustment problems with up to a hundred or so
- cameras, use ``DENSE_SCHUR``.
+3. For bundle adjustment problems with up to a hundred or so
+ cameras, use ``DENSE_SCHUR``.
- 4. For larger bundle adjustment problems with sparse Schur
- Complement/Reduced camera matrices use ``SPARSE_SCHUR``.
+4. For larger bundle adjustment problems with sparse Schur
+ Complement/Reduced camera matrices use ``SPARSE_SCHUR``.
- If you do not have access to these libraries for whatever
- reason, ``ITERATIVE_SCHUR`` with ``SCHUR_JACOBI`` is an
- excellent alternative.
+ If you do not have access to these libraries for whatever
+ reason, ``ITERATIVE_SCHUR`` with ``SCHUR_JACOBI`` is an
+ excellent alternative.
- 5. For large bundle adjustment problems (a few thousand cameras or
- more) use the ``ITERATIVE_SCHUR`` solver. There are a number of
- preconditioner choices here. ``SCHUR_JACOBI`` offers an
- excellent balance of speed and accuracy. This is also the
- recommended option if you are solving medium sized problems for
- which ``DENSE_SCHUR`` is too slow but ``SuiteSparse`` is not
- available.
+5. For large bundle adjustment problems (a few thousand cameras or
+ more) use the ``ITERATIVE_SCHUR`` solver. There are a number of
+ preconditioner choices here. ``SCHUR_JACOBI`` offers an
+ excellent balance of speed and accuracy. This is also the
+ recommended option if you are solving medium sized problems for
+ which ``DENSE_SCHUR`` is too slow but ``SuiteSparse`` is not
+ available.
- .. NOTE::
+ .. NOTE::
- If you are solving small to medium sized problems, consider
- setting ``Solver::Options::use_explicit_schur_complement`` to
- ``true``, it can result in a substantial performance boost.
+ If you are solving small to medium sized problems, consider
+ setting ``Solver::Options::use_explicit_schur_complement`` to
+ ``true``, it can result in a substantial performance boost.
- If you are not satisfied with ``SCHUR_JACOBI``'s performance try
- ``CLUSTER_JACOBI`` and ``CLUSTER_TRIDIAGONAL`` in that
- order. They require that you have ``SuiteSparse``
- installed. Both of these preconditioners use a clustering
- algorithm. Use ``SINGLE_LINKAGE`` before ``CANONICAL_VIEWS``.
+ If you are not satisfied with ``SCHUR_JACOBI``'s performance try
+ ``CLUSTER_JACOBI`` and ``CLUSTER_TRIDIAGONAL`` in that
+ order. They require that you have ``SuiteSparse``
+ installed. Both of these preconditioners use a clustering
+ algorithm. Use ``SINGLE_LINKAGE`` before ``CANONICAL_VIEWS``.
-#. Use :func:`Solver::Summary::FullReport` to diagnose performance problems.
+Use :func:`Solver::Summary::FullReport` to diagnose performance problems
+=========================================================================
- When diagnosing Ceres performance issues - runtime and convergence,
- the first place to start is by looking at the output of
- ``Solver::Summary::FullReport``. Here is an example
+When diagnosing Ceres performance issues - runtime and convergence, the first
+place to start is by looking at the output of ``Solver::Summary::FullReport``.
+Here is an example
- .. code-block:: console
+.. code-block:: console
- ./bin/bundle_adjuster --input ../data/problem-16-22106-pre.txt
+ ./bin/bundle_adjuster --input ../data/problem-16-22106-pre.txt
- iter cost cost_change |gradient| |step| tr_ratio tr_radius ls_iter iter_time total_time
- 0 4.185660e+06 0.00e+00 2.16e+07 0.00e+00 0.00e+00 1.00e+04 0 7.50e-02 3.58e-01
- 1 1.980525e+05 3.99e+06 5.34e+06 2.40e+03 9.60e-01 3.00e+04 1 1.84e-01 5.42e-01
- 2 5.086543e+04 1.47e+05 2.11e+06 1.01e+03 8.22e-01 4.09e+04 1 1.53e-01 6.95e-01
- 3 1.859667e+04 3.23e+04 2.87e+05 2.64e+02 9.85e-01 1.23e+05 1 1.71e-01 8.66e-01
- 4 1.803857e+04 5.58e+02 2.69e+04 8.66e+01 9.93e-01 3.69e+05 1 1.61e-01 1.03e+00
- 5 1.803391e+04 4.66e+00 3.11e+02 1.02e+01 1.00e+00 1.11e+06 1 1.49e-01 1.18e+00
+ iter cost cost_change |gradient| |step| tr_ratio tr_radius ls_iter iter_time total_time
+ 0 4.185660e+06 0.00e+00 2.16e+07 0.00e+00 0.00e+00 1.00e+04 0 7.50e-02 3.58e-01
+ 1 1.980525e+05 3.99e+06 5.34e+06 2.40e+03 9.60e-01 3.00e+04 1 1.84e-01 5.42e-01
+ 2 5.086543e+04 1.47e+05 2.11e+06 1.01e+03 8.22e-01 4.09e+04 1 1.53e-01 6.95e-01
+ 3 1.859667e+04 3.23e+04 2.87e+05 2.64e+02 9.85e-01 1.23e+05 1 1.71e-01 8.66e-01
+ 4 1.803857e+04 5.58e+02 2.69e+04 8.66e+01 9.93e-01 3.69e+05 1 1.61e-01 1.03e+00
+ 5 1.803391e+04 4.66e+00 3.11e+02 1.02e+01 1.00e+00 1.11e+06 1 1.49e-01 1.18e+00
- Ceres Solver v1.12.0 Solve Report
- ----------------------------------
- Original Reduced
- Parameter blocks 22122 22122
- Parameters 66462 66462
- Residual blocks 83718 83718
- Residual 167436 167436
+ Ceres Solver v1.12.0 Solve Report
+ ----------------------------------
+ Original Reduced
+ Parameter blocks 22122 22122
+ Parameters 66462 66462
+ Residual blocks 83718 83718
+ Residual 167436 167436
- Minimizer TRUST_REGION
+ Minimizer TRUST_REGION
- Sparse linear algebra library SUITE_SPARSE
- Trust region strategy LEVENBERG_MARQUARDT
+ Sparse linear algebra library SUITE_SPARSE
+ Trust region strategy LEVENBERG_MARQUARDT
- Given Used
- Linear solver SPARSE_SCHUR SPARSE_SCHUR
- Threads 1 1
- Linear solver threads 1 1
- Linear solver ordering AUTOMATIC 22106, 16
+ Given Used
+ Linear solver SPARSE_SCHUR SPARSE_SCHUR
+ Threads 1 1
+ Linear solver threads 1 1
+ Linear solver ordering AUTOMATIC 22106, 16
- Cost:
- Initial 4.185660e+06
- Final 1.803391e+04
- Change 4.167626e+06
+ Cost:
+ Initial 4.185660e+06
+ Final 1.803391e+04
+ Change 4.167626e+06
- Minimizer iterations 5
- Successful steps 5
- Unsuccessful steps 0
+ Minimizer iterations 5
+ Successful steps 5
+ Unsuccessful steps 0
- Time (in seconds):
- Preprocessor 0.283
+ Time (in seconds):
+ Preprocessor 0.283
- Residual evaluation 0.061
- Jacobian evaluation 0.361
- Linear solver 0.382
- Minimizer 0.895
+ Residual evaluation 0.061
+ Jacobian evaluation 0.361
+ Linear solver 0.382
+ Minimizer 0.895
- Postprocessor 0.002
- Total 1.220
+ Postprocessor 0.002
+ Total 1.220
- Termination: NO_CONVERGENCE (Maximum number of iterations reached.)
+ Termination: NO_CONVERGENCE (Maximum number of iterations reached.)
- Let us focus on run-time performance. The relevant lines to look at are
+Let us focus on run-time performance. The relevant lines to look at are
- .. code-block:: console
+.. code-block:: console
- Time (in seconds):
- Preprocessor 0.283
+ Time (in seconds):
+ Preprocessor 0.283
- Residual evaluation 0.061
- Jacobian evaluation 0.361
- Linear solver 0.382
- Minimizer 0.895
+ Residual evaluation 0.061
+ Jacobian evaluation 0.361
+ Linear solver 0.382
+ Minimizer 0.895
- Postprocessor 0.002
- Total 1.220
+ Postprocessor 0.002
+ Total 1.220
- Which tell us that of the total 1.2 seconds, about .3 seconds was spent in
- the linear solver and the rest was mostly spent in preprocessing and jacobian
- evaluation.
+Which tell us that of the total 1.2 seconds, about .3 seconds was spent in the
+linear solver and the rest was mostly spent in preprocessing and jacobian
+evaluation.
- The preprocessing seems particularly expensive. Looking back at the report,
- we observe
+The preprocessing seems particularly expensive. Looking back at the report, we
+observe
- .. code-block:: console
+.. code-block:: console
- Linear solver ordering AUTOMATIC 22106, 16
+ Linear solver ordering AUTOMATIC 22106, 16
- Which indicates that we are using automatic ordering for the ``SPARSE_SCHUR``
- solver. This can be expensive at times. A straight forward way to deal with
- this is to give the ordering manually. For ``bundle_adjuster`` this can be
- done by passing the flag ``-ordering=user``. Doing so and looking at the
- timing block of the full report gives us
+Which indicates that we are using automatic ordering for the ``SPARSE_SCHUR``
+solver. This can be expensive at times. A straight forward way to deal with this
+is to give the ordering manually. For ``bundle_adjuster`` this can be done by
+passing the flag ``-ordering=user``. Doing so and looking at the timing block of
+the full report gives us
- .. code-block:: console
+.. code-block:: console
- Time (in seconds):
- Preprocessor 0.051
+ Time (in seconds):
+ Preprocessor 0.051
- Residual evaluation 0.053
- Jacobian evaluation 0.344
- Linear solver 0.372
- Minimizer 0.854
+ Residual evaluation 0.053
+ Jacobian evaluation 0.344
+ Linear solver 0.372
+ Minimizer 0.854
- Postprocessor 0.002
- Total 0.935
+ Postprocessor 0.002
+ Total 0.935
- The preprocessor time has gone down by more than 5.5x!
+The preprocessor time has gone down by more than 5.5x!