10ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Ceres Solver - A fast non-linear least squares minimizer
20ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
30ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// http://code.google.com/p/ceres-solver/
40ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
50ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Redistribution and use in source and binary forms, with or without
60ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// modification, are permitted provided that the following conditions are met:
70ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
80ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions of source code must retain the above copyright notice,
90ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   this list of conditions and the following disclaimer.
100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions in binary form must reproduce the above copyright notice,
110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   this list of conditions and the following disclaimer in the documentation
120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   and/or other materials provided with the distribution.
130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Neither the name of Google Inc. nor the names of its contributors may be
140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   used to endorse or promote products derived from this software without
150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   specific prior written permission.
160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// POSSIBILITY OF SUCH DAMAGE.
280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Author: keir@google.com (Keir Mierle)
300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Computation of the Jacobian matrix for vector-valued functions of multiple
320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// variables, using automatic differentiation based on the implementation of
330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// dual numbers in jet.h. Before reading the rest of this file, it is adivsable
340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// to read jet.h's header comment in detail.
350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// The helper wrapper AutoDiff::Differentiate() computes the jacobian of
370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// functors with templated operator() taking this form:
380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   struct F {
400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//     template<typename T>
411d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//     bool operator()(const T *x, const T *y, ..., T *z) {
420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//       // Compute z[] based on x[], y[], ...
430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//       // return true if computation succeeded, false otherwise.
440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//     }
450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   };
460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// All inputs and outputs may be vector-valued.
480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// To understand how jets are used to compute the jacobian, a
500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// picture may help. Consider a vector-valued function, F, returning 3
510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// dimensions and taking a vector-valued parameter of 4 dimensions:
520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//     y            x
540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   [ * ]    F   [ * ]
550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   [ * ]  <---  [ * ]
560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   [ * ]        [ * ]
570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//                [ * ]
580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Similar to the 2-parameter example for f described in jet.h, computing the
600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// jacobian dy/dx is done by substutiting a suitable jet object for x and all
610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// intermediate steps of the computation of F. Since x is has 4 dimensions, use
620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// a Jet<double, 4>.
630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Before substituting a jet object for x, the dual components are set
650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// appropriately for each dimension of x:
660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//          y                       x
680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   [ * | * * * * ]    f   [ * | 1 0 0 0 ]   x0
690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   [ * | * * * * ]  <---  [ * | 0 1 0 0 ]   x1
700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   [ * | * * * * ]        [ * | 0 0 1 0 ]   x2
710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//         ---+---          [ * | 0 0 0 1 ]   x3
720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//            |                   ^ ^ ^ ^
730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//          dy/dx                 | | | +----- infinitesimal for x3
740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//                                | | +------- infinitesimal for x2
750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//                                | +--------- infinitesimal for x1
760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//                                +----------- infinitesimal for x0
770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// The reason to set the internal 4x4 submatrix to the identity is that we wish
790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// to take the derivative of y separately with respect to each dimension of x.
800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Each column of the 4x4 identity is therefore for a single component of the
810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// independent variable x.
820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Then the jacobian of the mapping, dy/dx, is the 3x4 sub-matrix of the
840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// extended y vector, indicated in the above diagram.
850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Functors with multiple parameters
870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ---------------------------------
880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// In practice, it is often convenient to use a function f of two or more
890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// vector-valued parameters, for example, x[3] and z[6]. Unfortunately, the jet
900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// framework is designed for a single-parameter vector-valued input. The wrapper
910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// in this file addresses this issue adding support for functions with one or
920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// more parameter vectors.
930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// To support multiple parameters, all the parameter vectors are concatenated
950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// into one and treated as a single parameter vector, except that since the
960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// functor expects different inputs, we need to construct the jets as if they
970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// were part of a single parameter vector. The extended jets are passed
980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// separately for each parameter.
990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
1000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// For example, consider a functor F taking two vector parameters, p[2] and
1010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// q[3], and producing an output y[4]:
1020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
1030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   struct F {
1040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//     template<typename T>
1051d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling//     bool operator()(const T *p, const T *q, T *z) {
1060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//       // ...
1070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//     }
1080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   };
1090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
1100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// In this case, the necessary jet type is Jet<double, 5>. Here is a
1110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// visualization of the jet objects in this case:
1120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
1130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//          Dual components for p ----+
1140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//                                    |
1150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//                                   -+-
1160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//           y                 [ * | 1 0 | 0 0 0 ]    --- p[0]
1170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//                             [ * | 0 1 | 0 0 0 ]    --- p[1]
1180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   [ * | . . | + + + ]         |
1190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   [ * | . . | + + + ]         v
1200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   [ * | . . | + + + ]  <--- F(p, q)
1210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   [ * | . . | + + + ]            ^
1220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//         ^^^   ^^^^^              |
1230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//        dy/dp  dy/dq            [ * | 0 0 | 1 0 0 ] --- q[0]
1240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//                                [ * | 0 0 | 0 1 0 ] --- q[1]
1250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//                                [ * | 0 0 | 0 0 1 ] --- q[2]
1260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//                                            --+--
1270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//                                              |
1280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//          Dual components for q --------------+
1290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
1300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// where the 4x2 submatrix (marked with ".") and 4x3 submatrix (marked with "+"
1310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// of y in the above diagram are the derivatives of y with respect to p and q
1320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// respectively. This is how autodiff works for functors taking multiple vector
1330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// valued arguments (up to 6).
1340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
1350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Jacobian NULL pointers
1360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ----------------------
1370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// In general, the functions below will accept NULL pointers for all or some of
1380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// the Jacobian parameters, meaning that those Jacobians will not be computed.
1390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#ifndef CERES_PUBLIC_INTERNAL_AUTODIFF_H_
1410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#define CERES_PUBLIC_INTERNAL_AUTODIFF_H_
1420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <stddef.h>
1440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/jet.h"
1460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/internal/eigen.h"
1470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/internal/fixed_array.h"
1481d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling#include "ceres/internal/variadic_evaluate.h"
1491d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling#include "glog/logging.h"
1500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace ceres {
1520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace internal {
1530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Extends src by a 1st order pertubation for every dimension and puts it in
1550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// dst. The size of src is N. Since this is also used for perturbations in
1560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// blocked arrays, offset is used to shift which part of the jet the
1570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// perturbation occurs. This is used to set up the extended x augmented by an
1580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// identity matrix. The JetT type should be a Jet type, and T should be a
1590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// numeric type (e.g. double). For example,
1600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
1610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//             0   1 2   3 4 5   6 7 8
1620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   dst[0]  [ * | . . | 1 0 0 | . . . ]
1630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   dst[1]  [ * | . . | 0 1 0 | . . . ]
1640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   dst[2]  [ * | . . | 0 0 1 | . . . ]
1650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
1660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// is what would get put in dst if N was 3, offset was 3, and the jet type JetT
1670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// was 8-dimensional.
1681d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberlingtemplate <typename JetT, typename T, int N>
1691d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberlinginline void Make1stOrderPerturbation(int offset, const T* src, JetT* dst) {
1700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  DCHECK(src);
1710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  DCHECK(dst);
1720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  for (int j = 0; j < N; ++j) {
1731d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    dst[j].a = src[j];
1741d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    dst[j].v.setZero();
17579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    dst[j].v[offset + j] = T(1.0);
1760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  }
1770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
1780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Takes the 0th order part of src, assumed to be a Jet type, and puts it in
1800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// dst. This is used to pick out the "vector" part of the extended y.
1810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate <typename JetT, typename T>
1820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Konginline void Take0thOrderPart(int M, const JetT *src, T dst) {
1830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  DCHECK(src);
1840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  for (int i = 0; i < M; ++i) {
1850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    dst[i] = src[i].a;
1860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  }
1870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
1880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Takes N 1st order parts, starting at index N0, and puts them in the M x N
1900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// matrix 'dst'. This is used to pick out the "matrix" parts of the extended y.
1910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate <typename JetT, typename T, int N0, int N>
1920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Konginline void Take1stOrderPart(const int M, const JetT *src, T *dst) {
1930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  DCHECK(src);
1940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  DCHECK(dst);
1950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  for (int i = 0; i < M; ++i) {
1961d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    Eigen::Map<Eigen::Matrix<T, N, 1> >(dst + N * i, N) =
1971d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling        src[i].v.template segment<N>(N0);
1980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  }
1990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
2000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2011d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// This is in a struct because default template parameters on a
2021d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// function are not supported in C++03 (though it is available in
2031d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// C++0x). N0 through N5 are the dimension of the input arguments to
2041d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling// the user supplied functor.
2050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtemplate <typename Functor, typename T,
2060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0,
2070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          int N5 = 0, int N6 = 0, int N7 = 0, int N8 = 0, int N9 = 0>
2080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongstruct AutoDiff {
2090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  static bool Differentiate(const Functor& functor,
2100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                            T const *const *parameters,
2110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                            int num_outputs,
2120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                            T *function_value,
2130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                            T **jacobians) {
2140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // This block breaks the 80 column rule to keep it somewhat readable.
2150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    DCHECK_GT(num_outputs, 0);
2161d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    DCHECK((!N1 && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
2170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          ((N1 > 0) && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
2180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          ((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
2190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          ((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
2200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5 && !N6 && !N7 && !N8 && !N9) ||
2210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && !N6 && !N7 && !N8 && !N9) ||
2220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && !N7 && !N8 && !N9) ||
2230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && !N8 && !N9) ||
2240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && !N9) ||
2250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong          ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && (N9 > 0)))
2260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        << "Zero block cannot precede a non-zero block. Block sizes are "
2270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        << "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", "
2280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        << N3 << ", " << N4 << ", " << N5 << ", " << N6 << ", " << N7 << ", "
2290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        << N8 << ", " << N9;
2300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    typedef Jet<T, N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9> JetT;
2320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    FixedArray<JetT, (256 * 7) / sizeof(JetT)> x(
2330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9 + num_outputs);
2340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    // These are the positions of the respective jets in the fixed array x.
2360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const int jet0  = 0;
2370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const int jet1  = N0;
2380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const int jet2  = N0 + N1;
2390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const int jet3  = N0 + N1 + N2;
2400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const int jet4  = N0 + N1 + N2 + N3;
2410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const int jet5  = N0 + N1 + N2 + N3 + N4;
2420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const int jet6  = N0 + N1 + N2 + N3 + N4 + N5;
2430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const int jet7  = N0 + N1 + N2 + N3 + N4 + N5 + N6;
2440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const int jet8  = N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7;
2450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const int jet9  = N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8;
2460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    const JetT *unpacked_parameters[10] = {
2480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        x.get() + jet0,
2490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        x.get() + jet1,
2500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        x.get() + jet2,
2510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        x.get() + jet3,
2520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        x.get() + jet4,
2530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        x.get() + jet5,
2540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        x.get() + jet6,
2550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        x.get() + jet7,
2560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        x.get() + jet8,
2570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        x.get() + jet9,
2580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    };
2590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2601d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    JetT* output = x.get() + N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9;
2611d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
2621d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling#define CERES_MAKE_1ST_ORDER_PERTURBATION(i)                            \
2631d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling    if (N ## i) {                                                       \
2641d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling      internal::Make1stOrderPerturbation<JetT, T, N ## i>(              \
2651d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling          jet ## i,                                                     \
2661d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling          parameters[i],                                                \
2671d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling          x.get() + jet ## i);                                          \
2680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
2690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_MAKE_1ST_ORDER_PERTURBATION(0);
2700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_MAKE_1ST_ORDER_PERTURBATION(1);
2710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_MAKE_1ST_ORDER_PERTURBATION(2);
2720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_MAKE_1ST_ORDER_PERTURBATION(3);
2730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_MAKE_1ST_ORDER_PERTURBATION(4);
2740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_MAKE_1ST_ORDER_PERTURBATION(5);
2750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_MAKE_1ST_ORDER_PERTURBATION(6);
2760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_MAKE_1ST_ORDER_PERTURBATION(7);
2770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_MAKE_1ST_ORDER_PERTURBATION(8);
2780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_MAKE_1ST_ORDER_PERTURBATION(9);
2790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#undef CERES_MAKE_1ST_ORDER_PERTURBATION
2800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    if (!VariadicEvaluate<Functor, JetT,
2820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                          N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>::Call(
2830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        functor, unpacked_parameters, output)) {
2840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      return false;
2850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
2860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    internal::Take0thOrderPart(num_outputs, output, function_value);
2880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
2890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#define CERES_TAKE_1ST_ORDER_PERTURBATION(i) \
2900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    if (N ## i) { \
2910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      if (jacobians[i]) { \
2920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong        internal::Take1stOrderPart<JetT, T, \
2930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   jet ## i, \
2940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   N ## i>(num_outputs, \
2950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                           output, \
2960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                           jacobians[i]); \
2970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      } \
2980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
2990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_TAKE_1ST_ORDER_PERTURBATION(0);
3000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_TAKE_1ST_ORDER_PERTURBATION(1);
3010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_TAKE_1ST_ORDER_PERTURBATION(2);
3020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_TAKE_1ST_ORDER_PERTURBATION(3);
3030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_TAKE_1ST_ORDER_PERTURBATION(4);
3040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_TAKE_1ST_ORDER_PERTURBATION(5);
3050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_TAKE_1ST_ORDER_PERTURBATION(6);
3060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_TAKE_1ST_ORDER_PERTURBATION(7);
3070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_TAKE_1ST_ORDER_PERTURBATION(8);
3080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    CERES_TAKE_1ST_ORDER_PERTURBATION(9);
3090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#undef CERES_TAKE_1ST_ORDER_PERTURBATION
3100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    return true;
3110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  }
3120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong};
3130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
3140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}  // namespace internal
3150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}  // namespace ceres
3160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
3170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#endif  // CERES_PUBLIC_INTERNAL_AUTODIFF_H_
318