Home | History | Annotate | Download | only in source
      1 .. highlight:: c++
      2 
      3 .. default-domain:: cpp
      4 
      5 .. _chapter-tutorial:
      6 
      7 ========
      8 Tutorial
      9 ========
     10 
     11 Ceres solves robustified non-linear bounds constrained least squares
     12 problems of the form
     13 
     14 .. math:: :label: ceresproblem
     15 
     16    \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) \\
     17    \text{s.t.} &\quad l_j \le x_j \le u_j
     18 
     19 Problems of this form comes up in a broad range of areas across
     20 science and engineering - from `fitting curves`_ in statistics, to
     21 constructing `3D models from photographs`_ in computer vision.
     22 
     23 .. _fitting curves: http://en.wikipedia.org/wiki/Nonlinear_regression
     24 .. _3D models from photographs: http://en.wikipedia.org/wiki/Bundle_adjustment
     25 
     26 In this chapter we will learn how to solve :eq:`ceresproblem` using
     27 Ceres Solver. Full working code for all the examples described in this
     28 chapter and more can be found in the `examples
     29 <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/>`_
     30 directory.
     31 
     32 The expression
     33 :math:`\rho_i\left(\left\|f_i\left(x_{i_1},...,x_{i_k}\right)\right\|^2\right)`
     34 is known as a ``ResidualBlock``, where :math:`f_i(\cdot)` is a
     35 :class:`CostFunction` that depends on the parameter blocks
     36 :math:`\left[x_{i_1},... , x_{i_k}\right]`. In most optimization
     37 problems small groups of scalars occur together. For example the three
     38 components of a translation vector and the four components of the
     39 quaternion that define the pose of a camera. We refer to such a group
     40 of small scalars as a ``ParameterBlock``. Of course a
     41 ``ParameterBlock`` can just be a single parameter. :math:`l_j` and
     42 :math:`u_j` are bounds on the parameter block :math:`x_j`.
     43 
     44 :math:`\rho_i` is a :class:`LossFunction`. A :class:`LossFunction` is
     45 a scalar function that is used to reduce the influence of outliers on
     46 the solution of non-linear least squares problems.
     47 
     48 As a special case, when :math:`\rho_i(x) = x`, i.e., the identity
     49 function, and :math:`l_j = -\infty` and :math:`u_j = \infty` we get
     50 the more familiar `non-linear least squares problem
     51 <http://en.wikipedia.org/wiki/Non-linear_least_squares>`_.
     52 
     53 .. math:: \frac{1}{2}\sum_{i} \left\|f_i\left(x_{i_1}, ... ,x_{i_k}\right)\right\|^2.
     54    :label: ceresproblem2
     55 
     56 .. _section-hello-world:
     57 
     58 Hello World!
     59 ============
     60 
     61 To get started, consider the problem of finding the minimum of the
     62 function
     63 
     64 .. math:: \frac{1}{2}(10 -x)^2.
     65 
     66 This is a trivial problem, whose minimum is located at :math:`x = 10`,
     67 but it is a good place to start to illustrate the basics of solving a
     68 problem with Ceres [#f1]_.
     69 
     70 The first step is to write a functor that will evaluate this the
     71 function :math:`f(x) = 10 - x`:
     72 
     73 .. code-block:: c++
     74 
     75    struct CostFunctor {
     76       template <typename T>
     77       bool operator()(const T* const x, T* residual) const {
     78         residual[0] = T(10.0) - x[0];
     79         return true;
     80       }
     81    };
     82 
     83 The important thing to note here is that ``operator()`` is a templated
     84 method, which assumes that all its inputs and outputs are of some type
     85 ``T``. The use of templating here allows Ceres to call
     86 ``CostFunctor::operator<T>()``, with ``T=double`` when just the value
     87 of the residual is needed, and with a special type ``T=Jet`` when the
     88 Jacobians are needed. In :ref:`section-derivatives` we will discuss the
     89 various ways of supplying derivatives to Ceres in more detail.
     90 
     91 Once we have a way of computing the residual function, it is now time
     92 to construct a non-linear least squares problem using it and have
     93 Ceres solve it.
     94 
     95 .. code-block:: c++
     96 
     97    int main(int argc, char** argv) {
     98      google::InitGoogleLogging(argv[0]);
     99 
    100      // The variable to solve for with its initial value.
    101      double initial_x = 5.0;
    102      double x = initial_x;
    103 
    104      // Build the problem.
    105      Problem problem;
    106 
    107      // Set up the only cost function (also known as residual). This uses
    108      // auto-differentiation to obtain the derivative (jacobian).
    109      CostFunction* cost_function =
    110          new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor);
    111      problem.AddResidualBlock(cost_function, NULL, &x);
    112 
    113      // Run the solver!
    114      Solver::Options options;
    115      options.linear_solver_type = ceres::DENSE_QR;
    116      options.minimizer_progress_to_stdout = true;
    117      Solver::Summary summary;
    118      Solve(options, &problem, &summary);
    119 
    120      std::cout << summary.BriefReport() << "\n";
    121      std::cout << "x : " << initial_x
    122                << " -> " << x << "\n";
    123      return 0;
    124    }
    125 
    126 :class:`AutoDiffCostFunction` takes a ``CostFunctor`` as input,
    127 automatically differentiates it and gives it a :class:`CostFunction`
    128 interface.
    129 
    130 Compiling and running `examples/helloworld.cc
    131 <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/helloworld.cc>`_
    132 gives us
    133 
    134 .. code-block:: bash
    135 
    136    iter      cost      cost_change  |gradient|   |step|    tr_ratio  tr_radius  ls_iter  iter_time  total_time
    137       0  4.512500e+01    0.00e+00    9.50e+00   0.00e+00   0.00e+00  1.00e+04       0    5.33e-04    3.46e-03
    138       1  4.511598e-07    4.51e+01    9.50e-04   9.50e+00   1.00e+00  3.00e+04       1    5.00e-04    4.05e-03
    139       2  5.012552e-16    4.51e-07    3.17e-08   9.50e-04   1.00e+00  9.00e+04       1    1.60e-05    4.09e-03
    140    Ceres Solver Report: Iterations: 2, Initial cost: 4.512500e+01, Final cost: 5.012552e-16, Termination: CONVERGENCE
    141    x : 0.5 -> 10
    142 
    143 Starting from a :math:`x=5`, the solver in two iterations goes to 10
    144 [#f2]_. The careful reader will note that this is a linear problem and
    145 one linear solve should be enough to get the optimal value.  The
    146 default configuration of the solver is aimed at non-linear problems,
    147 and for reasons of simplicity we did not change it in this example. It
    148 is indeed possible to obtain the solution to this problem using Ceres
    149 in one iteration. Also note that the solver did get very close to the
    150 optimal function value of 0 in the very first iteration. We will
    151 discuss these issues in greater detail when we talk about convergence
    152 and parameter settings for Ceres.
    153 
    154 .. rubric:: Footnotes
    155 
    156 .. [#f1] `examples/helloworld.cc
    157    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/helloworld.cc>`_
    158 
    159 .. [#f2] Actually the solver ran for three iterations, and it was
    160    by looking at the value returned by the linear solver in the third
    161    iteration, it observed that the update to the parameter block was too
    162    small and declared convergence. Ceres only prints out the display at
    163    the end of an iteration, and terminates as soon as it detects
    164    convergence, which is why you only see two iterations here and not
    165    three.
    166 
    167 .. _section-derivatives:
    168 
    169 
    170 Derivatives
    171 ===========
    172 
    173 Ceres Solver like most optimization packages, depends on being able to
    174 evaluate the value and the derivatives of each term in the objective
    175 function at arbitrary parameter values. Doing so correctly and
    176 efficiently is essential to getting good results.  Ceres Solver
    177 provides a number of ways of doing so. You have already seen one of
    178 them in action --
    179 Automatic Differentiation in `examples/helloworld.cc
    180 <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/helloworld.cc>`_
    181 
    182 We now consider the other two possibilities. Analytic and numeric
    183 derivatives.
    184 
    185 
    186 Numeric Derivatives
    187 -------------------
    188 
    189 In some cases, its not possible to define a templated cost functor,
    190 for example when the evaluation of the residual involves a call to a
    191 library function that you do not have control over.  In such a
    192 situation, numerical differentiation can be used. The user defines a
    193 functor which computes the residual value and construct a
    194 :class:`NumericDiffCostFunction` using it. e.g., for :math:`f(x) = 10 - x`
    195 the corresponding functor would be
    196 
    197 .. code-block:: c++
    198 
    199   struct NumericDiffCostFunctor {
    200     bool operator()(const double* const x, double* residual) const {
    201       residual[0] = 10.0 - x[0];
    202       return true;
    203     }
    204   };
    205 
    206 Which is added to the :class:`Problem` as:
    207 
    208 .. code-block:: c++
    209 
    210   CostFunction* cost_function =
    211     new NumericDiffCostFunction<NumericDiffCostFunctor, ceres::CENTRAL, 1, 1, 1>(
    212         new NumericDiffCostFunctor)
    213   problem.AddResidualBlock(cost_function, NULL, &x);
    214 
    215 Notice the parallel from when we were using automatic differentiation
    216 
    217 .. code-block:: c++
    218 
    219   CostFunction* cost_function =
    220       new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor);
    221   problem.AddResidualBlock(cost_function, NULL, &x);
    222 
    223 The construction looks almost identical to the one used for automatic
    224 differentiation, except for an extra template parameter that indicates
    225 the kind of finite differencing scheme to be used for computing the
    226 numerical derivatives [#f3]_. For more details see the documentation
    227 for :class:`NumericDiffCostFunction`.
    228 
    229 **Generally speaking we recommend automatic differentiation instead of
    230 numeric differentiation. The use of C++ templates makes automatic
    231 differentiation efficient, whereas numeric differentiation is
    232 expensive, prone to numeric errors, and leads to slower convergence.**
    233 
    234 
    235 Analytic Derivatives
    236 --------------------
    237 
    238 In some cases, using automatic differentiation is not possible. For
    239 example, it may be the case that it is more efficient to compute the
    240 derivatives in closed form instead of relying on the chain rule used
    241 by the automatic differentiation code.
    242 
    243 In such cases, it is possible to supply your own residual and jacobian
    244 computation code. To do this, define a subclass of
    245 :class:`CostFunction` or :class:`SizedCostFunction` if you know the
    246 sizes of the parameters and residuals at compile time. Here for
    247 example is ``SimpleCostFunction`` that implements :math:`f(x) = 10 -
    248 x`.
    249 
    250 .. code-block:: c++
    251 
    252   class QuadraticCostFunction : public ceres::SizedCostFunction<1, 1> {
    253    public:
    254     virtual ~QuadraticCostFunction() {}
    255     virtual bool Evaluate(double const* const* parameters,
    256                           double* residuals,
    257                           double** jacobians) const {
    258       const double x = parameters[0][0];
    259       residuals[0] = 10 - x;
    260 
    261       // Compute the Jacobian if asked for.
    262       if (jacobians != NULL && jacobians[0] != NULL) {
    263         jacobians[0][0] = -1;
    264       }
    265       return true;
    266     }
    267   };
    268 
    269 
    270 ``SimpleCostFunction::Evaluate`` is provided with an input array of
    271 ``parameters``, an output array ``residuals`` for residuals and an
    272 output array ``jacobians`` for Jacobians. The ``jacobians`` array is
    273 optional, ``Evaluate`` is expected to check when it is non-null, and
    274 if it is the case then fill it with the values of the derivative of
    275 the residual function. In this case since the residual function is
    276 linear, the Jacobian is constant [#f4]_ .
    277 
    278 As can be seen from the above code fragments, implementing
    279 :class:`CostFunction` objects is a bit tedious. We recommend that
    280 unless you have a good reason to manage the jacobian computation
    281 yourself, you use :class:`AutoDiffCostFunction` or
    282 :class:`NumericDiffCostFunction` to construct your residual blocks.
    283 
    284 More About Derivatives
    285 ----------------------
    286 
    287 Computing derivatives is by far the most complicated part of using
    288 Ceres, and depending on the circumstance the user may need more
    289 sophisticated ways of computing derivatives. This section just
    290 scratches the surface of how derivatives can be supplied to
    291 Ceres. Once you are comfortable with using
    292 :class:`NumericDiffCostFunction` and :class:`AutoDiffCostFunction` we
    293 recommend taking a look at :class:`DynamicAutoDiffCostFunction`,
    294 :class:`CostFunctionToFunctor`, :class:`NumericDiffFunctor` and
    295 :class:`ConditionedCostFunction` for more advanced ways of
    296 constructing and computing cost functions.
    297 
    298 .. rubric:: Footnotes
    299 
    300 .. [#f3] `examples/helloworld_numeric_diff.cc
    301    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/helloworld_numeric_diff.cc>`_.
    302 
    303 .. [#f4] `examples/helloworld_analytic_diff.cc
    304    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/helloworld_analytic_diff.cc>`_.
    305 
    306 
    307 .. _section-powell:
    308 
    309 Powell's Function
    310 =================
    311 
    312 Consider now a slightly more complicated example -- the minimization
    313 of Powell's function. Let :math:`x = \left[x_1, x_2, x_3, x_4 \right]`
    314 and
    315 
    316 .. math::
    317 
    318   \begin{align}
    319      f_1(x) &= x_1 + 10x_2 \\
    320      f_2(x) &= \sqrt{5}  (x_3 - x_4)\\
    321      f_3(x) &= (x_2 - 2x_3)^2\\
    322      f_4(x) &= \sqrt{10}  (x_1 - x_4)^2\\
    323        F(x) &= \left[f_1(x),\ f_2(x),\ f_3(x),\ f_4(x) \right]
    324   \end{align}
    325 
    326 
    327 :math:`F(x)` is a function of four parameters, has four residuals
    328 and we wish to find :math:`x` such that :math:`\frac{1}{2}\|F(x)\|^2`
    329 is minimized.
    330 
    331 Again, the first step is to define functors that evaluate of the terms
    332 in the objective functor. Here is the code for evaluating
    333 :math:`f_4(x_1, x_4)`:
    334 
    335 .. code-block:: c++
    336 
    337  struct F4 {
    338    template <typename T>
    339    bool operator()(const T* const x1, const T* const x4, T* residual) const {
    340      residual[0] = T(sqrt(10.0)) * (x1[0] - x4[0]) * (x1[0] - x4[0]);
    341      return true;
    342    }
    343  };
    344 
    345 
    346 Similarly, we can define classes ``F1``, ``F2`` and ``F4`` to evaluate
    347 :math:`f_1(x_1, x_2)`, :math:`f_2(x_3, x_4)` and :math:`f_3(x_2, x_3)`
    348 respectively. Using these, the problem can be constructed as follows:
    349 
    350 
    351 .. code-block:: c++
    352 
    353   double x1 =  3.0; double x2 = -1.0; double x3 =  0.0; double x4 = 1.0;
    354 
    355   Problem problem;
    356 
    357   // Add residual terms to the problem using the using the autodiff
    358   // wrapper to get the derivatives automatically.
    359   problem.AddResidualBlock(
    360     new AutoDiffCostFunction<F1, 1, 1, 1>(new F1), NULL, &x1, &x2);
    361   problem.AddResidualBlock(
    362     new AutoDiffCostFunction<F2, 1, 1, 1>(new F2), NULL, &x3, &x4);
    363   problem.AddResidualBlock(
    364     new AutoDiffCostFunction<F3, 1, 1, 1>(new F3), NULL, &x2, &x3)
    365   problem.AddResidualBlock(
    366     new AutoDiffCostFunction<F4, 1, 1, 1>(new F4), NULL, &x1, &x4);
    367 
    368 
    369 Note that each ``ResidualBlock`` only depends on the two parameters
    370 that the corresponding residual object depends on and not on all four
    371 parameters. Compiling and running `examples/powell.cc
    372 <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/powell.cc>`_
    373 gives us:
    374 
    375 .. code-block:: bash
    376 
    377     Initial x1 = 3, x2 = -1, x3 = 0, x4 = 1
    378     iter      cost      cost_change  |gradient|   |step|    tr_ratio  tr_radius  ls_iter  iter_time  total_time
    379        0  1.075000e+02    0.00e+00    1.55e+02   0.00e+00   0.00e+00  1.00e+04       0    4.95e-04    2.30e-03
    380        1  5.036190e+00    1.02e+02    2.00e+01   2.16e+00   9.53e-01  3.00e+04       1    4.39e-05    2.40e-03
    381        2  3.148168e-01    4.72e+00    2.50e+00   6.23e-01   9.37e-01  9.00e+04       1    9.06e-06    2.43e-03
    382        3  1.967760e-02    2.95e-01    3.13e-01   3.08e-01   9.37e-01  2.70e+05       1    8.11e-06    2.45e-03
    383        4  1.229900e-03    1.84e-02    3.91e-02   1.54e-01   9.37e-01  8.10e+05       1    6.91e-06    2.48e-03
    384        5  7.687123e-05    1.15e-03    4.89e-03   7.69e-02   9.37e-01  2.43e+06       1    7.87e-06    2.50e-03
    385        6  4.804625e-06    7.21e-05    6.11e-04   3.85e-02   9.37e-01  7.29e+06       1    5.96e-06    2.52e-03
    386        7  3.003028e-07    4.50e-06    7.64e-05   1.92e-02   9.37e-01  2.19e+07       1    5.96e-06    2.55e-03
    387        8  1.877006e-08    2.82e-07    9.54e-06   9.62e-03   9.37e-01  6.56e+07       1    5.96e-06    2.57e-03
    388        9  1.173223e-09    1.76e-08    1.19e-06   4.81e-03   9.37e-01  1.97e+08       1    7.87e-06    2.60e-03
    389       10  7.333425e-11    1.10e-09    1.49e-07   2.40e-03   9.37e-01  5.90e+08       1    6.20e-06    2.63e-03
    390       11  4.584044e-12    6.88e-11    1.86e-08   1.20e-03   9.37e-01  1.77e+09       1    6.91e-06    2.65e-03
    391       12  2.865573e-13    4.30e-12    2.33e-09   6.02e-04   9.37e-01  5.31e+09       1    5.96e-06    2.67e-03
    392       13  1.791438e-14    2.69e-13    2.91e-10   3.01e-04   9.37e-01  1.59e+10       1    7.15e-06    2.69e-03
    393 
    394     Ceres Solver v1.10.0 Solve Report
    395     ----------------------------------
    396                                          Original                  Reduced
    397     Parameter blocks                            4                        4
    398     Parameters                                  4                        4
    399     Residual blocks                             4                        4
    400     Residual                                    4                        4
    401 
    402     Minimizer                        TRUST_REGION
    403 
    404     Dense linear algebra library            EIGEN
    405     Trust region strategy     LEVENBERG_MARQUARDT
    406 
    407                                             Given                     Used
    408     Linear solver                        DENSE_QR                 DENSE_QR
    409     Threads                                     1                        1
    410     Linear solver threads                       1                        1
    411 
    412     Cost:
    413     Initial                          1.075000e+02
    414     Final                            1.791438e-14
    415     Change                           1.075000e+02
    416 
    417     Minimizer iterations                       14
    418     Successful steps                           14
    419     Unsuccessful steps                          0
    420 
    421     Time (in seconds):
    422     Preprocessor                            0.002
    423 
    424       Residual evaluation                   0.000
    425       Jacobian evaluation                   0.000
    426       Linear solver                         0.000
    427     Minimizer                               0.001
    428 
    429     Postprocessor                           0.000
    430     Total                                   0.005
    431 
    432     Termination:                      CONVERGENCE (Gradient tolerance reached. Gradient max norm: 3.642190e-11 <= 1.000000e-10)
    433 
    434     Final x1 = 0.000292189, x2 = -2.92189e-05, x3 = 4.79511e-05, x4 = 4.79511e-05
    435 
    436 It is easy to see that the optimal solution to this problem is at
    437 :math:`x_1=0, x_2=0, x_3=0, x_4=0` with an objective function value of
    438 :math:`0`. In 10 iterations, Ceres finds a solution with an objective
    439 function value of :math:`4\times 10^{-12}`.
    440 
    441 
    442 .. rubric:: Footnotes
    443 
    444 .. [#f5] `examples/powell.cc
    445    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/powell.cc>`_.
    446 
    447 
    448 .. _section-fitting:
    449 
    450 Curve Fitting
    451 =============
    452 
    453 The examples we have seen until now are simple optimization problems
    454 with no data. The original purpose of least squares and non-linear
    455 least squares analysis was fitting curves to data. It is only
    456 appropriate that we now consider an example of such a problem
    457 [#f6]_. It contains data generated by sampling the curve :math:`y =
    458 e^{0.3x + 0.1}` and adding Gaussian noise with standard deviation
    459 :math:`\sigma = 0.2`. Let us fit some data to the curve
    460 
    461 .. math::  y = e^{mx + c}.
    462 
    463 We begin by defining a templated object to evaluate the
    464 residual. There will be a residual for each observation.
    465 
    466 .. code-block:: c++
    467 
    468  struct ExponentialResidual {
    469    ExponentialResidual(double x, double y)
    470        : x_(x), y_(y) {}
    471 
    472    template <typename T>
    473    bool operator()(const T* const m, const T* const c, T* residual) const {
    474      residual[0] = T(y_) - exp(m[0] * T(x_) + c[0]);
    475      return true;
    476    }
    477 
    478   private:
    479    // Observations for a sample.
    480    const double x_;
    481    const double y_;
    482  };
    483 
    484 Assuming the observations are in a :math:`2n` sized array called
    485 ``data`` the problem construction is a simple matter of creating a
    486 :class:`CostFunction` for every observation.
    487 
    488 
    489 .. code-block:: c++
    490 
    491  double m = 0.0;
    492  double c = 0.0;
    493 
    494  Problem problem;
    495  for (int i = 0; i < kNumObservations; ++i) {
    496    CostFunction* cost_function =
    497         new AutoDiffCostFunction<ExponentialResidual, 1, 1, 1>(
    498             new ExponentialResidual(data[2 * i], data[2 * i + 1]));
    499    problem.AddResidualBlock(cost_function, NULL, &m, &c);
    500  }
    501 
    502 Compiling and running `examples/curve_fitting.cc
    503 <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/curve_fitting.cc>`_
    504 gives us:
    505 
    506 .. code-block:: bash
    507 
    508     iter      cost      cost_change  |gradient|   |step|    tr_ratio  tr_radius  ls_iter  iter_time  total_time
    509        0  1.211734e+02    0.00e+00    3.61e+02   0.00e+00   0.00e+00  1.00e+04       0    5.34e-04    2.56e-03
    510        1  1.211734e+02   -2.21e+03    0.00e+00   7.52e-01  -1.87e+01  5.00e+03       1    4.29e-05    3.25e-03
    511        2  1.211734e+02   -2.21e+03    0.00e+00   7.51e-01  -1.86e+01  1.25e+03       1    1.10e-05    3.28e-03
    512        3  1.211734e+02   -2.19e+03    0.00e+00   7.48e-01  -1.85e+01  1.56e+02       1    1.41e-05    3.31e-03
    513        4  1.211734e+02   -2.02e+03    0.00e+00   7.22e-01  -1.70e+01  9.77e+00       1    1.00e-05    3.34e-03
    514        5  1.211734e+02   -7.34e+02    0.00e+00   5.78e-01  -6.32e+00  3.05e-01       1    1.00e-05    3.36e-03
    515        6  3.306595e+01    8.81e+01    4.10e+02   3.18e-01   1.37e+00  9.16e-01       1    2.79e-05    3.41e-03
    516        7  6.426770e+00    2.66e+01    1.81e+02   1.29e-01   1.10e+00  2.75e+00       1    2.10e-05    3.45e-03
    517        8  3.344546e+00    3.08e+00    5.51e+01   3.05e-02   1.03e+00  8.24e+00       1    2.10e-05    3.48e-03
    518        9  1.987485e+00    1.36e+00    2.33e+01   8.87e-02   9.94e-01  2.47e+01       1    2.10e-05    3.52e-03
    519       10  1.211585e+00    7.76e-01    8.22e+00   1.05e-01   9.89e-01  7.42e+01       1    2.10e-05    3.56e-03
    520       11  1.063265e+00    1.48e-01    1.44e+00   6.06e-02   9.97e-01  2.22e+02       1    2.60e-05    3.61e-03
    521       12  1.056795e+00    6.47e-03    1.18e-01   1.47e-02   1.00e+00  6.67e+02       1    2.10e-05    3.64e-03
    522       13  1.056751e+00    4.39e-05    3.79e-03   1.28e-03   1.00e+00  2.00e+03       1    2.10e-05    3.68e-03
    523     Ceres Solver Report: Iterations: 13, Initial cost: 1.211734e+02, Final cost: 1.056751e+00, Termination: CONVERGENCE
    524     Initial m: 0 c: 0
    525     Final   m: 0.291861 c: 0.131439
    526 
    527 Starting from parameter values :math:`m = 0, c=0` with an initial
    528 objective function value of :math:`121.173` Ceres finds a solution
    529 :math:`m= 0.291861, c = 0.131439` with an objective function value of
    530 :math:`1.05675`. These values are a a bit different than the
    531 parameters of the original model :math:`m=0.3, c= 0.1`, but this is
    532 expected. When reconstructing a curve from noisy data, we expect to
    533 see such deviations. Indeed, if you were to evaluate the objective
    534 function for :math:`m=0.3, c=0.1`, the fit is worse with an objective
    535 function value of :math:`1.082425`.  The figure below illustrates the fit.
    536 
    537 .. figure:: least_squares_fit.png
    538    :figwidth: 500px
    539    :height: 400px
    540    :align: center
    541 
    542    Least squares curve fitting.
    543 
    544 
    545 .. rubric:: Footnotes
    546 
    547 .. [#f6] `examples/curve_fitting.cc
    548    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/curve_fitting.cc>`_
    549 
    550 
    551 Robust Curve Fitting
    552 =====================
    553 
    554 Now suppose the data we are given has some outliers, i.e., we have
    555 some points that do not obey the noise model. If we were to use the
    556 code above to fit such data, we would get a fit that looks as
    557 below. Notice how the fitted curve deviates from the ground truth.
    558 
    559 .. figure:: non_robust_least_squares_fit.png
    560    :figwidth: 500px
    561    :height: 400px
    562    :align: center
    563 
    564 To deal with outliers, a standard technique is to use a
    565 :class:`LossFunction`. Loss functions, reduce the influence of
    566 residual blocks with high residuals, usually the ones corresponding to
    567 outliers. To associate a loss function in a residual block, we change
    568 
    569 .. code-block:: c++
    570 
    571    problem.AddResidualBlock(cost_function, NULL , &m, &c);
    572 
    573 to
    574 
    575 .. code-block:: c++
    576 
    577    problem.AddResidualBlock(cost_function, new CauchyLoss(0.5) , &m, &c);
    578 
    579 :class:`CauchyLoss` is one of the loss functions that ships with Ceres
    580 Solver. The argument :math:`0.5` specifies the scale of the loss
    581 function. As a result, we get the fit below [#f7]_. Notice how the
    582 fitted curve moves back closer to the ground truth curve.
    583 
    584 .. figure:: robust_least_squares_fit.png
    585    :figwidth: 500px
    586    :height: 400px
    587    :align: center
    588 
    589    Using :class:`LossFunction` to reduce the effect of outliers on a
    590    least squares fit.
    591 
    592 
    593 .. rubric:: Footnotes
    594 
    595 .. [#f7] `examples/robust_curve_fitting.cc
    596    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/robust_curve_fitting.cc>`_
    597 
    598 
    599 Bundle Adjustment
    600 =================
    601 
    602 One of the main reasons for writing Ceres was our need to solve large
    603 scale bundle adjustment problems [HartleyZisserman]_, [Triggs]_.
    604 
    605 Given a set of measured image feature locations and correspondences,
    606 the goal of bundle adjustment is to find 3D point positions and camera
    607 parameters that minimize the reprojection error. This optimization
    608 problem is usually formulated as a non-linear least squares problem,
    609 where the error is the squared :math:`L_2` norm of the difference between
    610 the observed feature location and the projection of the corresponding
    611 3D point on the image plane of the camera. Ceres has extensive support
    612 for solving bundle adjustment problems.
    613 
    614 Let us solve a problem from the `BAL
    615 <http://grail.cs.washington.edu/projects/bal/>`_ dataset [#f8]_.
    616 
    617 The first step as usual is to define a templated functor that computes
    618 the reprojection error/residual. The structure of the functor is
    619 similar to the ``ExponentialResidual``, in that there is an
    620 instance of this object responsible for each image observation.
    621 
    622 Each residual in a BAL problem depends on a three dimensional point
    623 and a nine parameter camera. The nine parameters defining the camera
    624 are: three for rotation as a Rodriques' axis-angle vector, three
    625 for translation, one for focal length and two for radial distortion.
    626 The details of this camera model can be found the `Bundler homepage
    627 <http://phototour.cs.washington.edu/bundler/>`_ and the `BAL homepage
    628 <http://grail.cs.washington.edu/projects/bal/>`_.
    629 
    630 .. code-block:: c++
    631 
    632  struct SnavelyReprojectionError {
    633    SnavelyReprojectionError(double observed_x, double observed_y)
    634        : observed_x(observed_x), observed_y(observed_y) {}
    635 
    636    template <typename T>
    637    bool operator()(const T* const camera,
    638                    const T* const point,
    639                    T* residuals) const {
    640      // camera[0,1,2] are the angle-axis rotation.
    641      T p[3];
    642      ceres::AngleAxisRotatePoint(camera, point, p);
    643      // camera[3,4,5] are the translation.
    644      p[0] += camera[3]; p[1] += camera[4]; p[2] += camera[5];
    645 
    646      // Compute the center of distortion. The sign change comes from
    647      // the camera model that Noah Snavely's Bundler assumes, whereby
    648      // the camera coordinate system has a negative z axis.
    649      T xp = - p[0] / p[2];
    650      T yp = - p[1] / p[2];
    651 
    652      // Apply second and fourth order radial distortion.
    653      const T& l1 = camera[7];
    654      const T& l2 = camera[8];
    655      T r2 = xp*xp + yp*yp;
    656      T distortion = T(1.0) + r2  * (l1 + l2  * r2);
    657 
    658      // Compute final projected point position.
    659      const T& focal = camera[6];
    660      T predicted_x = focal * distortion * xp;
    661      T predicted_y = focal * distortion * yp;
    662 
    663      // The error is the difference between the predicted and observed position.
    664      residuals[0] = predicted_x - T(observed_x);
    665      residuals[1] = predicted_y - T(observed_y);
    666      return true;
    667    }
    668 
    669     // Factory to hide the construction of the CostFunction object from
    670     // the client code.
    671     static ceres::CostFunction* Create(const double observed_x,
    672                                        const double observed_y) {
    673       return (new ceres::AutoDiffCostFunction<SnavelyReprojectionError, 2, 9, 3>(
    674                   new SnavelyReprojectionError(observed_x, observed_y)));
    675     }
    676 
    677    double observed_x;
    678    double observed_y;
    679  };
    680 
    681 
    682 Note that unlike the examples before, this is a non-trivial function
    683 and computing its analytic Jacobian is a bit of a pain. Automatic
    684 differentiation makes life much simpler. The function
    685 :func:`AngleAxisRotatePoint` and other functions for manipulating
    686 rotations can be found in ``include/ceres/rotation.h``.
    687 
    688 Given this functor, the bundle adjustment problem can be constructed
    689 as follows:
    690 
    691 .. code-block:: c++
    692 
    693  ceres::Problem problem;
    694  for (int i = 0; i < bal_problem.num_observations(); ++i) {
    695    ceres::CostFunction* cost_function =
    696        SnavelyReprojectionError::Create(
    697             bal_problem.observations()[2 * i + 0],
    698             bal_problem.observations()[2 * i + 1]);
    699    problem.AddResidualBlock(cost_function,
    700                             NULL /* squared loss */,
    701                             bal_problem.mutable_camera_for_observation(i),
    702                             bal_problem.mutable_point_for_observation(i));
    703  }
    704 
    705 
    706 Notice that the problem construction for bundle adjustment is very
    707 similar to the curve fitting example -- one term is added to the
    708 objective function per observation.
    709 
    710 Since this large sparse problem (well large for ``DENSE_QR`` anyways),
    711 one way to solve this problem is to set
    712 :member:`Solver::Options::linear_solver_type` to
    713 ``SPARSE_NORMAL_CHOLESKY`` and call :member:`Solve`. And while this is
    714 a reasonable thing to do, bundle adjustment problems have a special
    715 sparsity structure that can be exploited to solve them much more
    716 efficiently. Ceres provides three specialized solvers (collectively
    717 known as Schur-based solvers) for this task. The example code uses the
    718 simplest of them ``DENSE_SCHUR``.
    719 
    720 .. code-block:: c++
    721 
    722  ceres::Solver::Options options;
    723  options.linear_solver_type = ceres::DENSE_SCHUR;
    724  options.minimizer_progress_to_stdout = true;
    725  ceres::Solver::Summary summary;
    726  ceres::Solve(options, &problem, &summary);
    727  std::cout << summary.FullReport() << "\n";
    728 
    729 For a more sophisticated bundle adjustment example which demonstrates
    730 the use of Ceres' more advanced features including its various linear
    731 solvers, robust loss functions and local parameterizations see
    732 `examples/bundle_adjuster.cc
    733 <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/bundle_adjuster.cc>`_
    734 
    735 
    736 .. rubric:: Footnotes
    737 
    738 .. [#f8] `examples/simple_bundle_adjuster.cc
    739    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/simple_bundle_adjuster.cc>`_
    740 
    741 
    742 Other Examples
    743 ==============
    744 
    745 Besides the examples in this chapter, the  `example
    746 <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/>`_
    747 directory contains a number of other examples:
    748 
    749 #. `bundle_adjuster.cc
    750    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/bundle_adjuster.cc>`_
    751    shows how to use the various features of Ceres to solve bundle
    752    adjustment problems.
    753 
    754 #. `circle_fit.cc
    755    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/circle_fit.cc>`_
    756    shows how to fit data to a circle.
    757 
    758 #. `denoising.cc
    759    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/denoising.cc>`_
    760    implements image denoising using the `Fields of Experts
    761    <http://www.gris.informatik.tu-darmstadt.de/~sroth/research/foe/index.html>`_
    762    model.
    763 
    764 #. `nist.cc
    765    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/nist.cc>`_
    766    implements and attempts to solves the `NIST
    767    <http://www.itl.nist.gov/div898/strd/nls/nls_main.shtm>`_
    768    non-linear regression problems.
    769 
    770 #. `libmv_bundle_adjuster.cc
    771    <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/libmv_bundle_adjuster.cc>`_
    772    is the bundle adjustment algorithm used by `Blender <www.blender.org>`_/libmv.
    773