camenduru commited on
Commit
e905f1d
·
1 Parent(s): 01fbe06

ceres-solver-v2

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +1 -0
  2. ceres-v2/include/autodiff_cost_function.h +228 -0
  3. ceres-v2/include/autodiff_first_order_function.h +151 -0
  4. ceres-v2/include/autodiff_local_parameterization.h +158 -0
  5. ceres-v2/include/autodiff_manifold.h +259 -0
  6. ceres-v2/include/c_api.h +148 -0
  7. ceres-v2/include/ceres.h +74 -0
  8. ceres-v2/include/conditioned_cost_function.h +101 -0
  9. ceres-v2/include/context.h +58 -0
  10. ceres-v2/include/cost_function.h +144 -0
  11. ceres-v2/include/cost_function_to_functor.h +171 -0
  12. ceres-v2/include/covariance.h +459 -0
  13. ceres-v2/include/crs_matrix.h +87 -0
  14. ceres-v2/include/cubic_interpolation.h +436 -0
  15. ceres-v2/include/dynamic_autodiff_cost_function.h +274 -0
  16. ceres-v2/include/dynamic_cost_function.h +57 -0
  17. ceres-v2/include/dynamic_cost_function_to_functor.h +194 -0
  18. ceres-v2/include/dynamic_numeric_diff_cost_function.h +164 -0
  19. ceres-v2/include/evaluation_callback.h +80 -0
  20. ceres-v2/include/first_order_function.h +54 -0
  21. ceres-v2/include/gradient_checker.h +189 -0
  22. ceres-v2/include/gradient_problem.h +185 -0
  23. ceres-v2/include/gradient_problem_solver.h +357 -0
  24. ceres-v2/include/internal/array_selector.h +97 -0
  25. ceres-v2/include/internal/autodiff.h +365 -0
  26. ceres-v2/include/internal/config.h +123 -0
  27. ceres-v2/include/internal/disable_warnings.h +44 -0
  28. ceres-v2/include/internal/eigen.h +75 -0
  29. ceres-v2/include/internal/export.h +42 -0
  30. ceres-v2/include/internal/fixed_array.h +467 -0
  31. ceres-v2/include/internal/householder_vector.h +96 -0
  32. ceres-v2/include/internal/integer_sequence_algorithm.h +291 -0
  33. ceres-v2/include/internal/jet_traits.h +223 -0
  34. ceres-v2/include/internal/line_parameterization.h +183 -0
  35. ceres-v2/include/internal/memory.h +90 -0
  36. ceres-v2/include/internal/numeric_diff.h +508 -0
  37. ceres-v2/include/internal/parameter_dims.h +124 -0
  38. ceres-v2/include/internal/port.h +88 -0
  39. ceres-v2/include/internal/reenable_warnings.h +38 -0
  40. ceres-v2/include/internal/sphere_manifold_functions.h +162 -0
  41. ceres-v2/include/internal/variadic_evaluate.h +113 -0
  42. ceres-v2/include/iteration_callback.h +204 -0
  43. ceres-v2/include/jet.h +1387 -0
  44. ceres-v2/include/jet_fwd.h +44 -0
  45. ceres-v2/include/line_manifold.h +304 -0
  46. ceres-v2/include/local_parameterization.h +371 -0
  47. ceres-v2/include/loss_function.h +433 -0
  48. ceres-v2/include/manifold.h +411 -0
  49. ceres-v2/include/manifold_test_utils.h +328 -0
  50. ceres-v2/include/normal_prior.h +78 -0
.gitattributes CHANGED
@@ -50,3 +50,4 @@ colmap/lib/libpba.a filter=lfs diff=lfs merge=lfs -text
50
  colmap/lib/libpoisson_recon.a filter=lfs diff=lfs merge=lfs -text
51
  colmap/lib/libsift_gpu.a filter=lfs diff=lfs merge=lfs -text
52
  ceres/lib/libceres.a filter=lfs diff=lfs merge=lfs -text
 
 
50
  colmap/lib/libpoisson_recon.a filter=lfs diff=lfs merge=lfs -text
51
  colmap/lib/libsift_gpu.a filter=lfs diff=lfs merge=lfs -text
52
  ceres/lib/libceres.a filter=lfs diff=lfs merge=lfs -text
53
+ ceres-v2/lib/libceres.a filter=lfs diff=lfs merge=lfs -text
ceres-v2/include/autodiff_cost_function.h ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+ //
31
+ // Create CostFunctions as needed by the least squares framework, with
32
+ // Jacobians computed via automatic differentiation. For more
33
+ // information on automatic differentiation, see the wikipedia article
34
+ // at http://en.wikipedia.org/wiki/Automatic_differentiation
35
+ //
36
+ // To get an auto differentiated cost function, you must define a class with a
37
+ // templated operator() (a functor) that computes the cost function in terms of
38
+ // the template parameter T. The autodiff framework substitutes appropriate
39
+ // "jet" objects for T in order to compute the derivative when necessary, but
40
+ // this is hidden, and you should write the function as if T were a scalar type
41
+ // (e.g. a double-precision floating point number).
42
+ //
43
+ // The function must write the computed value in the last argument
44
+ // (the only non-const one) and return true to indicate
45
+ // success. Please see cost_function.h for details on how the return
46
+ // value maybe used to impose simple constraints on the parameter
47
+ // block.
48
+ //
49
+ // For example, consider a scalar error e = k - x'y, where both x and y are
50
+ // two-dimensional column vector parameters, the prime sign indicates
51
+ // transposition, and k is a constant. The form of this error, which is the
52
+ // difference between a constant and an expression, is a common pattern in least
53
+ // squares problems. For example, the value x'y might be the model expectation
54
+ // for a series of measurements, where there is an instance of the cost function
55
+ // for each measurement k.
56
+ //
57
+ // The actual cost added to the total problem is e^2, or (k - x'y)^2; however,
58
+ // the squaring is implicitly done by the optimization framework.
59
+ //
60
+ // To write an auto-differentiable cost function for the above model, first
61
+ // define the object
62
+ //
63
+ // class MyScalarCostFunctor {
64
+ // MyScalarCostFunctor(double k): k_(k) {}
65
+ //
66
+ // template <typename T>
67
+ // bool operator()(const T* const x , const T* const y, T* e) const {
68
+ // e[0] = T(k_) - x[0] * y[0] + x[1] * y[1];
69
+ // return true;
70
+ // }
71
+ //
72
+ // private:
73
+ // double k_;
74
+ // };
75
+ //
76
+ // Note that in the declaration of operator() the input parameters x and y come
77
+ // first, and are passed as const pointers to arrays of T. If there were three
78
+ // input parameters, then the third input parameter would come after y. The
79
+ // output is always the last parameter, and is also a pointer to an array. In
80
+ // the example above, e is a scalar, so only e[0] is set.
81
+ //
82
+ // Then given this class definition, the auto differentiated cost function for
83
+ // it can be constructed as follows.
84
+ //
85
+ // CostFunction* cost_function
86
+ // = new AutoDiffCostFunction<MyScalarCostFunctor, 1, 2, 2>(
87
+ // new MyScalarCostFunctor(1.0)); ^ ^ ^
88
+ // | | |
89
+ // Dimension of residual -----+ | |
90
+ // Dimension of x ---------------+ |
91
+ // Dimension of y ------------------+
92
+ //
93
+ // In this example, there is usually an instance for each measurement of k.
94
+ //
95
+ // In the instantiation above, the template parameters following
96
+ // "MyScalarCostFunctor", "1, 2, 2", describe the functor as computing a
97
+ // 1-dimensional output from two arguments, both 2-dimensional.
98
+ //
99
+ // AutoDiffCostFunction also supports cost functions with a
100
+ // runtime-determined number of residuals. For example:
101
+ //
102
+ // CostFunction* cost_function
103
+ // = new AutoDiffCostFunction<MyScalarCostFunctor, DYNAMIC, 2, 2>(
104
+ // new CostFunctorWithDynamicNumResiduals(1.0), ^ ^ ^
105
+ // runtime_number_of_residuals); <----+ | | |
106
+ // | | | |
107
+ // | | | |
108
+ // Actual number of residuals ------+ | | |
109
+ // Indicate dynamic number of residuals --------+ | |
110
+ // Dimension of x ------------------------------------+ |
111
+ // Dimension of y ---------------------------------------+
112
+ //
113
+ // WARNING #1: Since the functor will get instantiated with different types for
114
+ // T, you must convert from other numeric types to T before mixing
115
+ // computations with other variables of type T. In the example above, this is
116
+ // seen where instead of using k_ directly, k_ is wrapped with T(k_).
117
+ //
118
+ // WARNING #2: A common beginner's error when first using autodiff cost
119
+ // functions is to get the sizing wrong. In particular, there is a tendency to
120
+ // set the template parameters to (dimension of residual, number of parameters)
121
+ // instead of passing a dimension parameter for *every parameter*. In the
122
+ // example above, that would be <MyScalarCostFunctor, 1, 2>, which is missing
123
+ // the last '2' argument. Please be careful when setting the size parameters.
124
+
125
+ #ifndef CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_
126
+ #define CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_
127
+
128
+ #include <memory>
129
+
130
+ #include "ceres/internal/autodiff.h"
131
+ #include "ceres/sized_cost_function.h"
132
+ #include "ceres/types.h"
133
+ #include "glog/logging.h"
134
+
135
+ namespace ceres {
136
+
137
+ // A cost function which computes the derivative of the cost with respect to
138
+ // the parameters (a.k.a. the jacobian) using an auto differentiation framework.
139
+ // The first template argument is the functor object, described in the header
140
+ // comment. The second argument is the dimension of the residual (or
141
+ // ceres::DYNAMIC to indicate it will be set at runtime), and subsequent
142
+ // arguments describe the size of the Nth parameter, one per parameter.
143
+ //
144
+ // The constructors take ownership of the cost functor.
145
+ //
146
+ // If the number of residuals (argument kNumResiduals below) is
147
+ // ceres::DYNAMIC, then the two-argument constructor must be used. The
148
+ // second constructor takes a number of residuals (in addition to the
149
+ // templated number of residuals). This allows for varying the number
150
+ // of residuals for a single autodiff cost function at runtime.
151
+ template <typename CostFunctor,
152
+ int kNumResiduals, // Number of residuals, or ceres::DYNAMIC.
153
+ int... Ns> // Number of parameters in each parameter block.
154
+ class AutoDiffCostFunction final
155
+ : public SizedCostFunction<kNumResiduals, Ns...> {
156
+ public:
157
+ // Takes ownership of functor by default. Uses the template-provided
158
+ // value for the number of residuals ("kNumResiduals").
159
+ explicit AutoDiffCostFunction(CostFunctor* functor,
160
+ Ownership ownership = TAKE_OWNERSHIP)
161
+ : functor_(functor), ownership_(ownership) {
162
+ static_assert(kNumResiduals != DYNAMIC,
163
+ "Can't run the fixed-size constructor if the number of "
164
+ "residuals is set to ceres::DYNAMIC.");
165
+ }
166
+
167
+ // Takes ownership of functor by default. Ignores the template-provided
168
+ // kNumResiduals in favor of the "num_residuals" argument provided.
169
+ //
170
+ // This allows for having autodiff cost functions which return varying
171
+ // numbers of residuals at runtime.
172
+ AutoDiffCostFunction(CostFunctor* functor,
173
+ int num_residuals,
174
+ Ownership ownership = TAKE_OWNERSHIP)
175
+ : functor_(functor), ownership_(ownership) {
176
+ static_assert(kNumResiduals == DYNAMIC,
177
+ "Can't run the dynamic-size constructor if the number of "
178
+ "residuals is not ceres::DYNAMIC.");
179
+ SizedCostFunction<kNumResiduals, Ns...>::set_num_residuals(num_residuals);
180
+ }
181
+
182
+ AutoDiffCostFunction(AutoDiffCostFunction&& other)
183
+ : functor_(std::move(other.functor_)), ownership_(other.ownership_) {}
184
+
185
+ virtual ~AutoDiffCostFunction() {
186
+ // Manually release pointer if configured to not take ownership rather than
187
+ // deleting only if ownership is taken.
188
+ // This is to stay maximally compatible to old user code which may have
189
+ // forgotten to implement a virtual destructor, from when the
190
+ // AutoDiffCostFunction always took ownership.
191
+ if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
192
+ functor_.release();
193
+ }
194
+ }
195
+
196
+ // Implementation details follow; clients of the autodiff cost function should
197
+ // not have to examine below here.
198
+ //
199
+ // To handle variadic cost functions, some template magic is needed. It's
200
+ // mostly hidden inside autodiff.h.
201
+ bool Evaluate(double const* const* parameters,
202
+ double* residuals,
203
+ double** jacobians) const override {
204
+ using ParameterDims =
205
+ typename SizedCostFunction<kNumResiduals, Ns...>::ParameterDims;
206
+
207
+ if (!jacobians) {
208
+ return internal::VariadicEvaluate<ParameterDims>(
209
+ *functor_, parameters, residuals);
210
+ }
211
+ return internal::AutoDifferentiate<kNumResiduals, ParameterDims>(
212
+ *functor_,
213
+ parameters,
214
+ SizedCostFunction<kNumResiduals, Ns...>::num_residuals(),
215
+ residuals,
216
+ jacobians);
217
+ };
218
+
219
+ const CostFunctor& functor() const { return *functor_; }
220
+
221
+ private:
222
+ std::unique_ptr<CostFunctor> functor_;
223
+ Ownership ownership_;
224
+ };
225
+
226
+ } // namespace ceres
227
+
228
+ #endif // CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_
ceres-v2/include/autodiff_first_order_function.h ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #ifndef CERES_PUBLIC_AUTODIFF_FIRST_ORDER_FUNCTION_H_
32
+ #define CERES_PUBLIC_AUTODIFF_FIRST_ORDER_FUNCTION_H_
33
+
34
+ #include <memory>
35
+
36
+ #include "ceres/first_order_function.h"
37
+ #include "ceres/internal/eigen.h"
38
+ #include "ceres/internal/fixed_array.h"
39
+ #include "ceres/jet.h"
40
+ #include "ceres/types.h"
41
+
42
+ namespace ceres {
43
+
44
+ // Create FirstOrderFunctions as needed by the GradientProblem
45
+ // framework, with gradients computed via automatic
46
+ // differentiation. For more information on automatic differentiation,
47
+ // see the wikipedia article at
48
+ // http://en.wikipedia.org/wiki/Automatic_differentiation
49
+ //
50
+ // To get an auto differentiated function, you must define a class
51
+ // with a templated operator() (a functor) that computes the cost
52
+ // function in terms of the template parameter T. The autodiff
53
+ // framework substitutes appropriate "jet" objects for T in order to
54
+ // compute the derivative when necessary, but this is hidden, and you
55
+ // should write the function as if T were a scalar type (e.g. a
56
+ // double-precision floating point number).
57
+ //
58
+ // The function must write the computed value in the last argument
59
+ // (the only non-const one) and return true to indicate
60
+ // success.
61
+ //
62
+ // For example, consider a scalar error e = x'y - a, where both x and y are
63
+ // two-dimensional column vector parameters, the prime sign indicates
64
+ // transposition, and a is a constant.
65
+ //
66
+ // To write an auto-differentiable FirstOrderFunction for the above model, first
67
+ // define the object
68
+ //
69
+ // class QuadraticCostFunctor {
70
+ // public:
71
+ // explicit QuadraticCostFunctor(double a) : a_(a) {}
72
+ // template <typename T>
73
+ // bool operator()(const T* const xy, T* cost) const {
74
+ // const T* const x = xy;
75
+ // const T* const y = xy + 2;
76
+ // *cost = x[0] * y[0] + x[1] * y[1] - T(a_);
77
+ // return true;
78
+ // }
79
+ //
80
+ // private:
81
+ // double a_;
82
+ // };
83
+ //
84
+ // Note that in the declaration of operator() the input parameters xy come
85
+ // first, and are passed as const pointers to arrays of T. The
86
+ // output is the last parameter.
87
+ //
88
+ // Then given this class definition, the auto differentiated FirstOrderFunction
89
+ // for it can be constructed as follows.
90
+ //
91
+ // FirstOrderFunction* function =
92
+ // new AutoDiffFirstOrderFunction<QuadraticCostFunctor, 4>(
93
+ // new QuadraticCostFunctor(1.0)));
94
+ //
95
+ // In the instantiation above, the template parameters following
96
+ // "QuadraticCostFunctor", "4", describe the functor as computing a
97
+ // 1-dimensional output from a four dimensional vector.
98
+ //
99
+ // WARNING: Since the functor will get instantiated with different types for
100
+ // T, you must convert from other numeric types to T before mixing
101
+ // computations with other variables of type T. In the example above, this is
102
+ // seen where instead of using a_ directly, a_ is wrapped with T(a_).
103
+
104
+ template <typename FirstOrderFunctor, int kNumParameters>
105
+ class AutoDiffFirstOrderFunction final : public FirstOrderFunction {
106
+ public:
107
+ // Takes ownership of functor.
108
+ explicit AutoDiffFirstOrderFunction(FirstOrderFunctor* functor)
109
+ : functor_(functor) {
110
+ static_assert(kNumParameters > 0, "kNumParameters must be positive");
111
+ }
112
+
113
+ bool Evaluate(const double* const parameters,
114
+ double* cost,
115
+ double* gradient) const override {
116
+ if (gradient == nullptr) {
117
+ return (*functor_)(parameters, cost);
118
+ }
119
+
120
+ using JetT = Jet<double, kNumParameters>;
121
+ internal::FixedArray<JetT, (256 * 7) / sizeof(JetT)> x(kNumParameters);
122
+ for (int i = 0; i < kNumParameters; ++i) {
123
+ x[i].a = parameters[i];
124
+ x[i].v.setZero();
125
+ x[i].v[i] = 1.0;
126
+ }
127
+
128
+ JetT output;
129
+ output.a = kImpossibleValue;
130
+ output.v.setConstant(kImpossibleValue);
131
+
132
+ if (!(*functor_)(x.data(), &output)) {
133
+ return false;
134
+ }
135
+
136
+ *cost = output.a;
137
+ VectorRef(gradient, kNumParameters) = output.v;
138
+ return true;
139
+ }
140
+
141
+ int NumParameters() const override { return kNumParameters; }
142
+
143
+ const FirstOrderFunctor& functor() const { return *functor_; }
144
+
145
+ private:
146
+ std::unique_ptr<FirstOrderFunctor> functor_;
147
+ };
148
+
149
+ } // namespace ceres
150
+
151
+ #endif // CERES_PUBLIC_AUTODIFF_FIRST_ORDER_FUNCTION_H_
ceres-v2/include/autodiff_local_parameterization.h ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sergey.vfx@gmail.com (Sergey Sharybin)
30
+ // mierle@gmail.com (Keir Mierle)
31
+ // sameeragarwal@google.com (Sameer Agarwal)
32
+
33
+ #ifndef CERES_PUBLIC_AUTODIFF_LOCAL_PARAMETERIZATION_H_
34
+ #define CERES_PUBLIC_AUTODIFF_LOCAL_PARAMETERIZATION_H_
35
+
36
+ #include <memory>
37
+
38
+ #include "ceres/internal/autodiff.h"
39
+ #include "ceres/local_parameterization.h"
40
+
41
+ namespace ceres {
42
+
43
+ // WARNING: LocalParameterizations are deprecated, so is
44
+ // AutoDiffLocalParameterization. They will be removed from Ceres Solver in
45
+ // version 2.2.0. Please use Manifolds and AutoDiffManifold instead.
46
+
47
+ // Create local parameterization with Jacobians computed via automatic
48
+ // differentiation. For more information on local parameterizations,
49
+ // see include/ceres/local_parameterization.h
50
+ //
51
+ // To get an auto differentiated local parameterization, you must define
52
+ // a class with a templated operator() (a functor) that computes
53
+ //
54
+ // x_plus_delta = Plus(x, delta);
55
+ //
56
+ // the template parameter T. The autodiff framework substitutes appropriate
57
+ // "Jet" objects for T in order to compute the derivative when necessary, but
58
+ // this is hidden, and you should write the function as if T were a scalar type
59
+ // (e.g. a double-precision floating point number).
60
+ //
61
+ // The function must write the computed value in the last argument (the only
62
+ // non-const one) and return true to indicate success.
63
+ //
64
+ // For example, Quaternions have a three dimensional local
65
+ // parameterization. It's plus operation can be implemented as (taken
66
+ // from internal/ceres/auto_diff_local_parameterization_test.cc)
67
+ //
68
+ // struct QuaternionPlus {
69
+ // template<typename T>
70
+ // bool operator()(const T* x, const T* delta, T* x_plus_delta) const {
71
+ // const T squared_norm_delta =
72
+ // delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2];
73
+ //
74
+ // T q_delta[4];
75
+ // if (squared_norm_delta > T(0.0)) {
76
+ // T norm_delta = sqrt(squared_norm_delta);
77
+ // const T sin_delta_by_delta = sin(norm_delta) / norm_delta;
78
+ // q_delta[0] = cos(norm_delta);
79
+ // q_delta[1] = sin_delta_by_delta * delta[0];
80
+ // q_delta[2] = sin_delta_by_delta * delta[1];
81
+ // q_delta[3] = sin_delta_by_delta * delta[2];
82
+ // } else {
83
+ // // We do not just use q_delta = [1,0,0,0] here because that is a
84
+ // // constant and when used for automatic differentiation will
85
+ // // lead to a zero derivative. Instead we take a first order
86
+ // // approximation and evaluate it at zero.
87
+ // q_delta[0] = T(1.0);
88
+ // q_delta[1] = delta[0];
89
+ // q_delta[2] = delta[1];
90
+ // q_delta[3] = delta[2];
91
+ // }
92
+ //
93
+ // QuaternionProduct(q_delta, x, x_plus_delta);
94
+ // return true;
95
+ // }
96
+ // };
97
+ //
98
+ // Then given this struct, the auto differentiated local
99
+ // parameterization can now be constructed as
100
+ //
101
+ // LocalParameterization* local_parameterization =
102
+ // new AutoDiffLocalParameterization<QuaternionPlus, 4, 3>;
103
+ // | |
104
+ // Global Size ---------------+ |
105
+ // Local Size -------------------+
106
+ //
107
+ // WARNING: Since the functor will get instantiated with different types for
108
+ // T, you must to convert from other numeric types to T before mixing
109
+ // computations with other variables of type T. In the example above, this is
110
+ // seen where instead of using k_ directly, k_ is wrapped with T(k_).
111
+
112
+ template <typename Functor, int kGlobalSize, int kLocalSize>
113
+ class CERES_DEPRECATED_WITH_MSG("Use AutoDiffManifold instead.")
114
+ AutoDiffLocalParameterization : public LocalParameterization {
115
+ public:
116
+ AutoDiffLocalParameterization() : functor_(new Functor()) {}
117
+
118
+ // Takes ownership of functor.
119
+ explicit AutoDiffLocalParameterization(Functor* functor)
120
+ : functor_(functor) {}
121
+
122
+ bool Plus(const double* x,
123
+ const double* delta,
124
+ double* x_plus_delta) const override {
125
+ return (*functor_)(x, delta, x_plus_delta);
126
+ }
127
+
128
+ bool ComputeJacobian(const double* x, double* jacobian) const override {
129
+ double zero_delta[kLocalSize];
130
+ for (int i = 0; i < kLocalSize; ++i) {
131
+ zero_delta[i] = 0.0;
132
+ }
133
+
134
+ double x_plus_delta[kGlobalSize];
135
+ for (int i = 0; i < kGlobalSize; ++i) {
136
+ x_plus_delta[i] = 0.0;
137
+ }
138
+
139
+ const double* parameter_ptrs[2] = {x, zero_delta};
140
+ double* jacobian_ptrs[2] = {nullptr, jacobian};
141
+ return internal::AutoDifferentiate<
142
+ kGlobalSize,
143
+ internal::StaticParameterDims<kGlobalSize, kLocalSize>>(
144
+ *functor_, parameter_ptrs, kGlobalSize, x_plus_delta, jacobian_ptrs);
145
+ }
146
+
147
+ int GlobalSize() const override { return kGlobalSize; }
148
+ int LocalSize() const override { return kLocalSize; }
149
+
150
+ const Functor& functor() const { return *functor_; }
151
+
152
+ private:
153
+ std::unique_ptr<Functor> functor_;
154
+ };
155
+
156
+ } // namespace ceres
157
+
158
+ #endif // CERES_PUBLIC_AUTODIFF_LOCAL_PARAMETERIZATION_H_
ceres-v2/include/autodiff_manifold.h ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #ifndef CERES_PUBLIC_AUTODIFF_MANIFOLD_H_
32
+ #define CERES_PUBLIC_AUTODIFF_MANIFOLD_H_
33
+
34
+ #include <memory>
35
+
36
+ #include "ceres/internal/autodiff.h"
37
+ #include "ceres/manifold.h"
38
+
39
+ namespace ceres {
40
+
41
+ // Create a Manifold with Jacobians computed via automatic differentiation. For
42
+ // more information on manifolds, see include/ceres/manifold.h
43
+ //
44
+ // To get an auto differentiated manifold, you must define a class/struct with
45
+ // templated Plus and Minus functions that compute
46
+ //
47
+ // x_plus_delta = Plus(x, delta);
48
+ // y_minus_x = Minus(y, x);
49
+ //
50
+ // Where, x, y and x_plus_y are vectors on the manifold in the ambient space (so
51
+ // they are kAmbientSize vectors) and delta, y_minus_x are vectors in the
52
+ // tangent space (so they are kTangentSize vectors).
53
+ //
54
+ // The Functor should have the signature:
55
+ //
56
+ // struct Functor {
57
+ // template <typename T>
58
+ // bool Plus(const T* x, const T* delta, T* x_plus_delta) const;
59
+ //
60
+ // template <typename T>
61
+ // bool Minus(const T* y, const T* x, T* y_minus_x) const;
62
+ // };
63
+ //
64
+ // Observe that the Plus and Minus operations are templated on the parameter T.
65
+ // The autodiff framework substitutes appropriate "Jet" objects for T in order
66
+ // to compute the derivative when necessary. This is the same mechanism that is
67
+ // used to compute derivatives when using AutoDiffCostFunction.
68
+ //
69
+ // Plus and Minus should return true if the computation is successful and false
70
+ // otherwise, in which case the result will not be used.
71
+ //
72
+ // Given this Functor, the corresponding Manifold can be constructed as:
73
+ //
74
+ // AutoDiffManifold<Functor, kAmbientSize, kTangentSize> manifold;
75
+ //
76
+ // As a concrete example consider the case of Quaternions. Quaternions form a
77
+ // three dimensional manifold embedded in R^4, i.e. they have an ambient
78
+ // dimension of 4 and their tangent space has dimension 3. The following Functor
79
+ // (taken from autodiff_manifold_test.cc) defines the Plus and Minus operations
80
+ // on the Quaternion manifold:
81
+ //
82
+ // NOTE: The following is only used for illustration purposes. Ceres Solver
83
+ // ships with optimized production grade QuaternionManifold implementation. See
84
+ // manifold.h.
85
+ //
86
+ // This functor assumes that the quaternions are laid out as [w,x,y,z] in
87
+ // memory, i.e. the real or scalar part is the first coordinate.
88
+ //
89
+ // struct QuaternionFunctor {
90
+ // template <typename T>
91
+ // bool Plus(const T* x, const T* delta, T* x_plus_delta) const {
92
+ // const T squared_norm_delta =
93
+ // delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2];
94
+ //
95
+ // T q_delta[4];
96
+ // if (squared_norm_delta > T(0.0)) {
97
+ // T norm_delta = sqrt(squared_norm_delta);
98
+ // const T sin_delta_by_delta = sin(norm_delta) / norm_delta;
99
+ // q_delta[0] = cos(norm_delta);
100
+ // q_delta[1] = sin_delta_by_delta * delta[0];
101
+ // q_delta[2] = sin_delta_by_delta * delta[1];
102
+ // q_delta[3] = sin_delta_by_delta * delta[2];
103
+ // } else {
104
+ // // We do not just use q_delta = [1,0,0,0] here because that is a
105
+ // // constant and when used for automatic differentiation will
106
+ // // lead to a zero derivative. Instead we take a first order
107
+ // // approximation and evaluate it at zero.
108
+ // q_delta[0] = T(1.0);
109
+ // q_delta[1] = delta[0];
110
+ // q_delta[2] = delta[1];
111
+ // q_delta[3] = delta[2];
112
+ // }
113
+ //
114
+ // QuaternionProduct(q_delta, x, x_plus_delta);
115
+ // return true;
116
+ // }
117
+ //
118
+ // template <typename T>
119
+ // bool Minus(const T* y, const T* x, T* y_minus_x) const {
120
+ // T minus_x[4] = {x[0], -x[1], -x[2], -x[3]};
121
+ // T ambient_y_minus_x[4];
122
+ // QuaternionProduct(y, minus_x, ambient_y_minus_x);
123
+ // T u_norm = sqrt(ambient_y_minus_x[1] * ambient_y_minus_x[1] +
124
+ // ambient_y_minus_x[2] * ambient_y_minus_x[2] +
125
+ // ambient_y_minus_x[3] * ambient_y_minus_x[3]);
126
+ // if (u_norm > 0.0) {
127
+ // T theta = atan2(u_norm, ambient_y_minus_x[0]);
128
+ // y_minus_x[0] = theta * ambient_y_minus_x[1] / u_norm;
129
+ // y_minus_x[1] = theta * ambient_y_minus_x[2] / u_norm;
130
+ // y_minus_x[2] = theta * ambient_y_minus_x[3] / u_norm;
131
+ // } else {
132
+ // // We do not use [0,0,0] here because even though the value part is
133
+ // // a constant, the derivative part is not.
134
+ // y_minus_x[0] = ambient_y_minus_x[1];
135
+ // y_minus_x[1] = ambient_y_minus_x[2];
136
+ // y_minus_x[2] = ambient_y_minus_x[3];
137
+ // }
138
+ // return true;
139
+ // }
140
+ // };
141
+ //
142
+ // Then given this struct, the auto differentiated Quaternion Manifold can now
143
+ // be constructed as
144
+ //
145
+ // Manifold* manifold = new AutoDiffManifold<QuaternionFunctor, 4, 3>;
146
+
147
+ template <typename Functor, int kAmbientSize, int kTangentSize>
148
+ class AutoDiffManifold final : public Manifold {
149
+ public:
150
+ AutoDiffManifold() : functor_(std::make_unique<Functor>()) {}
151
+
152
+ // Takes ownership of functor.
153
+ explicit AutoDiffManifold(Functor* functor) : functor_(functor) {}
154
+
155
+ int AmbientSize() const override { return kAmbientSize; }
156
+ int TangentSize() const override { return kTangentSize; }
157
+
158
+ bool Plus(const double* x,
159
+ const double* delta,
160
+ double* x_plus_delta) const override {
161
+ return functor_->Plus(x, delta, x_plus_delta);
162
+ }
163
+
164
+ bool PlusJacobian(const double* x, double* jacobian) const override;
165
+
166
+ bool Minus(const double* y,
167
+ const double* x,
168
+ double* y_minus_x) const override {
169
+ return functor_->Minus(y, x, y_minus_x);
170
+ }
171
+
172
+ bool MinusJacobian(const double* x, double* jacobian) const override;
173
+
174
+ const Functor& functor() const { return *functor_; }
175
+
176
+ private:
177
+ std::unique_ptr<Functor> functor_;
178
+ };
179
+
180
+ namespace internal {
181
+
182
+ // The following two helper structs are needed to interface the Plus and Minus
183
+ // methods of the ManifoldFunctor with the automatic differentiation which
184
+ // expects a Functor with operator().
185
+ template <typename Functor>
186
+ struct PlusWrapper {
187
+ explicit PlusWrapper(const Functor& functor) : functor(functor) {}
188
+ template <typename T>
189
+ bool operator()(const T* x, const T* delta, T* x_plus_delta) const {
190
+ return functor.Plus(x, delta, x_plus_delta);
191
+ }
192
+ const Functor& functor;
193
+ };
194
+
195
+ template <typename Functor>
196
+ struct MinusWrapper {
197
+ explicit MinusWrapper(const Functor& functor) : functor(functor) {}
198
+ template <typename T>
199
+ bool operator()(const T* y, const T* x, T* y_minus_x) const {
200
+ return functor.Minus(y, x, y_minus_x);
201
+ }
202
+ const Functor& functor;
203
+ };
204
+ } // namespace internal
205
+
206
+ template <typename Functor, int kAmbientSize, int kTangentSize>
207
+ bool AutoDiffManifold<Functor, kAmbientSize, kTangentSize>::PlusJacobian(
208
+ const double* x, double* jacobian) const {
209
+ double zero_delta[kTangentSize];
210
+ for (int i = 0; i < kTangentSize; ++i) {
211
+ zero_delta[i] = 0.0;
212
+ }
213
+
214
+ double x_plus_delta[kAmbientSize];
215
+ for (int i = 0; i < kAmbientSize; ++i) {
216
+ x_plus_delta[i] = 0.0;
217
+ }
218
+
219
+ const double* parameter_ptrs[2] = {x, zero_delta};
220
+
221
+ // PlusJacobian is D_2 Plus(x,0) so we only need to compute the Jacobian
222
+ // w.r.t. the second argument.
223
+ double* jacobian_ptrs[2] = {nullptr, jacobian};
224
+ return internal::AutoDifferentiate<
225
+ kAmbientSize,
226
+ internal::StaticParameterDims<kAmbientSize, kTangentSize>>(
227
+ internal::PlusWrapper<Functor>(*functor_),
228
+ parameter_ptrs,
229
+ kAmbientSize,
230
+ x_plus_delta,
231
+ jacobian_ptrs);
232
+ }
233
+
234
+ template <typename Functor, int kAmbientSize, int kTangentSize>
235
+ bool AutoDiffManifold<Functor, kAmbientSize, kTangentSize>::MinusJacobian(
236
+ const double* x, double* jacobian) const {
237
+ double y_minus_x[kTangentSize];
238
+ for (int i = 0; i < kTangentSize; ++i) {
239
+ y_minus_x[i] = 0.0;
240
+ }
241
+
242
+ const double* parameter_ptrs[2] = {x, x};
243
+
244
+ // MinusJacobian is D_1 Minus(x,x), so we only need to compute the Jacobian
245
+ // w.r.t. the first argument.
246
+ double* jacobian_ptrs[2] = {jacobian, nullptr};
247
+ return internal::AutoDifferentiate<
248
+ kTangentSize,
249
+ internal::StaticParameterDims<kAmbientSize, kAmbientSize>>(
250
+ internal::MinusWrapper<Functor>(*functor_),
251
+ parameter_ptrs,
252
+ kTangentSize,
253
+ y_minus_x,
254
+ jacobian_ptrs);
255
+ }
256
+
257
+ } // namespace ceres
258
+
259
+ #endif // CERES_PUBLIC_AUTODIFF_MANIFOLD_H_
ceres-v2/include/c_api.h ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Ceres Solver - A fast non-linear least squares minimizer
2
+ * Copyright 2019 Google Inc. All rights reserved.
3
+ * http://ceres-solver.org/
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ *
8
+ * - Redistributions of source code must retain the above copyright notice,
9
+ * this list of conditions and the following disclaimer.
10
+ * - Redistributions in binary form must reproduce the above copyright notice,
11
+ * this list of conditions and the following disclaimer in the documentation
12
+ * and/or other materials provided with the distribution.
13
+ * - Neither the name of Google Inc. nor the names of its contributors may be
14
+ * used to endorse or promote products derived from this software without
15
+ * specific prior written permission.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ * POSSIBILITY OF SUCH DAMAGE.
28
+ *
29
+ * Author: mierle@gmail.com (Keir Mierle)
30
+ *
31
+ * A minimal C API for Ceres. Not all functionality is included. This API is
32
+ * not intended for clients of Ceres, but is instead intended for easing the
33
+ * process of binding Ceres to other languages.
34
+ *
35
+ * Currently this is a work in progress.
36
+ */
37
+
38
+ #ifndef CERES_PUBLIC_C_API_H_
39
+ #define CERES_PUBLIC_C_API_H_
40
+
41
+ // clang-format off
42
+ #include "ceres/internal/export.h"
43
+ #include "ceres/internal/disable_warnings.h"
44
+ // clang-format on
45
+
46
+ #ifdef __cplusplus
47
+ extern "C" {
48
+ #endif
49
+
50
+ /* Init the Ceres private data. Must be called before anything else. */
51
+ CERES_EXPORT void ceres_init();
52
+
53
+ /* Equivalent to CostFunction::Evaluate() in the C++ API.
54
+ *
55
+ * The user may keep private information inside the opaque user_data object.
56
+ * The pointer here is the same one passed in the ceres_add_residual_block().
57
+ */
58
+ typedef int (*ceres_cost_function_t)(void* user_data,
59
+ double** parameters,
60
+ double* residuals,
61
+ double** jacobians);
62
+
63
+ /* Equivalent to LossFunction::Evaluate() from the C++ API. */
64
+ typedef void (*ceres_loss_function_t)(void* user_data,
65
+ double squared_norm,
66
+ double out[3]);
67
+
68
+ /* Create callback data for Ceres' stock loss functions.
69
+ *
70
+ * Ceres has several loss functions available by default, and these functions
71
+ * expose those to the C API. To use the stock loss functions, call
72
+ * ceres_create_*_loss_data(), which internally creates an instance of one of
73
+ * the stock loss functions (for example ceres::CauchyLoss), and pass the
74
+ * returned "loss_function_data" along with the ceres_stock_loss_function to
75
+ * ceres_add_residual_block().
76
+ *
77
+ * For example:
78
+ *
79
+ * void* cauchy_loss_function_data =
80
+ * ceres_create_cauchy_loss_function_data(1.2, 0.0);
81
+ * ceres_problem_add_residual_block(
82
+ * problem,
83
+ * my_cost_function,
84
+ * my_cost_function_data,
85
+ * ceres_stock_loss_function,
86
+ * cauchy_loss_function_data,
87
+ * 1,
88
+ * 2,
89
+ * parameter_sizes,
90
+ * parameter_pointers);
91
+ * ...
92
+ * ceres_free_stock_loss_function_data(cauchy_loss_function_data);
93
+ *
94
+ * See loss_function.h for the details of each loss function.
95
+ */
96
+ CERES_EXPORT void* ceres_create_huber_loss_function_data(double a);
97
+ CERES_EXPORT void* ceres_create_softl1_loss_function_data(double a);
98
+ CERES_EXPORT void* ceres_create_cauchy_loss_function_data(double a);
99
+ CERES_EXPORT void* ceres_create_arctan_loss_function_data(double a);
100
+ CERES_EXPORT void* ceres_create_tolerant_loss_function_data(double a, double b);
101
+
102
+ /* Free the given stock loss function data. */
103
+ CERES_EXPORT void ceres_free_stock_loss_function_data(void* loss_function_data);
104
+
105
+ /* This is an implementation of ceres_loss_function_t contained within Ceres
106
+ * itself, intended as a way to access the various stock Ceres loss functions
107
+ * from the C API. This should be passed to ceres_add_residual() below, in
108
+ * combination with a user_data pointer generated by
109
+ * ceres_create_stock_loss_function() above. */
110
+ CERES_EXPORT void ceres_stock_loss_function(void* user_data,
111
+ double squared_norm,
112
+ double out[3]);
113
+
114
+ /* Equivalent to Problem from the C++ API. */
115
+ struct ceres_problem_s;
116
+ typedef struct ceres_problem_s ceres_problem_t;
117
+
118
+ struct ceres_residual_block_id_s;
119
+ typedef struct ceres_residual_block_id_s ceres_residual_block_id_t;
120
+
121
+ /* Create and destroy a problem */
122
+ /* TODO(keir): Add options for the problem. */
123
+ CERES_EXPORT ceres_problem_t* ceres_create_problem();
124
+ CERES_EXPORT void ceres_free_problem(ceres_problem_t* problem);
125
+
126
+ /* Add a residual block. */
127
+ CERES_EXPORT ceres_residual_block_id_t* ceres_problem_add_residual_block(
128
+ ceres_problem_t* problem,
129
+ ceres_cost_function_t cost_function,
130
+ void* cost_function_data,
131
+ ceres_loss_function_t loss_function,
132
+ void* loss_function_data,
133
+ int num_residuals,
134
+ int num_parameter_blocks,
135
+ int* parameter_block_sizes,
136
+ double** parameters);
137
+
138
+ CERES_EXPORT void ceres_solve(ceres_problem_t* problem);
139
+
140
+ /* TODO(keir): Figure out a way to pass a config in. */
141
+
142
+ #ifdef __cplusplus
143
+ }
144
+ #endif
145
+
146
+ #include "ceres/internal/reenable_warnings.h"
147
+
148
+ #endif /* CERES_PUBLIC_C_API_H_ */
ceres-v2/include/ceres.h ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: keir@google.com (Keir Mierle)
30
+ //
31
+ // This is a forwarding header containing the public symbols exported from
32
+ // Ceres. Anything in the "ceres" namespace is available for use.
33
+
34
+ #ifndef CERES_PUBLIC_CERES_H_
35
+ #define CERES_PUBLIC_CERES_H_
36
+
37
+ #include "ceres/autodiff_cost_function.h"
38
+ #include "ceres/autodiff_first_order_function.h"
39
+ #include "ceres/autodiff_local_parameterization.h"
40
+ #include "ceres/autodiff_manifold.h"
41
+ #include "ceres/conditioned_cost_function.h"
42
+ #include "ceres/context.h"
43
+ #include "ceres/cost_function.h"
44
+ #include "ceres/cost_function_to_functor.h"
45
+ #include "ceres/covariance.h"
46
+ #include "ceres/crs_matrix.h"
47
+ #include "ceres/dynamic_autodiff_cost_function.h"
48
+ #include "ceres/dynamic_cost_function.h"
49
+ #include "ceres/dynamic_cost_function_to_functor.h"
50
+ #include "ceres/dynamic_numeric_diff_cost_function.h"
51
+ #include "ceres/evaluation_callback.h"
52
+ #include "ceres/first_order_function.h"
53
+ #include "ceres/gradient_checker.h"
54
+ #include "ceres/gradient_problem.h"
55
+ #include "ceres/gradient_problem_solver.h"
56
+ #include "ceres/iteration_callback.h"
57
+ #include "ceres/jet.h"
58
+ #include "ceres/line_manifold.h"
59
+ #include "ceres/local_parameterization.h"
60
+ #include "ceres/loss_function.h"
61
+ #include "ceres/manifold.h"
62
+ #include "ceres/numeric_diff_cost_function.h"
63
+ #include "ceres/numeric_diff_first_order_function.h"
64
+ #include "ceres/numeric_diff_options.h"
65
+ #include "ceres/ordered_groups.h"
66
+ #include "ceres/problem.h"
67
+ #include "ceres/product_manifold.h"
68
+ #include "ceres/sized_cost_function.h"
69
+ #include "ceres/solver.h"
70
+ #include "ceres/sphere_manifold.h"
71
+ #include "ceres/types.h"
72
+ #include "ceres/version.h"
73
+
74
+ #endif // CERES_PUBLIC_CERES_H_
ceres-v2/include/conditioned_cost_function.h ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: wjr@google.com (William Rucklidge)
30
+ //
31
+ // This file contains a cost function that can apply a transformation to
32
+ // each residual value before they are square-summed.
33
+
34
+ #ifndef CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_
35
+ #define CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_
36
+
37
+ #include <memory>
38
+ #include <vector>
39
+
40
+ #include "ceres/cost_function.h"
41
+ #include "ceres/internal/disable_warnings.h"
42
+ #include "ceres/types.h"
43
+
44
+ namespace ceres {
45
+
46
+ // This class allows you to apply different conditioning to the residual
47
+ // values of a wrapped cost function. An example where this is useful is
48
+ // where you have an existing cost function that produces N values, but you
49
+ // want the total cost to be something other than just the sum of these
50
+ // squared values - maybe you want to apply a different scaling to some
51
+ // values, to change their contribution to the cost.
52
+ //
53
+ // Usage:
54
+ //
55
+ // // my_cost_function produces N residuals
56
+ // CostFunction* my_cost_function = ...
57
+ // CHECK_EQ(N, my_cost_function->num_residuals());
58
+ // vector<CostFunction*> conditioners;
59
+ //
60
+ // // Make N 1x1 cost functions (1 parameter, 1 residual)
61
+ // CostFunction* f_1 = ...
62
+ // conditioners.push_back(f_1);
63
+ // ...
64
+ // CostFunction* f_N = ...
65
+ // conditioners.push_back(f_N);
66
+ // ConditionedCostFunction* ccf =
67
+ // new ConditionedCostFunction(my_cost_function, conditioners);
68
+ //
69
+ // Now ccf's residual i (i=0..N-1) will be passed though the i'th conditioner.
70
+ //
71
+ // ccf_residual[i] = f_i(my_cost_function_residual[i])
72
+ //
73
+ // and the Jacobian will be affected appropriately.
74
+ class CERES_EXPORT ConditionedCostFunction final : public CostFunction {
75
+ public:
76
+ // Builds a cost function based on a wrapped cost function, and a
77
+ // per-residual conditioner. Takes ownership of all of the wrapped cost
78
+ // functions, or not, depending on the ownership parameter. Conditioners
79
+ // may be nullptr, in which case the corresponding residual is not modified.
80
+ //
81
+ // The conditioners can repeat.
82
+ ConditionedCostFunction(CostFunction* wrapped_cost_function,
83
+ const std::vector<CostFunction*>& conditioners,
84
+ Ownership ownership);
85
+ ~ConditionedCostFunction() override;
86
+
87
+ bool Evaluate(double const* const* parameters,
88
+ double* residuals,
89
+ double** jacobians) const override;
90
+
91
+ private:
92
+ std::unique_ptr<CostFunction> wrapped_cost_function_;
93
+ std::vector<CostFunction*> conditioners_;
94
+ Ownership ownership_;
95
+ };
96
+
97
+ } // namespace ceres
98
+
99
+ #include "ceres/internal/reenable_warnings.h"
100
+
101
+ #endif // CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_
ceres-v2/include/context.h ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: vitus@google.com (Michael Vitus)
30
+
31
+ #ifndef CERES_PUBLIC_CONTEXT_H_
32
+ #define CERES_PUBLIC_CONTEXT_H_
33
+
34
+ #include "ceres/internal/export.h"
35
+
36
+ namespace ceres {
37
+
38
+ // A global context for processing data in Ceres. This provides a mechanism to
39
+ // allow Ceres to reuse items that are expensive to create between multiple
40
+ // calls; for example, thread pools. The same Context can be used on multiple
41
+ // Problems, either serially or in parallel. When using it with multiple
42
+ // Problems at the same time, they may end up contending for resources
43
+ // (e.g. threads) managed by the Context.
44
+ class CERES_EXPORT Context {
45
+ public:
46
+ Context();
47
+ Context(const Context&) = delete;
48
+ void operator=(const Context&) = delete;
49
+
50
+ virtual ~Context();
51
+
52
+ // Creates a context object and the caller takes ownership.
53
+ static Context* Create();
54
+ };
55
+
56
+ } // namespace ceres
57
+
58
+ #endif // CERES_PUBLIC_CONTEXT_H_
ceres-v2/include/cost_function.h ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+ // keir@google.m (Keir Mierle)
31
+ //
32
+ // This is the interface through which the least squares solver accesses the
33
+ // residual and Jacobian of the least squares problem. Users are expected to
34
+ // subclass CostFunction to define their own terms in the least squares problem.
35
+ //
36
+ // It is recommended that users define templated residual functors for use as
37
+ // arguments for AutoDiffCostFunction (see autodiff_cost_function.h), instead of
38
+ // directly implementing the CostFunction interface. This often results in both
39
+ // shorter code and faster execution than hand-coded derivatives. However,
40
+ // specialized cases may demand direct implementation of the lower-level
41
+ // CostFunction interface; for example, this is true when calling legacy code
42
+ // which is not templated on numeric types.
43
+
44
+ #ifndef CERES_PUBLIC_COST_FUNCTION_H_
45
+ #define CERES_PUBLIC_COST_FUNCTION_H_
46
+
47
+ #include <cstdint>
48
+ #include <vector>
49
+
50
+ #include "ceres/internal/disable_warnings.h"
51
+ #include "ceres/internal/export.h"
52
+
53
+ namespace ceres {
54
+
55
+ // This class implements the computation of the cost (a.k.a. residual) terms as
56
+ // a function of the input (control) variables, and is the interface for users
57
+ // to describe their least squares problem to Ceres. In other words, this is the
58
+ // modeling layer between users and the Ceres optimizer. The signature of the
59
+ // function (number and sizes of input parameter blocks and number of outputs)
60
+ // is stored in parameter_block_sizes_ and num_residuals_ respectively. User
61
+ // code inheriting from this class is expected to set these two members with the
62
+ // corresponding accessors. This information will be verified by the Problem
63
+ // when added with AddResidualBlock().
64
+ class CERES_EXPORT CostFunction {
65
+ public:
66
+ CostFunction();
67
+ CostFunction(const CostFunction&) = delete;
68
+ void operator=(const CostFunction&) = delete;
69
+
70
+ virtual ~CostFunction();
71
+
72
+ // Inputs:
73
+ //
74
+ // parameters is an array of pointers to arrays containing the
75
+ // various parameter blocks. parameters has the same number of
76
+ // elements as parameter_block_sizes_. Parameter blocks are in the
77
+ // same order as parameter_block_sizes_.i.e.,
78
+ //
79
+ // parameters_[i] = double[parameter_block_sizes_[i]]
80
+ //
81
+ // Outputs:
82
+ //
83
+ // residuals is an array of size num_residuals_.
84
+ //
85
+ // jacobians is an array of size parameter_block_sizes_ containing
86
+ // pointers to storage for jacobian blocks corresponding to each
87
+ // parameter block. Jacobian blocks are in the same order as
88
+ // parameter_block_sizes, i.e. jacobians[i], is an
89
+ // array that contains num_residuals_* parameter_block_sizes_[i]
90
+ // elements. Each jacobian block is stored in row-major order, i.e.,
91
+ //
92
+ // jacobians[i][r*parameter_block_size_[i] + c] =
93
+ // d residual[r] / d parameters[i][c]
94
+ //
95
+ // If jacobians is nullptr, then no derivatives are returned; this is
96
+ // the case when computing cost only. If jacobians[i] is nullptr, then
97
+ // the jacobian block corresponding to the i'th parameter block must
98
+ // not to be returned.
99
+ //
100
+ // The return value indicates whether the computation of the
101
+ // residuals and/or jacobians was successful or not.
102
+ //
103
+ // This can be used to communicate numerical failures in jacobian
104
+ // computations for instance.
105
+ //
106
+ // A more interesting and common use is to impose constraints on the
107
+ // parameters. If the initial values of the parameter blocks satisfy
108
+ // the constraints, then returning false whenever the constraints
109
+ // are not satisfied will prevent the solver from moving into the
110
+ // infeasible region. This is not a very sophisticated mechanism for
111
+ // enforcing constraints, but is often good enough.
112
+ //
113
+ // Note that it is important that the initial values of the
114
+ // parameter block must be feasible, otherwise the solver will
115
+ // declare a numerical problem at iteration 0.
116
+ virtual bool Evaluate(double const* const* parameters,
117
+ double* residuals,
118
+ double** jacobians) const = 0;
119
+
120
+ const std::vector<int32_t>& parameter_block_sizes() const {
121
+ return parameter_block_sizes_;
122
+ }
123
+
124
+ int num_residuals() const { return num_residuals_; }
125
+
126
+ protected:
127
+ std::vector<int32_t>* mutable_parameter_block_sizes() {
128
+ return &parameter_block_sizes_;
129
+ }
130
+
131
+ void set_num_residuals(int num_residuals) { num_residuals_ = num_residuals; }
132
+
133
+ private:
134
+ // Cost function signature metadata: number of inputs & their sizes,
135
+ // number of outputs (residuals).
136
+ std::vector<int32_t> parameter_block_sizes_;
137
+ int num_residuals_;
138
+ };
139
+
140
+ } // namespace ceres
141
+
142
+ #include "ceres/internal/reenable_warnings.h"
143
+
144
+ #endif // CERES_PUBLIC_COST_FUNCTION_H_
ceres-v2/include/cost_function_to_functor.h ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+ //
31
+ // CostFunctionToFunctor is an adapter class that allows users to use
32
+ // SizedCostFunction objects in templated functors which are to be used for
33
+ // automatic differentiation. This allows the user to seamlessly mix
34
+ // analytic, numeric and automatic differentiation.
35
+ //
36
+ // For example, let us assume that
37
+ //
38
+ // class IntrinsicProjection : public SizedCostFunction<2, 5, 3> {
39
+ // public:
40
+ // IntrinsicProjection(const double* observation);
41
+ // bool Evaluate(double const* const* parameters,
42
+ // double* residuals,
43
+ // double** jacobians) const override;
44
+ // };
45
+ //
46
+ // is a cost function that implements the projection of a point in its
47
+ // local coordinate system onto its image plane and subtracts it from
48
+ // the observed point projection. It can compute its residual and
49
+ // jacobians either via analytic or numerical differentiation.
50
+ //
51
+ // Now we would like to compose the action of this CostFunction with
52
+ // the action of camera extrinsics, i.e., rotation and
53
+ // translation. Say we have a templated function
54
+ //
55
+ // template<typename T>
56
+ // void RotateAndTranslatePoint(const T* rotation,
57
+ // const T* translation,
58
+ // const T* point,
59
+ // T* result);
60
+ //
61
+ // Then we can now do the following,
62
+ //
63
+ // struct CameraProjection {
64
+ // CameraProjection(const double* observation)
65
+ // : intrinsic_projection_(new IntrinsicProjection(observation)) {
66
+ // }
67
+ // template <typename T>
68
+ // bool operator()(const T* rotation,
69
+ // const T* translation,
70
+ // const T* intrinsics,
71
+ // const T* point,
72
+ // T* residual) const {
73
+ // T transformed_point[3];
74
+ // RotateAndTranslatePoint(rotation, translation, point, transformed_point);
75
+ //
76
+ // // Note that we call intrinsic_projection_, just like it was
77
+ // // any other templated functor.
78
+ //
79
+ // return intrinsic_projection_(intrinsics, transformed_point, residual);
80
+ // }
81
+ //
82
+ // private:
83
+ // CostFunctionToFunctor<2,5,3> intrinsic_projection_;
84
+ // };
85
+
86
+ #ifndef CERES_PUBLIC_COST_FUNCTION_TO_FUNCTOR_H_
87
+ #define CERES_PUBLIC_COST_FUNCTION_TO_FUNCTOR_H_
88
+
89
+ #include <cstdint>
90
+ #include <numeric>
91
+ #include <tuple>
92
+ #include <utility>
93
+ #include <vector>
94
+
95
+ #include "ceres/cost_function.h"
96
+ #include "ceres/dynamic_cost_function_to_functor.h"
97
+ #include "ceres/internal/export.h"
98
+ #include "ceres/internal/fixed_array.h"
99
+ #include "ceres/internal/parameter_dims.h"
100
+ #include "ceres/types.h"
101
+ #include "glog/logging.h"
102
+
103
+ namespace ceres {
104
+
105
+ template <int kNumResiduals, int... Ns>
106
+ class CostFunctionToFunctor {
107
+ public:
108
+ // Takes ownership of cost_function.
109
+ explicit CostFunctionToFunctor(CostFunction* cost_function)
110
+ : cost_functor_(cost_function) {
111
+ CHECK(cost_function != nullptr);
112
+ CHECK(kNumResiduals > 0 || kNumResiduals == DYNAMIC);
113
+
114
+ const std::vector<int32_t>& parameter_block_sizes =
115
+ cost_function->parameter_block_sizes();
116
+ const int num_parameter_blocks = ParameterDims::kNumParameterBlocks;
117
+ CHECK_EQ(static_cast<int>(parameter_block_sizes.size()),
118
+ num_parameter_blocks);
119
+
120
+ if (parameter_block_sizes.size() == num_parameter_blocks) {
121
+ for (int block = 0; block < num_parameter_blocks; ++block) {
122
+ CHECK_EQ(ParameterDims::GetDim(block), parameter_block_sizes[block])
123
+ << "Parameter block size missmatch. The specified static parameter "
124
+ "block dimension does not match the one from the cost function.";
125
+ }
126
+ }
127
+
128
+ CHECK_EQ(accumulate(
129
+ parameter_block_sizes.begin(), parameter_block_sizes.end(), 0),
130
+ ParameterDims::kNumParameters);
131
+ }
132
+
133
+ template <typename T, typename... Ts>
134
+ bool operator()(const T* p1, Ts*... ps) const {
135
+ // Add one because of residual block.
136
+ static_assert(sizeof...(Ts) + 1 == ParameterDims::kNumParameterBlocks + 1,
137
+ "Invalid number of parameter blocks specified.");
138
+
139
+ auto params = std::make_tuple(p1, ps...);
140
+
141
+ // Extract residual pointer from params. The residual pointer is the
142
+ // last pointer.
143
+ constexpr int kResidualIndex = ParameterDims::kNumParameterBlocks;
144
+ T* residuals = std::get<kResidualIndex>(params);
145
+
146
+ // Extract parameter block pointers from params.
147
+ using Indices =
148
+ std::make_integer_sequence<int, ParameterDims::kNumParameterBlocks>;
149
+ std::array<const T*, ParameterDims::kNumParameterBlocks> parameter_blocks =
150
+ GetParameterPointers<T>(params, Indices());
151
+
152
+ return cost_functor_(parameter_blocks.data(), residuals);
153
+ }
154
+
155
+ private:
156
+ using ParameterDims = internal::StaticParameterDims<Ns...>;
157
+
158
+ template <typename T, typename Tuple, int... Indices>
159
+ static std::array<const T*, ParameterDims::kNumParameterBlocks>
160
+ GetParameterPointers(const Tuple& paramPointers,
161
+ std::integer_sequence<int, Indices...>) {
162
+ return std::array<const T*, ParameterDims::kNumParameterBlocks>{
163
+ {std::get<Indices>(paramPointers)...}};
164
+ }
165
+
166
+ DynamicCostFunctionToFunctor cost_functor_;
167
+ };
168
+
169
+ } // namespace ceres
170
+
171
+ #endif // CERES_PUBLIC_COST_FUNCTION_TO_FUNCTOR_H_
ceres-v2/include/covariance.h ADDED
@@ -0,0 +1,459 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #ifndef CERES_PUBLIC_COVARIANCE_H_
32
+ #define CERES_PUBLIC_COVARIANCE_H_
33
+
34
+ #include <memory>
35
+ #include <utility>
36
+ #include <vector>
37
+
38
+ #include "ceres/internal/config.h"
39
+ #include "ceres/internal/disable_warnings.h"
40
+ #include "ceres/internal/export.h"
41
+ #include "ceres/types.h"
42
+
43
+ namespace ceres {
44
+
45
+ class Problem;
46
+
47
+ namespace internal {
48
+ class CovarianceImpl;
49
+ } // namespace internal
50
+
51
+ // WARNING
52
+ // =======
53
+ // It is very easy to use this class incorrectly without understanding
54
+ // the underlying mathematics. Please read and understand the
55
+ // documentation completely before attempting to use it.
56
+ //
57
+ //
58
+ // This class allows the user to evaluate the covariance for a
59
+ // non-linear least squares problem and provides random access to its
60
+ // blocks
61
+ //
62
+ // Background
63
+ // ==========
64
+ // One way to assess the quality of the solution returned by a
65
+ // non-linear least squares solver is to analyze the covariance of the
66
+ // solution.
67
+ //
68
+ // Let us consider the non-linear regression problem
69
+ //
70
+ // y = f(x) + N(0, I)
71
+ //
72
+ // i.e., the observation y is a random non-linear function of the
73
+ // independent variable x with mean f(x) and identity covariance. Then
74
+ // the maximum likelihood estimate of x given observations y is the
75
+ // solution to the non-linear least squares problem:
76
+ //
77
+ // x* = arg min_x |f(x) - y|^2
78
+ //
79
+ // And the covariance of x* is given by
80
+ //
81
+ // C(x*) = inverse[J'(x*)J(x*)]
82
+ //
83
+ // Here J(x*) is the Jacobian of f at x*. The above formula assumes
84
+ // that J(x*) has full column rank.
85
+ //
86
+ // If J(x*) is rank deficient, then the covariance matrix C(x*) is
87
+ // also rank deficient and is given by
88
+ //
89
+ // C(x*) = pseudoinverse[J'(x*)J(x*)]
90
+ //
91
+ // Note that in the above, we assumed that the covariance
92
+ // matrix for y was identity. This is an important assumption. If this
93
+ // is not the case and we have
94
+ //
95
+ // y = f(x) + N(0, S)
96
+ //
97
+ // Where S is a positive semi-definite matrix denoting the covariance
98
+ // of y, then the maximum likelihood problem to be solved is
99
+ //
100
+ // x* = arg min_x f'(x) inverse[S] f(x)
101
+ //
102
+ // and the corresponding covariance estimate of x* is given by
103
+ //
104
+ // C(x*) = inverse[J'(x*) inverse[S] J(x*)]
105
+ //
106
+ // So, if it is the case that the observations being fitted to have a
107
+ // covariance matrix not equal to identity, then it is the user's
108
+ // responsibility that the corresponding cost functions are correctly
109
+ // scaled, e.g. in the above case the cost function for this problem
110
+ // should evaluate S^{-1/2} f(x) instead of just f(x), where S^{-1/2}
111
+ // is the inverse square root of the covariance matrix S.
112
+ //
113
+ // This class allows the user to evaluate the covariance for a
114
+ // non-linear least squares problem and provides random access to its
115
+ // blocks. The computation assumes that the CostFunctions compute
116
+ // residuals such that their covariance is identity.
117
+ //
118
+ // Since the computation of the covariance matrix requires computing
119
+ // the inverse of a potentially large matrix, this can involve a
120
+ // rather large amount of time and memory. However, it is usually the
121
+ // case that the user is only interested in a small part of the
122
+ // covariance matrix. Quite often just the block diagonal. This class
123
+ // allows the user to specify the parts of the covariance matrix that
124
+ // she is interested in and then uses this information to only compute
125
+ // and store those parts of the covariance matrix.
126
+ //
127
+ // Rank of the Jacobian
128
+ // --------------------
129
+ // As we noted above, if the jacobian is rank deficient, then the
130
+ // inverse of J'J is not defined and instead a pseudo inverse needs to
131
+ // be computed.
132
+ //
133
+ // The rank deficiency in J can be structural -- columns which are
134
+ // always known to be zero or numerical -- depending on the exact
135
+ // values in the Jacobian.
136
+ //
137
+ // Structural rank deficiency occurs when the problem contains
138
+ // parameter blocks that are constant. This class correctly handles
139
+ // structural rank deficiency like that.
140
+ //
141
+ // Numerical rank deficiency, where the rank of the matrix cannot be
142
+ // predicted by its sparsity structure and requires looking at its
143
+ // numerical values is more complicated. Here again there are two
144
+ // cases.
145
+ //
146
+ // a. The rank deficiency arises from overparameterization. e.g., a
147
+ // four dimensional quaternion used to parameterize SO(3), which is
148
+ // a three dimensional manifold. In cases like this, the user should
149
+ // use an appropriate LocalParameterization/Manifold. Not only will this lead
150
+ // to better numerical behaviour of the Solver, it will also expose
151
+ // the rank deficiency to the Covariance object so that it can
152
+ // handle it correctly.
153
+ //
154
+ // b. More general numerical rank deficiency in the Jacobian
155
+ // requires the computation of the so called Singular Value
156
+ // Decomposition (SVD) of J'J. We do not know how to do this for
157
+ // large sparse matrices efficiently. For small and moderate sized
158
+ // problems this is done using dense linear algebra.
159
+ //
160
+ // Gauge Invariance
161
+ // ----------------
162
+ // In structure from motion (3D reconstruction) problems, the
163
+ // reconstruction is ambiguous up to a similarity transform. This is
164
+ // known as a Gauge Ambiguity. Handling Gauges correctly requires the
165
+ // use of SVD or custom inversion algorithms. For small problems the
166
+ // user can use the dense algorithm. For more details see
167
+ //
168
+ // Ken-ichi Kanatani, Daniel D. Morris: Gauges and gauge
169
+ // transformations for uncertainty description of geometric structure
170
+ // with indeterminacy. IEEE Transactions on Information Theory 47(5):
171
+ // 2017-2028 (2001)
172
+ //
173
+ // Example Usage
174
+ // =============
175
+ //
176
+ // double x[3];
177
+ // double y[2];
178
+ //
179
+ // Problem problem;
180
+ // problem.AddParameterBlock(x, 3);
181
+ // problem.AddParameterBlock(y, 2);
182
+ // <Build Problem>
183
+ // <Solve Problem>
184
+ //
185
+ // Covariance::Options options;
186
+ // Covariance covariance(options);
187
+ //
188
+ // std::vector<std::pair<const double*, const double*>> covariance_blocks;
189
+ // covariance_blocks.push_back(make_pair(x, x));
190
+ // covariance_blocks.push_back(make_pair(y, y));
191
+ // covariance_blocks.push_back(make_pair(x, y));
192
+ //
193
+ // CHECK(covariance.Compute(covariance_blocks, &problem));
194
+ //
195
+ // double covariance_xx[3 * 3];
196
+ // double covariance_yy[2 * 2];
197
+ // double covariance_xy[3 * 2];
198
+ // covariance.GetCovarianceBlock(x, x, covariance_xx)
199
+ // covariance.GetCovarianceBlock(y, y, covariance_yy)
200
+ // covariance.GetCovarianceBlock(x, y, covariance_xy)
201
+ //
202
+ class CERES_EXPORT Covariance {
203
+ public:
204
+ struct CERES_EXPORT Options {
205
+ // Sparse linear algebra library to use when a sparse matrix
206
+ // factorization is being used to compute the covariance matrix.
207
+ //
208
+ // Currently this only applies to SPARSE_QR.
209
+ SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type =
210
+ #if !defined(CERES_NO_SUITESPARSE)
211
+ SUITE_SPARSE;
212
+ #else
213
+ // Eigen's QR factorization is always available.
214
+ EIGEN_SPARSE;
215
+ #endif
216
+
217
+ // Ceres supports two different algorithms for covariance
218
+ // estimation, which represent different tradeoffs in speed,
219
+ // accuracy and reliability.
220
+ //
221
+ // 1. DENSE_SVD uses Eigen's JacobiSVD to perform the
222
+ // computations. It computes the singular value decomposition
223
+ //
224
+ // U * D * V' = J
225
+ //
226
+ // and then uses it to compute the pseudo inverse of J'J as
227
+ //
228
+ // pseudoinverse[J'J] = V * pseudoinverse[D^2] * V'
229
+ //
230
+ // It is an accurate but slow method and should only be used
231
+ // for small to moderate sized problems. It can handle
232
+ // full-rank as well as rank deficient Jacobians.
233
+ //
234
+ // 2. SPARSE_QR uses the sparse QR factorization algorithm
235
+ // to compute the decomposition
236
+ //
237
+ // Q * R = J
238
+ //
239
+ // [J'J]^-1 = [R'*R]^-1
240
+ //
241
+ // SPARSE_QR is not capable of computing the covariance if the
242
+ // Jacobian is rank deficient. Depending on the value of
243
+ // Covariance::Options::sparse_linear_algebra_library_type, either
244
+ // Eigen's Sparse QR factorization algorithm will be used or
245
+ // SuiteSparse's high performance SuiteSparseQR algorithm will be
246
+ // used.
247
+ CovarianceAlgorithmType algorithm_type = SPARSE_QR;
248
+
249
+ // If the Jacobian matrix is near singular, then inverting J'J
250
+ // will result in unreliable results, e.g, if
251
+ //
252
+ // J = [1.0 1.0 ]
253
+ // [1.0 1.0000001 ]
254
+ //
255
+ // which is essentially a rank deficient matrix, we have
256
+ //
257
+ // inv(J'J) = [ 2.0471e+14 -2.0471e+14]
258
+ // [-2.0471e+14 2.0471e+14]
259
+ //
260
+ // This is not a useful result. Therefore, by default
261
+ // Covariance::Compute will return false if a rank deficient
262
+ // Jacobian is encountered. How rank deficiency is detected
263
+ // depends on the algorithm being used.
264
+ //
265
+ // 1. DENSE_SVD
266
+ //
267
+ // min_sigma / max_sigma < sqrt(min_reciprocal_condition_number)
268
+ //
269
+ // where min_sigma and max_sigma are the minimum and maxiumum
270
+ // singular values of J respectively.
271
+ //
272
+ // 2. SPARSE_QR
273
+ //
274
+ // rank(J) < num_col(J)
275
+ //
276
+ // Here rank(J) is the estimate of the rank of J returned by the
277
+ // sparse QR factorization algorithm. It is a fairly reliable
278
+ // indication of rank deficiency.
279
+ //
280
+ double min_reciprocal_condition_number = 1e-14;
281
+
282
+ // When using DENSE_SVD, the user has more control in dealing with
283
+ // singular and near singular covariance matrices.
284
+ //
285
+ // As mentioned above, when the covariance matrix is near
286
+ // singular, instead of computing the inverse of J'J, the
287
+ // Moore-Penrose pseudoinverse of J'J should be computed.
288
+ //
289
+ // If J'J has the eigen decomposition (lambda_i, e_i), where
290
+ // lambda_i is the i^th eigenvalue and e_i is the corresponding
291
+ // eigenvector, then the inverse of J'J is
292
+ //
293
+ // inverse[J'J] = sum_i e_i e_i' / lambda_i
294
+ //
295
+ // and computing the pseudo inverse involves dropping terms from
296
+ // this sum that correspond to small eigenvalues.
297
+ //
298
+ // How terms are dropped is controlled by
299
+ // min_reciprocal_condition_number and null_space_rank.
300
+ //
301
+ // If null_space_rank is non-negative, then the smallest
302
+ // null_space_rank eigenvalue/eigenvectors are dropped
303
+ // irrespective of the magnitude of lambda_i. If the ratio of the
304
+ // smallest non-zero eigenvalue to the largest eigenvalue in the
305
+ // truncated matrix is still below
306
+ // min_reciprocal_condition_number, then the Covariance::Compute()
307
+ // will fail and return false.
308
+ //
309
+ // Setting null_space_rank = -1 drops all terms for which
310
+ //
311
+ // lambda_i / lambda_max < min_reciprocal_condition_number.
312
+ //
313
+ // This option has no effect on the SUITE_SPARSE_QR and
314
+ // EIGEN_SPARSE_QR algorithms.
315
+ int null_space_rank = 0;
316
+
317
+ int num_threads = 1;
318
+
319
+ // Even though the residual blocks in the problem may contain loss
320
+ // functions, setting apply_loss_function to false will turn off
321
+ // the application of the loss function to the output of the cost
322
+ // function and in turn its effect on the covariance.
323
+ //
324
+ // TODO(sameergaarwal): Expand this based on Jim's experiments.
325
+ bool apply_loss_function = true;
326
+ };
327
+
328
+ explicit Covariance(const Options& options);
329
+ ~Covariance();
330
+
331
+ // Compute a part of the covariance matrix.
332
+ //
333
+ // The vector covariance_blocks, indexes into the covariance matrix
334
+ // block-wise using pairs of parameter blocks. This allows the
335
+ // covariance estimation algorithm to only compute and store these
336
+ // blocks.
337
+ //
338
+ // Since the covariance matrix is symmetric, if the user passes
339
+ // (block1, block2), then GetCovarianceBlock can be called with
340
+ // block1, block2 as well as block2, block1.
341
+ //
342
+ // covariance_blocks cannot contain duplicates. Bad things will
343
+ // happen if they do.
344
+ //
345
+ // Note that the list of covariance_blocks is only used to determine
346
+ // what parts of the covariance matrix are computed. The full
347
+ // Jacobian is used to do the computation, i.e. they do not have an
348
+ // impact on what part of the Jacobian is used for computation.
349
+ //
350
+ // The return value indicates the success or failure of the
351
+ // covariance computation. Please see the documentation for
352
+ // Covariance::Options for more on the conditions under which this
353
+ // function returns false.
354
+ bool Compute(const std::vector<std::pair<const double*, const double*>>&
355
+ covariance_blocks,
356
+ Problem* problem);
357
+
358
+ // Compute a part of the covariance matrix.
359
+ //
360
+ // The vector parameter_blocks contains the parameter blocks that
361
+ // are used for computing the covariance matrix. From this vector
362
+ // all covariance pairs are generated. This allows the covariance
363
+ // estimation algorithm to only compute and store these blocks.
364
+ //
365
+ // parameter_blocks cannot contain duplicates. Bad things will
366
+ // happen if they do.
367
+ //
368
+ // Note that the list of covariance_blocks is only used to determine
369
+ // what parts of the covariance matrix are computed. The full
370
+ // Jacobian is used to do the computation, i.e. they do not have an
371
+ // impact on what part of the Jacobian is used for computation.
372
+ //
373
+ // The return value indicates the success or failure of the
374
+ // covariance computation. Please see the documentation for
375
+ // Covariance::Options for more on the conditions under which this
376
+ // function returns false.
377
+ bool Compute(const std::vector<const double*>& parameter_blocks,
378
+ Problem* problem);
379
+
380
+ // Return the block of the cross-covariance matrix corresponding to
381
+ // parameter_block1 and parameter_block2.
382
+ //
383
+ // Compute must be called before the first call to
384
+ // GetCovarianceBlock and the pair <parameter_block1,
385
+ // parameter_block2> OR the pair <parameter_block2,
386
+ // parameter_block1> must have been present in the vector
387
+ // covariance_blocks when Compute was called. Otherwise
388
+ // GetCovarianceBlock will return false.
389
+ //
390
+ // covariance_block must point to a memory location that can store a
391
+ // parameter_block1_size x parameter_block2_size matrix. The
392
+ // returned covariance will be a row-major matrix.
393
+ bool GetCovarianceBlock(const double* parameter_block1,
394
+ const double* parameter_block2,
395
+ double* covariance_block) const;
396
+
397
+ // Return the block of the cross-covariance matrix corresponding to
398
+ // parameter_block1 and parameter_block2.
399
+ // Returns cross-covariance in the tangent space if a local
400
+ // parameterization is associated with either parameter block;
401
+ // else returns cross-covariance in the ambient space.
402
+ //
403
+ // Compute must be called before the first call to
404
+ // GetCovarianceBlock and the pair <parameter_block1,
405
+ // parameter_block2> OR the pair <parameter_block2,
406
+ // parameter_block1> must have been present in the vector
407
+ // covariance_blocks when Compute was called. Otherwise
408
+ // GetCovarianceBlock will return false.
409
+ //
410
+ // covariance_block must point to a memory location that can store a
411
+ // parameter_block1_local_size x parameter_block2_local_size matrix. The
412
+ // returned covariance will be a row-major matrix.
413
+ bool GetCovarianceBlockInTangentSpace(const double* parameter_block1,
414
+ const double* parameter_block2,
415
+ double* covariance_block) const;
416
+
417
+ // Return the covariance matrix corresponding to all parameter_blocks.
418
+ //
419
+ // Compute must be called before calling GetCovarianceMatrix and all
420
+ // parameter_blocks must have been present in the vector
421
+ // parameter_blocks when Compute was called. Otherwise
422
+ // GetCovarianceMatrix returns false.
423
+ //
424
+ // covariance_matrix must point to a memory location that can store
425
+ // the size of the covariance matrix. The covariance matrix will be
426
+ // a square matrix whose row and column count is equal to the sum of
427
+ // the sizes of the individual parameter blocks. The covariance
428
+ // matrix will be a row-major matrix.
429
+ bool GetCovarianceMatrix(const std::vector<const double*>& parameter_blocks,
430
+ double* covariance_matrix) const;
431
+
432
+ // Return the covariance matrix corresponding to parameter_blocks
433
+ // in the tangent space if a local parameterization is associated
434
+ // with one of the parameter blocks else returns the covariance
435
+ // matrix in the ambient space.
436
+ //
437
+ // Compute must be called before calling GetCovarianceMatrix and all
438
+ // parameter_blocks must have been present in the vector
439
+ // parameters_blocks when Compute was called. Otherwise
440
+ // GetCovarianceMatrix returns false.
441
+ //
442
+ // covariance_matrix must point to a memory location that can store
443
+ // the size of the covariance matrix. The covariance matrix will be
444
+ // a square matrix whose row and column count is equal to the sum of
445
+ // the sizes of the tangent spaces of the individual parameter
446
+ // blocks. The covariance matrix will be a row-major matrix.
447
+ bool GetCovarianceMatrixInTangentSpace(
448
+ const std::vector<const double*>& parameter_blocks,
449
+ double* covariance_matrix) const;
450
+
451
+ private:
452
+ std::unique_ptr<internal::CovarianceImpl> impl_;
453
+ };
454
+
455
+ } // namespace ceres
456
+
457
+ #include "ceres/internal/reenable_warnings.h"
458
+
459
+ #endif // CERES_PUBLIC_COVARIANCE_H_
ceres-v2/include/crs_matrix.h ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #ifndef CERES_PUBLIC_CRS_MATRIX_H_
32
+ #define CERES_PUBLIC_CRS_MATRIX_H_
33
+
34
+ #include <vector>
35
+
36
+ #include "ceres/internal/disable_warnings.h"
37
+ #include "ceres/internal/export.h"
38
+
39
+ namespace ceres {
40
+
41
+ // A compressed row sparse matrix used primarily for communicating the
42
+ // Jacobian matrix to the user.
43
+ struct CERES_EXPORT CRSMatrix {
44
+ CRSMatrix() = default;
45
+
46
+ int num_rows{0};
47
+ int num_cols{0};
48
+
49
+ // A compressed row matrix stores its contents in three arrays,
50
+ // rows, cols and values.
51
+ //
52
+ // rows is a num_rows + 1 sized array that points into the cols and
53
+ // values array. For each row i:
54
+ //
55
+ // cols[rows[i]] ... cols[rows[i + 1] - 1] are the indices of the
56
+ // non-zero columns of row i.
57
+ //
58
+ // values[rows[i]] .. values[rows[i + 1] - 1] are the values of the
59
+ // corresponding entries.
60
+ //
61
+ // cols and values contain as many entries as there are non-zeros in
62
+ // the matrix.
63
+ //
64
+ // e.g, consider the 3x4 sparse matrix
65
+ //
66
+ // [ 0 10 0 4 ]
67
+ // [ 0 2 -3 2 ]
68
+ // [ 1 2 0 0 ]
69
+ //
70
+ // The three arrays will be:
71
+ //
72
+ //
73
+ // -row0- ---row1--- -row2-
74
+ // rows = [ 0, 2, 5, 7]
75
+ // cols = [ 1, 3, 1, 2, 3, 0, 1]
76
+ // values = [10, 4, 2, -3, 2, 1, 2]
77
+
78
+ std::vector<int> cols;
79
+ std::vector<int> rows;
80
+ std::vector<double> values;
81
+ };
82
+
83
+ } // namespace ceres
84
+
85
+ #include "ceres/internal/reenable_warnings.h"
86
+
87
+ #endif // CERES_PUBLIC_CRS_MATRIX_H_
ceres-v2/include/cubic_interpolation.h ADDED
@@ -0,0 +1,436 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #ifndef CERES_PUBLIC_CUBIC_INTERPOLATION_H_
32
+ #define CERES_PUBLIC_CUBIC_INTERPOLATION_H_
33
+
34
+ #include "Eigen/Core"
35
+ #include "ceres/internal/export.h"
36
+ #include "glog/logging.h"
37
+
38
+ namespace ceres {
39
+
40
+ // Given samples from a function sampled at four equally spaced points,
41
+ //
42
+ // p0 = f(-1)
43
+ // p1 = f(0)
44
+ // p2 = f(1)
45
+ // p3 = f(2)
46
+ //
47
+ // Evaluate the cubic Hermite spline (also known as the Catmull-Rom
48
+ // spline) at a point x that lies in the interval [0, 1].
49
+ //
50
+ // This is also the interpolation kernel (for the case of a = 0.5) as
51
+ // proposed by R. Keys, in:
52
+ //
53
+ // "Cubic convolution interpolation for digital image processing".
54
+ // IEEE Transactions on Acoustics, Speech, and Signal Processing
55
+ // 29 (6): 1153-1160.
56
+ //
57
+ // For more details see
58
+ //
59
+ // http://en.wikipedia.org/wiki/Cubic_Hermite_spline
60
+ // http://en.wikipedia.org/wiki/Bicubic_interpolation
61
+ //
62
+ // f if not nullptr will contain the interpolated function values.
63
+ // dfdx if not nullptr will contain the interpolated derivative values.
64
+ template <int kDataDimension>
65
+ void CubicHermiteSpline(const Eigen::Matrix<double, kDataDimension, 1>& p0,
66
+ const Eigen::Matrix<double, kDataDimension, 1>& p1,
67
+ const Eigen::Matrix<double, kDataDimension, 1>& p2,
68
+ const Eigen::Matrix<double, kDataDimension, 1>& p3,
69
+ const double x,
70
+ double* f,
71
+ double* dfdx) {
72
+ using VType = Eigen::Matrix<double, kDataDimension, 1>;
73
+ const VType a = 0.5 * (-p0 + 3.0 * p1 - 3.0 * p2 + p3);
74
+ const VType b = 0.5 * (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3);
75
+ const VType c = 0.5 * (-p0 + p2);
76
+ const VType d = p1;
77
+
78
+ // Use Horner's rule to evaluate the function value and its
79
+ // derivative.
80
+
81
+ // f = ax^3 + bx^2 + cx + d
82
+ if (f != nullptr) {
83
+ Eigen::Map<VType>(f, kDataDimension) = d + x * (c + x * (b + x * a));
84
+ }
85
+
86
+ // dfdx = 3ax^2 + 2bx + c
87
+ if (dfdx != nullptr) {
88
+ Eigen::Map<VType>(dfdx, kDataDimension) = c + x * (2.0 * b + 3.0 * a * x);
89
+ }
90
+ }
91
+
92
+ // Given as input an infinite one dimensional grid, which provides the
93
+ // following interface.
94
+ //
95
+ // class Grid {
96
+ // public:
97
+ // enum { DATA_DIMENSION = 2; };
98
+ // void GetValue(int n, double* f) const;
99
+ // };
100
+ //
101
+ // Here, GetValue gives the value of a function f (possibly vector
102
+ // valued) for any integer n.
103
+ //
104
+ // The enum DATA_DIMENSION indicates the dimensionality of the
105
+ // function being interpolated. For example if you are interpolating
106
+ // rotations in axis-angle format over time, then DATA_DIMENSION = 3.
107
+ //
108
+ // CubicInterpolator uses cubic Hermite splines to produce a smooth
109
+ // approximation to it that can be used to evaluate the f(x) and f'(x)
110
+ // at any point on the real number line.
111
+ //
112
+ // For more details on cubic interpolation see
113
+ //
114
+ // http://en.wikipedia.org/wiki/Cubic_Hermite_spline
115
+ //
116
+ // Example usage:
117
+ //
118
+ // const double data[] = {1.0, 2.0, 5.0, 6.0};
119
+ // Grid1D<double, 1> grid(data, 0, 4);
120
+ // CubicInterpolator<Grid1D<double, 1>> interpolator(grid);
121
+ // double f, dfdx;
122
+ // interpolator.Evaluator(1.5, &f, &dfdx);
123
+ template <typename Grid>
124
+ class CubicInterpolator {
125
+ public:
126
+ explicit CubicInterpolator(const Grid& grid) : grid_(grid) {
127
+ // The + casts the enum into an int before doing the
128
+ // comparison. It is needed to prevent
129
+ // "-Wunnamed-type-template-args" related errors.
130
+ CHECK_GE(+Grid::DATA_DIMENSION, 1);
131
+ }
132
+
133
+ void Evaluate(double x, double* f, double* dfdx) const {
134
+ const int n = std::floor(x);
135
+ Eigen::Matrix<double, Grid::DATA_DIMENSION, 1> p0, p1, p2, p3;
136
+ grid_.GetValue(n - 1, p0.data());
137
+ grid_.GetValue(n, p1.data());
138
+ grid_.GetValue(n + 1, p2.data());
139
+ grid_.GetValue(n + 2, p3.data());
140
+ CubicHermiteSpline<Grid::DATA_DIMENSION>(p0, p1, p2, p3, x - n, f, dfdx);
141
+ }
142
+
143
+ // The following two Evaluate overloads are needed for interfacing
144
+ // with automatic differentiation. The first is for when a scalar
145
+ // evaluation is done, and the second one is for when Jets are used.
146
+ void Evaluate(const double& x, double* f) const { Evaluate(x, f, nullptr); }
147
+
148
+ template <typename JetT>
149
+ void Evaluate(const JetT& x, JetT* f) const {
150
+ double fx[Grid::DATA_DIMENSION], dfdx[Grid::DATA_DIMENSION];
151
+ Evaluate(x.a, fx, dfdx);
152
+ for (int i = 0; i < Grid::DATA_DIMENSION; ++i) {
153
+ f[i].a = fx[i];
154
+ f[i].v = dfdx[i] * x.v;
155
+ }
156
+ }
157
+
158
+ private:
159
+ const Grid& grid_;
160
+ };
161
+
162
+ // An object that implements an infinite one dimensional grid needed
163
+ // by the CubicInterpolator where the source of the function values is
164
+ // an array of type T on the interval
165
+ //
166
+ // [begin, ..., end - 1]
167
+ //
168
+ // Since the input array is finite and the grid is infinite, values
169
+ // outside this interval needs to be computed. Grid1D uses the value
170
+ // from the nearest edge.
171
+ //
172
+ // The function being provided can be vector valued, in which case
173
+ // kDataDimension > 1. The dimensional slices of the function maybe
174
+ // interleaved, or they maybe stacked, i.e, if the function has
175
+ // kDataDimension = 2, if kInterleaved = true, then it is stored as
176
+ //
177
+ // f01, f02, f11, f12 ....
178
+ //
179
+ // and if kInterleaved = false, then it is stored as
180
+ //
181
+ // f01, f11, .. fn1, f02, f12, .. , fn2
182
+ //
183
+ template <typename T, int kDataDimension = 1, bool kInterleaved = true>
184
+ struct Grid1D {
185
+ public:
186
+ enum { DATA_DIMENSION = kDataDimension };
187
+
188
+ Grid1D(const T* data, const int begin, const int end)
189
+ : data_(data), begin_(begin), end_(end), num_values_(end - begin) {
190
+ CHECK_LT(begin, end);
191
+ }
192
+
193
+ EIGEN_STRONG_INLINE void GetValue(const int n, double* f) const {
194
+ const int idx = (std::min)((std::max)(begin_, n), end_ - 1) - begin_;
195
+ if (kInterleaved) {
196
+ for (int i = 0; i < kDataDimension; ++i) {
197
+ f[i] = static_cast<double>(data_[kDataDimension * idx + i]);
198
+ }
199
+ } else {
200
+ for (int i = 0; i < kDataDimension; ++i) {
201
+ f[i] = static_cast<double>(data_[i * num_values_ + idx]);
202
+ }
203
+ }
204
+ }
205
+
206
+ private:
207
+ const T* data_;
208
+ const int begin_;
209
+ const int end_;
210
+ const int num_values_;
211
+ };
212
+
213
+ // Given as input an infinite two dimensional grid like object, which
214
+ // provides the following interface:
215
+ //
216
+ // struct Grid {
217
+ // enum { DATA_DIMENSION = 1 };
218
+ // void GetValue(int row, int col, double* f) const;
219
+ // };
220
+ //
221
+ // Where, GetValue gives us the value of a function f (possibly vector
222
+ // valued) for any pairs of integers (row, col), and the enum
223
+ // DATA_DIMENSION indicates the dimensionality of the function being
224
+ // interpolated. For example if you are interpolating a color image
225
+ // with three channels (Red, Green & Blue), then DATA_DIMENSION = 3.
226
+ //
227
+ // BiCubicInterpolator uses the cubic convolution interpolation
228
+ // algorithm of R. Keys, to produce a smooth approximation to it that
229
+ // can be used to evaluate the f(r,c), df(r, c)/dr and df(r,c)/dc at
230
+ // any point in the real plane.
231
+ //
232
+ // For more details on the algorithm used here see:
233
+ //
234
+ // "Cubic convolution interpolation for digital image processing".
235
+ // Robert G. Keys, IEEE Trans. on Acoustics, Speech, and Signal
236
+ // Processing 29 (6): 1153-1160, 1981.
237
+ //
238
+ // http://en.wikipedia.org/wiki/Cubic_Hermite_spline
239
+ // http://en.wikipedia.org/wiki/Bicubic_interpolation
240
+ //
241
+ // Example usage:
242
+ //
243
+ // const double data[] = {1.0, 3.0, -1.0, 4.0,
244
+ // 3.6, 2.1, 4.2, 2.0,
245
+ // 2.0, 1.0, 3.1, 5.2};
246
+ // Grid2D<double, 1> grid(data, 3, 4);
247
+ // BiCubicInterpolator<Grid2D<double, 1>> interpolator(grid);
248
+ // double f, dfdr, dfdc;
249
+ // interpolator.Evaluate(1.2, 2.5, &f, &dfdr, &dfdc);
250
+
251
+ template <typename Grid>
252
+ class BiCubicInterpolator {
253
+ public:
254
+ explicit BiCubicInterpolator(const Grid& grid) : grid_(grid) {
255
+ // The + casts the enum into an int before doing the
256
+ // comparison. It is needed to prevent
257
+ // "-Wunnamed-type-template-args" related errors.
258
+ CHECK_GE(+Grid::DATA_DIMENSION, 1);
259
+ }
260
+
261
+ // Evaluate the interpolated function value and/or its
262
+ // derivative. Uses the nearest point on the grid boundary if r or
263
+ // c is out of bounds.
264
+ void Evaluate(
265
+ double r, double c, double* f, double* dfdr, double* dfdc) const {
266
+ // BiCubic interpolation requires 16 values around the point being
267
+ // evaluated. We will use pij, to indicate the elements of the
268
+ // 4x4 grid of values.
269
+ //
270
+ // col
271
+ // p00 p01 p02 p03
272
+ // row p10 p11 p12 p13
273
+ // p20 p21 p22 p23
274
+ // p30 p31 p32 p33
275
+ //
276
+ // The point (r,c) being evaluated is assumed to lie in the square
277
+ // defined by p11, p12, p22 and p21.
278
+
279
+ const int row = std::floor(r);
280
+ const int col = std::floor(c);
281
+
282
+ Eigen::Matrix<double, Grid::DATA_DIMENSION, 1> p0, p1, p2, p3;
283
+
284
+ // Interpolate along each of the four rows, evaluating the function
285
+ // value and the horizontal derivative in each row.
286
+ Eigen::Matrix<double, Grid::DATA_DIMENSION, 1> f0, f1, f2, f3;
287
+ Eigen::Matrix<double, Grid::DATA_DIMENSION, 1> df0dc, df1dc, df2dc, df3dc;
288
+
289
+ grid_.GetValue(row - 1, col - 1, p0.data());
290
+ grid_.GetValue(row - 1, col, p1.data());
291
+ grid_.GetValue(row - 1, col + 1, p2.data());
292
+ grid_.GetValue(row - 1, col + 2, p3.data());
293
+ CubicHermiteSpline<Grid::DATA_DIMENSION>(
294
+ p0, p1, p2, p3, c - col, f0.data(), df0dc.data());
295
+
296
+ grid_.GetValue(row, col - 1, p0.data());
297
+ grid_.GetValue(row, col, p1.data());
298
+ grid_.GetValue(row, col + 1, p2.data());
299
+ grid_.GetValue(row, col + 2, p3.data());
300
+ CubicHermiteSpline<Grid::DATA_DIMENSION>(
301
+ p0, p1, p2, p3, c - col, f1.data(), df1dc.data());
302
+
303
+ grid_.GetValue(row + 1, col - 1, p0.data());
304
+ grid_.GetValue(row + 1, col, p1.data());
305
+ grid_.GetValue(row + 1, col + 1, p2.data());
306
+ grid_.GetValue(row + 1, col + 2, p3.data());
307
+ CubicHermiteSpline<Grid::DATA_DIMENSION>(
308
+ p0, p1, p2, p3, c - col, f2.data(), df2dc.data());
309
+
310
+ grid_.GetValue(row + 2, col - 1, p0.data());
311
+ grid_.GetValue(row + 2, col, p1.data());
312
+ grid_.GetValue(row + 2, col + 1, p2.data());
313
+ grid_.GetValue(row + 2, col + 2, p3.data());
314
+ CubicHermiteSpline<Grid::DATA_DIMENSION>(
315
+ p0, p1, p2, p3, c - col, f3.data(), df3dc.data());
316
+
317
+ // Interpolate vertically the interpolated value from each row and
318
+ // compute the derivative along the columns.
319
+ CubicHermiteSpline<Grid::DATA_DIMENSION>(f0, f1, f2, f3, r - row, f, dfdr);
320
+ if (dfdc != nullptr) {
321
+ // Interpolate vertically the derivative along the columns.
322
+ CubicHermiteSpline<Grid::DATA_DIMENSION>(
323
+ df0dc, df1dc, df2dc, df3dc, r - row, dfdc, nullptr);
324
+ }
325
+ }
326
+
327
+ // The following two Evaluate overloads are needed for interfacing
328
+ // with automatic differentiation. The first is for when a scalar
329
+ // evaluation is done, and the second one is for when Jets are used.
330
+ void Evaluate(const double& r, const double& c, double* f) const {
331
+ Evaluate(r, c, f, nullptr, nullptr);
332
+ }
333
+
334
+ template <typename JetT>
335
+ void Evaluate(const JetT& r, const JetT& c, JetT* f) const {
336
+ double frc[Grid::DATA_DIMENSION];
337
+ double dfdr[Grid::DATA_DIMENSION];
338
+ double dfdc[Grid::DATA_DIMENSION];
339
+ Evaluate(r.a, c.a, frc, dfdr, dfdc);
340
+ for (int i = 0; i < Grid::DATA_DIMENSION; ++i) {
341
+ f[i].a = frc[i];
342
+ f[i].v = dfdr[i] * r.v + dfdc[i] * c.v;
343
+ }
344
+ }
345
+
346
+ private:
347
+ const Grid& grid_;
348
+ };
349
+
350
+ // An object that implements an infinite two dimensional grid needed
351
+ // by the BiCubicInterpolator where the source of the function values
352
+ // is an grid of type T on the grid
353
+ //
354
+ // [(row_start, col_start), ..., (row_start, col_end - 1)]
355
+ // [ ... ]
356
+ // [(row_end - 1, col_start), ..., (row_end - 1, col_end - 1)]
357
+ //
358
+ // Since the input grid is finite and the grid is infinite, values
359
+ // outside this interval needs to be computed. Grid2D uses the value
360
+ // from the nearest edge.
361
+ //
362
+ // The function being provided can be vector valued, in which case
363
+ // kDataDimension > 1. The data maybe stored in row or column major
364
+ // format and the various dimensional slices of the function maybe
365
+ // interleaved, or they maybe stacked, i.e, if the function has
366
+ // kDataDimension = 2, is stored in row-major format and if
367
+ // kInterleaved = true, then it is stored as
368
+ //
369
+ // f001, f002, f011, f012, ...
370
+ //
371
+ // A commonly occuring example are color images (RGB) where the three
372
+ // channels are stored interleaved.
373
+ //
374
+ // If kInterleaved = false, then it is stored as
375
+ //
376
+ // f001, f011, ..., fnm1, f002, f012, ...
377
+ template <typename T,
378
+ int kDataDimension = 1,
379
+ bool kRowMajor = true,
380
+ bool kInterleaved = true>
381
+ struct Grid2D {
382
+ public:
383
+ enum { DATA_DIMENSION = kDataDimension };
384
+
385
+ Grid2D(const T* data,
386
+ const int row_begin,
387
+ const int row_end,
388
+ const int col_begin,
389
+ const int col_end)
390
+ : data_(data),
391
+ row_begin_(row_begin),
392
+ row_end_(row_end),
393
+ col_begin_(col_begin),
394
+ col_end_(col_end),
395
+ num_rows_(row_end - row_begin),
396
+ num_cols_(col_end - col_begin),
397
+ num_values_(num_rows_ * num_cols_) {
398
+ CHECK_GE(kDataDimension, 1);
399
+ CHECK_LT(row_begin, row_end);
400
+ CHECK_LT(col_begin, col_end);
401
+ }
402
+
403
+ EIGEN_STRONG_INLINE void GetValue(const int r, const int c, double* f) const {
404
+ const int row_idx =
405
+ (std::min)((std::max)(row_begin_, r), row_end_ - 1) - row_begin_;
406
+ const int col_idx =
407
+ (std::min)((std::max)(col_begin_, c), col_end_ - 1) - col_begin_;
408
+
409
+ const int n = (kRowMajor) ? num_cols_ * row_idx + col_idx
410
+ : num_rows_ * col_idx + row_idx;
411
+
412
+ if (kInterleaved) {
413
+ for (int i = 0; i < kDataDimension; ++i) {
414
+ f[i] = static_cast<double>(data_[kDataDimension * n + i]);
415
+ }
416
+ } else {
417
+ for (int i = 0; i < kDataDimension; ++i) {
418
+ f[i] = static_cast<double>(data_[i * num_values_ + n]);
419
+ }
420
+ }
421
+ }
422
+
423
+ private:
424
+ const T* data_;
425
+ const int row_begin_;
426
+ const int row_end_;
427
+ const int col_begin_;
428
+ const int col_end_;
429
+ const int num_rows_;
430
+ const int num_cols_;
431
+ const int num_values_;
432
+ };
433
+
434
+ } // namespace ceres
435
+
436
+ #endif // CERES_PUBLIC_CUBIC_INTERPOLATOR_H_
ceres-v2/include/dynamic_autodiff_cost_function.h ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+ // mierle@gmail.com (Keir Mierle)
31
+
32
+ #ifndef CERES_PUBLIC_DYNAMIC_AUTODIFF_COST_FUNCTION_H_
33
+ #define CERES_PUBLIC_DYNAMIC_AUTODIFF_COST_FUNCTION_H_
34
+
35
+ #include <cmath>
36
+ #include <memory>
37
+ #include <numeric>
38
+ #include <vector>
39
+
40
+ #include "ceres/dynamic_cost_function.h"
41
+ #include "ceres/internal/fixed_array.h"
42
+ #include "ceres/jet.h"
43
+ #include "ceres/types.h"
44
+ #include "glog/logging.h"
45
+
46
+ namespace ceres {
47
+
48
+ // This autodiff implementation differs from the one found in
49
+ // autodiff_cost_function.h by supporting autodiff on cost functions
50
+ // with variable numbers of parameters with variable sizes. With the
51
+ // other implementation, all the sizes (both the number of parameter
52
+ // blocks and the size of each block) must be fixed at compile time.
53
+ //
54
+ // The functor API differs slightly from the API for fixed size
55
+ // autodiff; the expected interface for the cost functors is:
56
+ //
57
+ // struct MyCostFunctor {
58
+ // template<typename T>
59
+ // bool operator()(T const* const* parameters, T* residuals) const {
60
+ // // Use parameters[i] to access the i'th parameter block.
61
+ // }
62
+ // };
63
+ //
64
+ // Since the sizing of the parameters is done at runtime, you must
65
+ // also specify the sizes after creating the dynamic autodiff cost
66
+ // function. For example:
67
+ //
68
+ // DynamicAutoDiffCostFunction<MyCostFunctor, 3> cost_function(
69
+ // new MyCostFunctor());
70
+ // cost_function.AddParameterBlock(5);
71
+ // cost_function.AddParameterBlock(10);
72
+ // cost_function.SetNumResiduals(21);
73
+ //
74
+ // Under the hood, the implementation evaluates the cost function
75
+ // multiple times, computing a small set of the derivatives (four by
76
+ // default, controlled by the Stride template parameter) with each
77
+ // pass. There is a tradeoff with the size of the passes; you may want
78
+ // to experiment with the stride.
79
+ template <typename CostFunctor, int Stride = 4>
80
+ class DynamicAutoDiffCostFunction final : public DynamicCostFunction {
81
+ public:
82
+ // Takes ownership by default.
83
+ explicit DynamicAutoDiffCostFunction(CostFunctor* functor,
84
+ Ownership ownership = TAKE_OWNERSHIP)
85
+ : functor_(functor), ownership_(ownership) {}
86
+
87
+ DynamicAutoDiffCostFunction(DynamicAutoDiffCostFunction&& other)
88
+ : functor_(std::move(other.functor_)), ownership_(other.ownership_) {}
89
+
90
+ ~DynamicAutoDiffCostFunction() override {
91
+ // Manually release pointer if configured to not take ownership
92
+ // rather than deleting only if ownership is taken. This is to
93
+ // stay maximally compatible to old user code which may have
94
+ // forgotten to implement a virtual destructor, from when the
95
+ // AutoDiffCostFunction always took ownership.
96
+ if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
97
+ functor_.release();
98
+ }
99
+ }
100
+
101
+ bool Evaluate(double const* const* parameters,
102
+ double* residuals,
103
+ double** jacobians) const override {
104
+ CHECK_GT(num_residuals(), 0)
105
+ << "You must call DynamicAutoDiffCostFunction::SetNumResiduals() "
106
+ << "before DynamicAutoDiffCostFunction::Evaluate().";
107
+
108
+ if (jacobians == nullptr) {
109
+ return (*functor_)(parameters, residuals);
110
+ }
111
+
112
+ // The difficulty with Jets, as implemented in Ceres, is that they were
113
+ // originally designed for strictly compile-sized use. At this point, there
114
+ // is a large body of code that assumes inside a cost functor it is
115
+ // acceptable to do e.g. T(1.5) and get an appropriately sized jet back.
116
+ //
117
+ // Unfortunately, it is impossible to communicate the expected size of a
118
+ // dynamically sized jet to the static instantiations that existing code
119
+ // depends on.
120
+ //
121
+ // To work around this issue, the solution here is to evaluate the
122
+ // jacobians in a series of passes, each one computing Stride *
123
+ // num_residuals() derivatives. This is done with small, fixed-size jets.
124
+ const int num_parameter_blocks =
125
+ static_cast<int>(parameter_block_sizes().size());
126
+ const int num_parameters = std::accumulate(
127
+ parameter_block_sizes().begin(), parameter_block_sizes().end(), 0);
128
+
129
+ // Allocate scratch space for the strided evaluation.
130
+ using JetT = Jet<double, Stride>;
131
+ internal::FixedArray<JetT, (256 * 7) / sizeof(JetT)> input_jets(
132
+ num_parameters);
133
+ internal::FixedArray<JetT, (256 * 7) / sizeof(JetT)> output_jets(
134
+ num_residuals());
135
+
136
+ // Make the parameter pack that is sent to the functor (reused).
137
+ internal::FixedArray<Jet<double, Stride>*> jet_parameters(
138
+ num_parameter_blocks, nullptr);
139
+ int num_active_parameters = 0;
140
+
141
+ // To handle constant parameters between non-constant parameter blocks, the
142
+ // start position --- a raw parameter index --- of each contiguous block of
143
+ // non-constant parameters is recorded in start_derivative_section.
144
+ std::vector<int> start_derivative_section;
145
+ bool in_derivative_section = false;
146
+ int parameter_cursor = 0;
147
+
148
+ // Discover the derivative sections and set the parameter values.
149
+ for (int i = 0; i < num_parameter_blocks; ++i) {
150
+ jet_parameters[i] = &input_jets[parameter_cursor];
151
+
152
+ const int parameter_block_size = parameter_block_sizes()[i];
153
+ if (jacobians[i] != nullptr) {
154
+ if (!in_derivative_section) {
155
+ start_derivative_section.push_back(parameter_cursor);
156
+ in_derivative_section = true;
157
+ }
158
+
159
+ num_active_parameters += parameter_block_size;
160
+ } else {
161
+ in_derivative_section = false;
162
+ }
163
+
164
+ for (int j = 0; j < parameter_block_size; ++j, parameter_cursor++) {
165
+ input_jets[parameter_cursor].a = parameters[i][j];
166
+ }
167
+ }
168
+
169
+ if (num_active_parameters == 0) {
170
+ return (*functor_)(parameters, residuals);
171
+ }
172
+ // When `num_active_parameters % Stride != 0` then it can be the case
173
+ // that `active_parameter_count < Stride` while parameter_cursor is less
174
+ // than the total number of parameters and with no remaining non-constant
175
+ // parameter blocks. Pushing parameter_cursor (the total number of
176
+ // parameters) as a final entry to start_derivative_section is required
177
+ // because if a constant parameter block is encountered after the
178
+ // last non-constant block then current_derivative_section is incremented
179
+ // and would otherwise index an invalid position in
180
+ // start_derivative_section. Setting the final element to the total number
181
+ // of parameters means that this can only happen at most once in the loop
182
+ // below.
183
+ start_derivative_section.push_back(parameter_cursor);
184
+
185
+ // Evaluate all of the strides. Each stride is a chunk of the derivative to
186
+ // evaluate, typically some size proportional to the size of the SIMD
187
+ // registers of the CPU.
188
+ int num_strides = static_cast<int>(
189
+ ceil(num_active_parameters / static_cast<float>(Stride)));
190
+
191
+ int current_derivative_section = 0;
192
+ int current_derivative_section_cursor = 0;
193
+
194
+ for (int pass = 0; pass < num_strides; ++pass) {
195
+ // Set most of the jet components to zero, except for
196
+ // non-constant #Stride parameters.
197
+ const int initial_derivative_section = current_derivative_section;
198
+ const int initial_derivative_section_cursor =
199
+ current_derivative_section_cursor;
200
+
201
+ int active_parameter_count = 0;
202
+ parameter_cursor = 0;
203
+
204
+ for (int i = 0; i < num_parameter_blocks; ++i) {
205
+ for (int j = 0; j < parameter_block_sizes()[i];
206
+ ++j, parameter_cursor++) {
207
+ input_jets[parameter_cursor].v.setZero();
208
+ if (active_parameter_count < Stride &&
209
+ parameter_cursor >=
210
+ (start_derivative_section[current_derivative_section] +
211
+ current_derivative_section_cursor)) {
212
+ if (jacobians[i] != nullptr) {
213
+ input_jets[parameter_cursor].v[active_parameter_count] = 1.0;
214
+ ++active_parameter_count;
215
+ ++current_derivative_section_cursor;
216
+ } else {
217
+ ++current_derivative_section;
218
+ current_derivative_section_cursor = 0;
219
+ }
220
+ }
221
+ }
222
+ }
223
+
224
+ if (!(*functor_)(&jet_parameters[0], &output_jets[0])) {
225
+ return false;
226
+ }
227
+
228
+ // Copy the pieces of the jacobians into their final place.
229
+ active_parameter_count = 0;
230
+
231
+ current_derivative_section = initial_derivative_section;
232
+ current_derivative_section_cursor = initial_derivative_section_cursor;
233
+
234
+ for (int i = 0, parameter_cursor = 0; i < num_parameter_blocks; ++i) {
235
+ for (int j = 0; j < parameter_block_sizes()[i];
236
+ ++j, parameter_cursor++) {
237
+ if (active_parameter_count < Stride &&
238
+ parameter_cursor >=
239
+ (start_derivative_section[current_derivative_section] +
240
+ current_derivative_section_cursor)) {
241
+ if (jacobians[i] != nullptr) {
242
+ for (int k = 0; k < num_residuals(); ++k) {
243
+ jacobians[i][k * parameter_block_sizes()[i] + j] =
244
+ output_jets[k].v[active_parameter_count];
245
+ }
246
+ ++active_parameter_count;
247
+ ++current_derivative_section_cursor;
248
+ } else {
249
+ ++current_derivative_section;
250
+ current_derivative_section_cursor = 0;
251
+ }
252
+ }
253
+ }
254
+ }
255
+
256
+ // Only copy the residuals over once (even though we compute them on
257
+ // every loop).
258
+ if (pass == num_strides - 1) {
259
+ for (int k = 0; k < num_residuals(); ++k) {
260
+ residuals[k] = output_jets[k].a;
261
+ }
262
+ }
263
+ }
264
+ return true;
265
+ }
266
+
267
+ private:
268
+ std::unique_ptr<CostFunctor> functor_;
269
+ Ownership ownership_;
270
+ };
271
+
272
+ } // namespace ceres
273
+
274
+ #endif // CERES_PUBLIC_DYNAMIC_AUTODIFF_COST_FUNCTION_H_
ceres-v2/include/dynamic_cost_function.h ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #ifndef CERES_PUBLIC_DYNAMIC_COST_FUNCTION_H_
32
+ #define CERES_PUBLIC_DYNAMIC_COST_FUNCTION_H_
33
+
34
+ #include "ceres/cost_function.h"
35
+ #include "ceres/internal/disable_warnings.h"
36
+
37
+ namespace ceres {
38
+
39
+ // A common base class for DynamicAutoDiffCostFunction and
40
+ // DynamicNumericDiffCostFunction which depend on methods that can add
41
+ // parameter blocks and set the number of residuals at run time.
42
+ class CERES_EXPORT DynamicCostFunction : public CostFunction {
43
+ public:
44
+ virtual void AddParameterBlock(int size) {
45
+ mutable_parameter_block_sizes()->push_back(size);
46
+ }
47
+
48
+ virtual void SetNumResiduals(int num_residuals) {
49
+ set_num_residuals(num_residuals);
50
+ }
51
+ };
52
+
53
+ } // namespace ceres
54
+
55
+ #include "ceres/internal/reenable_warnings.h"
56
+
57
+ #endif // CERES_PUBLIC_DYNAMIC_COST_FUNCTION_H_
ceres-v2/include/dynamic_cost_function_to_functor.h ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+ // dgossow@google.com (David Gossow)
31
+
32
+ #ifndef CERES_PUBLIC_DYNAMIC_COST_FUNCTION_TO_FUNCTOR_H_
33
+ #define CERES_PUBLIC_DYNAMIC_COST_FUNCTION_TO_FUNCTOR_H_
34
+
35
+ #include <memory>
36
+ #include <numeric>
37
+ #include <vector>
38
+
39
+ #include "ceres/dynamic_cost_function.h"
40
+ #include "ceres/internal/disable_warnings.h"
41
+ #include "ceres/internal/export.h"
42
+ #include "ceres/internal/fixed_array.h"
43
+ #include "glog/logging.h"
44
+
45
+ namespace ceres {
46
+
47
+ // DynamicCostFunctionToFunctor allows users to use CostFunction
48
+ // objects in templated functors which are to be used for automatic
49
+ // differentiation. It works similar to CostFunctionToFunctor, with the
50
+ // difference that it allows you to wrap a cost function with dynamic numbers
51
+ // of parameters and residuals.
52
+ //
53
+ // For example, let us assume that
54
+ //
55
+ // class IntrinsicProjection : public CostFunction {
56
+ // public:
57
+ // IntrinsicProjection(const double* observation);
58
+ // bool Evaluate(double const* const* parameters,
59
+ // double* residuals,
60
+ // double** jacobians) const override;
61
+ // };
62
+ //
63
+ // is a cost function that implements the projection of a point in its
64
+ // local coordinate system onto its image plane and subtracts it from
65
+ // the observed point projection. It can compute its residual and
66
+ // either via analytic or numerical differentiation can compute its
67
+ // jacobians. The intrinsics are passed in as parameters[0] and the point as
68
+ // parameters[1].
69
+ //
70
+ // Now we would like to compose the action of this CostFunction with
71
+ // the action of camera extrinsics, i.e., rotation and
72
+ // translation. Say we have a templated function
73
+ //
74
+ // template<typename T>
75
+ // void RotateAndTranslatePoint(double const* const* parameters,
76
+ // double* residuals);
77
+ //
78
+ // Then we can now do the following,
79
+ //
80
+ // struct CameraProjection {
81
+ // CameraProjection(const double* observation)
82
+ // : intrinsic_projection_.(new IntrinsicProjection(observation)) {
83
+ // }
84
+ // template <typename T>
85
+ // bool operator()(T const* const* parameters,
86
+ // T* residual) const {
87
+ // const T* rotation = parameters[0];
88
+ // const T* translation = parameters[1];
89
+ // const T* intrinsics = parameters[2];
90
+ // const T* point = parameters[3];
91
+ // T transformed_point[3];
92
+ // RotateAndTranslatePoint(rotation, translation, point, transformed_point);
93
+ //
94
+ // // Note that we call intrinsic_projection_, just like it was
95
+ // // any other templated functor.
96
+ // const T* projection_parameters[2];
97
+ // projection_parameters[0] = intrinsics;
98
+ // projection_parameters[1] = transformed_point;
99
+ // return intrinsic_projection_(projection_parameters, residual);
100
+ // }
101
+ //
102
+ // private:
103
+ // DynamicCostFunctionToFunctor intrinsic_projection_;
104
+ // };
105
+ class CERES_EXPORT DynamicCostFunctionToFunctor {
106
+ public:
107
+ // Takes ownership of cost_function.
108
+ explicit DynamicCostFunctionToFunctor(CostFunction* cost_function)
109
+ : cost_function_(cost_function) {
110
+ CHECK(cost_function != nullptr);
111
+ }
112
+
113
+ bool operator()(double const* const* parameters, double* residuals) const {
114
+ return cost_function_->Evaluate(parameters, residuals, nullptr);
115
+ }
116
+
117
+ template <typename JetT>
118
+ bool operator()(JetT const* const* inputs, JetT* output) const {
119
+ const std::vector<int32_t>& parameter_block_sizes =
120
+ cost_function_->parameter_block_sizes();
121
+ const int num_parameter_blocks =
122
+ static_cast<int>(parameter_block_sizes.size());
123
+ const int num_residuals = cost_function_->num_residuals();
124
+ const int num_parameters = std::accumulate(
125
+ parameter_block_sizes.begin(), parameter_block_sizes.end(), 0);
126
+
127
+ internal::FixedArray<double> parameters(num_parameters);
128
+ internal::FixedArray<double*> parameter_blocks(num_parameter_blocks);
129
+ internal::FixedArray<double> jacobians(num_residuals * num_parameters);
130
+ internal::FixedArray<double*> jacobian_blocks(num_parameter_blocks);
131
+ internal::FixedArray<double> residuals(num_residuals);
132
+
133
+ // Build a set of arrays to get the residuals and jacobians from
134
+ // the CostFunction wrapped by this functor.
135
+ double* parameter_ptr = parameters.data();
136
+ double* jacobian_ptr = jacobians.data();
137
+ for (int i = 0; i < num_parameter_blocks; ++i) {
138
+ parameter_blocks[i] = parameter_ptr;
139
+ jacobian_blocks[i] = jacobian_ptr;
140
+ for (int j = 0; j < parameter_block_sizes[i]; ++j) {
141
+ *parameter_ptr++ = inputs[i][j].a;
142
+ }
143
+ jacobian_ptr += num_residuals * parameter_block_sizes[i];
144
+ }
145
+
146
+ if (!cost_function_->Evaluate(parameter_blocks.data(),
147
+ residuals.data(),
148
+ jacobian_blocks.data())) {
149
+ return false;
150
+ }
151
+
152
+ // Now that we have the incoming Jets, which are carrying the
153
+ // partial derivatives of each of the inputs w.r.t to some other
154
+ // underlying parameters. The derivative of the outputs of the
155
+ // cost function w.r.t to the same underlying parameters can now
156
+ // be computed by applying the chain rule.
157
+ //
158
+ // d output[i] d output[i] d input[j]
159
+ // -------------- = sum_j ----------- * ------------
160
+ // d parameter[k] d input[j] d parameter[k]
161
+ //
162
+ // d input[j]
163
+ // -------------- = inputs[j], so
164
+ // d parameter[k]
165
+ //
166
+ // outputJet[i] = sum_k jacobian[i][k] * inputJet[k]
167
+ //
168
+ // The following loop, iterates over the residuals, computing one
169
+ // output jet at a time.
170
+ for (int i = 0; i < num_residuals; ++i) {
171
+ output[i].a = residuals[i];
172
+ output[i].v.setZero();
173
+
174
+ for (int j = 0; j < num_parameter_blocks; ++j) {
175
+ const int32_t block_size = parameter_block_sizes[j];
176
+ for (int k = 0; k < parameter_block_sizes[j]; ++k) {
177
+ output[i].v +=
178
+ jacobian_blocks[j][i * block_size + k] * inputs[j][k].v;
179
+ }
180
+ }
181
+ }
182
+
183
+ return true;
184
+ }
185
+
186
+ private:
187
+ std::unique_ptr<CostFunction> cost_function_;
188
+ };
189
+
190
+ } // namespace ceres
191
+
192
+ #include "ceres/internal/reenable_warnings.h"
193
+
194
+ #endif // CERES_PUBLIC_DYNAMIC_COST_FUNCTION_TO_FUNCTOR_H_
ceres-v2/include/dynamic_numeric_diff_cost_function.h ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: mierle@gmail.com (Keir Mierle)
30
+ // sameeragarwal@google.com (Sameer Agarwal)
31
+ // thadh@gmail.com (Thad Hughes)
32
+ // tbennun@gmail.com (Tal Ben-Nun)
33
+
34
+ #ifndef CERES_PUBLIC_DYNAMIC_NUMERIC_DIFF_COST_FUNCTION_H_
35
+ #define CERES_PUBLIC_DYNAMIC_NUMERIC_DIFF_COST_FUNCTION_H_
36
+
37
+ #include <cmath>
38
+ #include <memory>
39
+ #include <numeric>
40
+ #include <vector>
41
+
42
+ #include "ceres/dynamic_cost_function.h"
43
+ #include "ceres/internal/eigen.h"
44
+ #include "ceres/internal/numeric_diff.h"
45
+ #include "ceres/internal/parameter_dims.h"
46
+ #include "ceres/numeric_diff_options.h"
47
+ #include "ceres/types.h"
48
+ #include "glog/logging.h"
49
+
50
+ namespace ceres {
51
+
52
+ // This numeric diff implementation differs from the one found in
53
+ // numeric_diff_cost_function.h by supporting numericdiff on cost
54
+ // functions with variable numbers of parameters with variable
55
+ // sizes. With the other implementation, all the sizes (both the
56
+ // number of parameter blocks and the size of each block) must be
57
+ // fixed at compile time.
58
+ //
59
+ // The functor API differs slightly from the API for fixed size
60
+ // numeric diff; the expected interface for the cost functors is:
61
+ //
62
+ // struct MyCostFunctor {
63
+ // bool operator()(double const*
64
+ // const* parameters,
65
+ // double* residuals) const {
66
+ // // Use parameters[i] to access the i'th parameter block.
67
+ // }
68
+ // }
69
+ //
70
+ // Since the sizing of the parameters is done at runtime, you must
71
+ // also specify the sizes after creating the
72
+ // DynamicNumericDiffCostFunction. For example:
73
+ //
74
+ // DynamicAutoDiffCostFunction<MyCostFunctor, CENTRAL> cost_function(
75
+ // new MyCostFunctor());
76
+ // cost_function.AddParameterBlock(5);
77
+ // cost_function.AddParameterBlock(10);
78
+ // cost_function.SetNumResiduals(21);
79
+ template <typename CostFunctor, NumericDiffMethodType method = CENTRAL>
80
+ class DynamicNumericDiffCostFunction final : public DynamicCostFunction {
81
+ public:
82
+ explicit DynamicNumericDiffCostFunction(
83
+ const CostFunctor* functor,
84
+ Ownership ownership = TAKE_OWNERSHIP,
85
+ const NumericDiffOptions& options = NumericDiffOptions())
86
+ : functor_(functor), ownership_(ownership), options_(options) {}
87
+
88
+ DynamicNumericDiffCostFunction(DynamicNumericDiffCostFunction&& other)
89
+ : functor_(std::move(other.functor_)), ownership_(other.ownership_) {}
90
+
91
+ ~DynamicNumericDiffCostFunction() override {
92
+ if (ownership_ != TAKE_OWNERSHIP) {
93
+ functor_.release();
94
+ }
95
+ }
96
+
97
+ bool Evaluate(double const* const* parameters,
98
+ double* residuals,
99
+ double** jacobians) const override {
100
+ using internal::NumericDiff;
101
+ CHECK_GT(num_residuals(), 0)
102
+ << "You must call DynamicNumericDiffCostFunction::SetNumResiduals() "
103
+ << "before DynamicNumericDiffCostFunction::Evaluate().";
104
+
105
+ const std::vector<int32_t>& block_sizes = parameter_block_sizes();
106
+ CHECK(!block_sizes.empty())
107
+ << "You must call DynamicNumericDiffCostFunction::AddParameterBlock() "
108
+ << "before DynamicNumericDiffCostFunction::Evaluate().";
109
+
110
+ const bool status =
111
+ internal::VariadicEvaluate<internal::DynamicParameterDims>(
112
+ *functor_.get(), parameters, residuals);
113
+ if (jacobians == nullptr || !status) {
114
+ return status;
115
+ }
116
+
117
+ // Create local space for a copy of the parameters which will get mutated.
118
+ int parameters_size = accumulate(block_sizes.begin(), block_sizes.end(), 0);
119
+ std::vector<double> parameters_copy(parameters_size);
120
+ std::vector<double*> parameters_references_copy(block_sizes.size());
121
+ parameters_references_copy[0] = &parameters_copy[0];
122
+ for (size_t block = 1; block < block_sizes.size(); ++block) {
123
+ parameters_references_copy[block] =
124
+ parameters_references_copy[block - 1] + block_sizes[block - 1];
125
+ }
126
+
127
+ // Copy the parameters into the local temp space.
128
+ for (size_t block = 0; block < block_sizes.size(); ++block) {
129
+ memcpy(parameters_references_copy[block],
130
+ parameters[block],
131
+ block_sizes[block] * sizeof(*parameters[block]));
132
+ }
133
+
134
+ for (size_t block = 0; block < block_sizes.size(); ++block) {
135
+ if (jacobians[block] != nullptr &&
136
+ !NumericDiff<CostFunctor,
137
+ method,
138
+ ceres::DYNAMIC,
139
+ internal::DynamicParameterDims,
140
+ ceres::DYNAMIC,
141
+ ceres::DYNAMIC>::
142
+ EvaluateJacobianForParameterBlock(functor_.get(),
143
+ residuals,
144
+ options_,
145
+ this->num_residuals(),
146
+ block,
147
+ block_sizes[block],
148
+ &parameters_references_copy[0],
149
+ jacobians[block])) {
150
+ return false;
151
+ }
152
+ }
153
+ return true;
154
+ }
155
+
156
+ private:
157
+ std::unique_ptr<const CostFunctor> functor_;
158
+ Ownership ownership_;
159
+ NumericDiffOptions options_;
160
+ };
161
+
162
+ } // namespace ceres
163
+
164
+ #endif // CERES_PUBLIC_DYNAMIC_AUTODIFF_COST_FUNCTION_H_
ceres-v2/include/evaluation_callback.h ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: mierle@gmail.com (Keir Mierle)
30
+
31
+ #ifndef CERES_PUBLIC_EVALUATION_CALLBACK_H_
32
+ #define CERES_PUBLIC_EVALUATION_CALLBACK_H_
33
+
34
+ #include "ceres/internal/export.h"
35
+
36
+ namespace ceres {
37
+
38
+ // Using this callback interface, Ceres can notify you when it is
39
+ // about to evaluate the residuals or jacobians. With the callback,
40
+ // you can share computation between residual blocks by doing the
41
+ // shared computation in PrepareForEvaluation() before Ceres calls
42
+ // CostFunction::Evaluate(). It also enables caching results between a
43
+ // pure residual evaluation and a residual & jacobian evaluation, via
44
+ // the new_evaluation_point argument.
45
+ //
46
+ // One use case for this callback is if the cost function compute is
47
+ // moved to the GPU. In that case, the prepare call does the actual
48
+ // cost function evaluation, and subsequent calls from Ceres to the
49
+ // actual cost functions merely copy the results from the GPU onto the
50
+ // corresponding blocks for Ceres to plug into the solver.
51
+ //
52
+ // NOTE: Ceres provides no mechanism to share data other than the
53
+ // notification from the callback. Users must provide access to
54
+ // pre-computed shared data to their cost functions behind the scenes;
55
+ // this all happens without Ceres knowing.
56
+ //
57
+ // One approach is to put a pointer to the shared data in each cost
58
+ // function (recommended) or to use a global shared variable
59
+ // (discouraged; bug-prone). As far as Ceres is concerned, it is
60
+ // evaluating cost functions like any other; it just so happens that
61
+ // behind the scenes the cost functions reuse pre-computed data to
62
+ // execute faster.
63
+ class CERES_EXPORT EvaluationCallback {
64
+ public:
65
+ virtual ~EvaluationCallback();
66
+
67
+ // Called before Ceres requests residuals or jacobians for a given setting of
68
+ // the parameters. User parameters (the double* values provided to the cost
69
+ // functions) are fixed until the next call to PrepareForEvaluation(). If
70
+ // new_evaluation_point == true, then this is a new point that is different
71
+ // from the last evaluated point. Otherwise, it is the same point that was
72
+ // evaluated previously (either jacobian or residual) and the user can use
73
+ // cached results from previous evaluations.
74
+ virtual void PrepareForEvaluation(bool evaluate_jacobians,
75
+ bool new_evaluation_point) = 0;
76
+ };
77
+
78
+ } // namespace ceres
79
+
80
+ #endif // CERES_PUBLIC_EVALUATION_CALLBACK_H_
ceres-v2/include/first_order_function.h ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #ifndef CERES_PUBLIC_FIRST_ORDER_FUNCTION_H_
32
+ #define CERES_PUBLIC_FIRST_ORDER_FUNCTION_H_
33
+
34
+ #include "ceres/internal/export.h"
35
+
36
+ namespace ceres {
37
+
38
+ // A FirstOrderFunction object implements the evaluation of a function
39
+ // and its gradient.
40
+ class CERES_EXPORT FirstOrderFunction {
41
+ public:
42
+ virtual ~FirstOrderFunction();
43
+
44
+ // cost is never null. gradient may be null. The return value
45
+ // indicates whether the evaluation was successful or not.
46
+ virtual bool Evaluate(const double* const parameters,
47
+ double* cost,
48
+ double* gradient) const = 0;
49
+ virtual int NumParameters() const = 0;
50
+ };
51
+
52
+ } // namespace ceres
53
+
54
+ #endif // CERES_PUBLIC_FIRST_ORDER_FUNCTION_H_
ceres-v2/include/gradient_checker.h ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ // Copyright 2007 Google Inc. All Rights Reserved.
29
+ //
30
+ // Authors: wjr@google.com (William Rucklidge),
31
+ // keir@google.com (Keir Mierle),
32
+ // dgossow@google.com (David Gossow)
33
+
34
+ #ifndef CERES_PUBLIC_GRADIENT_CHECKER_H_
35
+ #define CERES_PUBLIC_GRADIENT_CHECKER_H_
36
+
37
+ #include <memory>
38
+ #include <string>
39
+ #include <vector>
40
+
41
+ #include "ceres/cost_function.h"
42
+ #include "ceres/dynamic_numeric_diff_cost_function.h"
43
+ #include "ceres/internal/disable_warnings.h"
44
+ #include "ceres/internal/eigen.h"
45
+ #include "ceres/internal/export.h"
46
+ #include "ceres/internal/fixed_array.h"
47
+ #include "ceres/local_parameterization.h"
48
+ #include "ceres/manifold.h"
49
+ #include "glog/logging.h"
50
+
51
+ namespace ceres {
52
+
53
+ // GradientChecker compares the Jacobians returned by a cost function against
54
+ // derivatives estimated using finite differencing.
55
+ //
56
+ // The condition enforced is that
57
+ //
58
+ // (J_actual(i, j) - J_numeric(i, j))
59
+ // ------------------------------------ < relative_precision
60
+ // max(J_actual(i, j), J_numeric(i, j))
61
+ //
62
+ // where J_actual(i, j) is the jacobian as computed by the supplied cost
63
+ // function (by the user) multiplied by the local parameterization Jacobian
64
+ // and J_numeric is the jacobian as computed by finite differences, multiplied
65
+ // by the local parameterization Jacobian as well.
66
+ //
67
+ // How to use: Fill in an array of pointers to parameter blocks for your
68
+ // CostFunction, and then call Probe(). Check that the return value is 'true'.
69
+ class CERES_EXPORT GradientChecker {
70
+ public:
71
+ // This constructor will not take ownership of the cost function or local
72
+ // parameterizations.
73
+ //
74
+ // function: The cost function to probe.
75
+ //
76
+ // local_parameterizations: A vector of local parameterizations, one for each
77
+ // parameter block. May be nullptr or contain nullptrs to indicate that the
78
+ // respective parameter does not have a local parameterization.
79
+ //
80
+ // options: Options to use for numerical differentiation.
81
+ //
82
+ // NOTE: This constructor is deprecated and will be removed in the next public
83
+ // release of Ceres Solver. Please transition to using the Manifold based
84
+ // version.
85
+ CERES_DEPRECATED_WITH_MSG(
86
+ "Local Parameterizations are deprecated. Use the constructor that uses "
87
+ "Manifolds instead.")
88
+ GradientChecker(
89
+ const CostFunction* function,
90
+ const std::vector<const LocalParameterization*>* local_parameterizations,
91
+ const NumericDiffOptions& options);
92
+
93
+ // This will not take ownership of the cost function or manifolds.
94
+ //
95
+ // function: The cost function to probe.
96
+ //
97
+ // manifolds: A vector of manifolds for each parameter. May be nullptr or
98
+ // contain nullptrs to indicate that the respective parameter blocks are
99
+ // Euclidean.
100
+ //
101
+ // options: Options to use for numerical differentiation.
102
+ GradientChecker(const CostFunction* function,
103
+ const std::vector<const Manifold*>* manifolds,
104
+ const NumericDiffOptions& options);
105
+ ~GradientChecker();
106
+
107
+ // Contains results from a call to Probe for later inspection.
108
+ struct CERES_EXPORT ProbeResults {
109
+ // The return value of the cost function.
110
+ bool return_value;
111
+
112
+ // Computed residual vector.
113
+ Vector residuals;
114
+
115
+ // The sizes of the Jacobians below are dictated by the cost function's
116
+ // parameter block size and residual block sizes. If a parameter block has a
117
+ // manifold associated with it, the size of the "local" Jacobian will be
118
+ // determined by the dimension of the manifold (which is the same as the
119
+ // dimension of the tangent space) and residual block size, otherwise it
120
+ // will be identical to the regular Jacobian.
121
+
122
+ // Derivatives as computed by the cost function.
123
+ std::vector<Matrix> jacobians;
124
+
125
+ // Derivatives as computed by the cost function in local space.
126
+ std::vector<Matrix> local_jacobians;
127
+
128
+ // Derivatives as computed by numerical differentiation in local space.
129
+ std::vector<Matrix> numeric_jacobians;
130
+
131
+ // Derivatives as computed by numerical differentiation in local space.
132
+ std::vector<Matrix> local_numeric_jacobians;
133
+
134
+ // Contains the maximum relative error found in the local Jacobians.
135
+ double maximum_relative_error;
136
+
137
+ // If an error was detected, this will contain a detailed description of
138
+ // that error.
139
+ std::string error_log;
140
+ };
141
+
142
+ // Call the cost function, compute alternative Jacobians using finite
143
+ // differencing and compare results. If manifolds are given, the Jacobians
144
+ // will be multiplied by the manifold Jacobians before performing the check,
145
+ // which effectively means that all errors along the null space of the
146
+ // manifold will be ignored. Returns false if the Jacobians don't match, the
147
+ // cost function return false, or if a cost function returns a different
148
+ // residual when called with a Jacobian output argument vs. calling it
149
+ // without. Otherwise returns true.
150
+ //
151
+ // parameters: The parameter values at which to probe.
152
+ // relative_precision: A threshold for the relative difference between the
153
+ // Jacobians. If the Jacobians differ by more than this amount, then the
154
+ // probe fails.
155
+ // results: On return, the Jacobians (and other information) will be stored
156
+ // here. May be nullptr.
157
+ //
158
+ // Returns true if no problems are detected and the difference between the
159
+ // Jacobians is less than error_tolerance.
160
+ bool Probe(double const* const* parameters,
161
+ double relative_precision,
162
+ ProbeResults* results) const;
163
+
164
+ private:
165
+ GradientChecker() = delete;
166
+ GradientChecker(const GradientChecker&) = delete;
167
+ void operator=(const GradientChecker&) = delete;
168
+
169
+ // This bool is used to determine whether the constructor with the
170
+ // LocalParameterizations is called or the one with Manifolds is called. If
171
+ // the former, then the vector of manifolds is a vector of ManifoldAdapter
172
+ // objects which we own and should be deleted. If the latter then they are
173
+ // real Manifold objects owned by the caller and will not be deleted.
174
+ //
175
+ // This bool is only needed during the LocalParameterization to Manifold
176
+ // transition, once this transition is complete the LocalParameterization
177
+ // based constructor and this bool will be removed.
178
+ const bool delete_manifolds_ = false;
179
+
180
+ std::vector<const Manifold*> manifolds_;
181
+ const CostFunction* function_;
182
+ std::unique_ptr<CostFunction> finite_diff_cost_function_;
183
+ };
184
+
185
+ } // namespace ceres
186
+
187
+ #include "ceres/internal/reenable_warnings.h"
188
+
189
+ #endif // CERES_PUBLIC_GRADIENT_CHECKER_H_
ceres-v2/include/gradient_problem.h ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #ifndef CERES_PUBLIC_GRADIENT_PROBLEM_H_
32
+ #define CERES_PUBLIC_GRADIENT_PROBLEM_H_
33
+
34
+ #include <memory>
35
+
36
+ #include "ceres/first_order_function.h"
37
+ #include "ceres/internal/disable_warnings.h"
38
+ #include "ceres/internal/export.h"
39
+ #include "ceres/local_parameterization.h"
40
+ #include "ceres/manifold.h"
41
+
42
+ namespace ceres {
43
+
44
+ class FirstOrderFunction;
45
+
46
+ // Instances of GradientProblem represent general non-linear
47
+ // optimization problems that must be solved using just the value of
48
+ // the objective function and its gradient.
49
+
50
+ // Unlike the Problem class, which can only be used to model non-linear least
51
+ // squares problems, instances of GradientProblem are not restricted in the form
52
+ // of the objective function.
53
+ //
54
+ // Structurally GradientProblem is a composition of a FirstOrderFunction and
55
+ // optionally a Manifold.
56
+ //
57
+ // The FirstOrderFunction is responsible for evaluating the cost and gradient of
58
+ // the objective function.
59
+ //
60
+ // The Manifold is responsible for going back and forth between the ambient
61
+ // space and the local tangent space. (See manifold.h for more details). When a
62
+ // Manifold is not provided, then the tangent space is assumed to coincide with
63
+ // the ambient Euclidean space that the gradient vector lives in.
64
+ //
65
+ // Example usage:
66
+ //
67
+ // The following demonstrate the problem construction for Rosenbrock's function
68
+ //
69
+ // f(x,y) = (1-x)^2 + 100(y - x^2)^2;
70
+ //
71
+ // class Rosenbrock : public ceres::FirstOrderFunction {
72
+ // public:
73
+ // virtual ~Rosenbrock() {}
74
+ //
75
+ // virtual bool Evaluate(const double* parameters,
76
+ // double* cost,
77
+ // double* gradient) const {
78
+ // const double x = parameters[0];
79
+ // const double y = parameters[1];
80
+ //
81
+ // cost[0] = (1.0 - x) * (1.0 - x) + 100.0 * (y - x * x) * (y - x * x);
82
+ // if (gradient != nullptr) {
83
+ // gradient[0] = -2.0 * (1.0 - x) - 200.0 * (y - x * x) * 2.0 * x;
84
+ // gradient[1] = 200.0 * (y - x * x);
85
+ // }
86
+ // return true;
87
+ // };
88
+ //
89
+ // virtual int NumParameters() const { return 2; };
90
+ // };
91
+ //
92
+ // ceres::GradientProblem problem(new Rosenbrock());
93
+ //
94
+ // NOTE: We are currently in the process of transitioning from
95
+ // LocalParameterization to Manifolds in the Ceres API. During this period,
96
+ // GradientProblem will support using both Manifold and LocalParameterization
97
+ // objects interchangably. For methods in the API affected by this change, see
98
+ // their documentation below.
99
+ class CERES_EXPORT GradientProblem {
100
+ public:
101
+ // Takes ownership of the function.
102
+ explicit GradientProblem(FirstOrderFunction* function);
103
+
104
+ // Takes ownership of the function and the parameterization.
105
+ //
106
+ // NOTE: This constructor is deprecated and will be removed in the next public
107
+ // release of Ceres Solver. Please move to using the Manifold based
108
+ // constructor.
109
+ CERES_DEPRECATED_WITH_MSG(
110
+ "LocalParameterizations are deprecated. Please use the constructor that "
111
+ "uses Manifold instead.")
112
+ GradientProblem(FirstOrderFunction* function,
113
+ LocalParameterization* parameterization);
114
+
115
+ // Takes ownership of the function and the manifold.
116
+ GradientProblem(FirstOrderFunction* function, Manifold* manifold);
117
+
118
+ int NumParameters() const;
119
+
120
+ // Dimension of the manifold (and its tangent space).
121
+ //
122
+ // During the transition from LocalParameterization to Manifold, this method
123
+ // reports the LocalSize of the LocalParameterization or the TangentSize of
124
+ // the Manifold object associated with this problem.
125
+ int NumTangentParameters() const;
126
+
127
+ // Dimension of the manifold (and its tangent space).
128
+ //
129
+ // NOTE: This method is deprecated and will be removed in the next public
130
+ // release of Ceres Solver. Please move to using NumTangentParameters()
131
+ // instead.
132
+ int NumLocalParameters() const { return NumTangentParameters(); }
133
+
134
+ // This call is not thread safe.
135
+ bool Evaluate(const double* parameters, double* cost, double* gradient) const;
136
+ bool Plus(const double* x, const double* delta, double* x_plus_delta) const;
137
+
138
+ const FirstOrderFunction* function() const { return function_.get(); }
139
+ FirstOrderFunction* mutable_function() { return function_.get(); }
140
+
141
+ // NOTE: During the transition from LocalParameterization to Manifold we need
142
+ // to support both The LocalParameterization and Manifold based constructors.
143
+ //
144
+ // When the user uses the LocalParameterization, internally the solver will
145
+ // wrap it in a ManifoldAdapter object and return it when manifold or
146
+ // mutable_manifold are called.
147
+ //
148
+ // As a result this method will return a non-nullptr result if a Manifold or a
149
+ // LocalParameterization was used when constructing the GradientProblem.
150
+ const Manifold* manifold() const { return manifold_.get(); }
151
+ Manifold* mutable_manifold() { return manifold_.get(); }
152
+
153
+ // If the problem is constructed without a LocalParameterization or with a
154
+ // Manifold this method will return a nullptr.
155
+ //
156
+ // NOTE: This method is deprecated and will be removed in the next public
157
+ // release of Ceres Solver.
158
+ CERES_DEPRECATED_WITH_MSG("Use Manifolds instead.")
159
+ const LocalParameterization* parameterization() const {
160
+ return parameterization_.get();
161
+ }
162
+
163
+ // If the problem is constructed without a LocalParameterization or with a
164
+ // Manifold this method will return a nullptr.
165
+ //
166
+ // NOTE: This method is deprecated and will be removed in the next public
167
+ // release of Ceres Solver.
168
+ CERES_DEPRECATED_WITH_MSG("Use Manifolds instead.")
169
+ LocalParameterization* mutable_parameterization() {
170
+ return parameterization_.get();
171
+ }
172
+
173
+ private:
174
+ std::unique_ptr<FirstOrderFunction> function_;
175
+ CERES_DEPRECATED_WITH_MSG("")
176
+ std::unique_ptr<LocalParameterization> parameterization_;
177
+ std::unique_ptr<Manifold> manifold_;
178
+ std::unique_ptr<double[]> scratch_;
179
+ };
180
+
181
+ } // namespace ceres
182
+
183
+ #include "ceres/internal/reenable_warnings.h"
184
+
185
+ #endif // CERES_PUBLIC_GRADIENT_PROBLEM_H_
ceres-v2/include/gradient_problem_solver.h ADDED
@@ -0,0 +1,357 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #ifndef CERES_PUBLIC_GRADIENT_PROBLEM_SOLVER_H_
32
+ #define CERES_PUBLIC_GRADIENT_PROBLEM_SOLVER_H_
33
+
34
+ #include <cmath>
35
+ #include <string>
36
+ #include <vector>
37
+
38
+ #include "ceres/internal/disable_warnings.h"
39
+ #include "ceres/internal/export.h"
40
+ #include "ceres/internal/port.h"
41
+ #include "ceres/iteration_callback.h"
42
+ #include "ceres/types.h"
43
+
44
+ namespace ceres {
45
+
46
+ class GradientProblem;
47
+
48
+ class CERES_EXPORT GradientProblemSolver {
49
+ public:
50
+ virtual ~GradientProblemSolver();
51
+
52
+ // The options structure contains, not surprisingly, options that control how
53
+ // the solver operates. The defaults should be suitable for a wide range of
54
+ // problems; however, better performance is often obtainable with tweaking.
55
+ //
56
+ // The constants are defined inside types.h
57
+ struct CERES_EXPORT Options {
58
+ // Returns true if the options struct has a valid
59
+ // configuration. Returns false otherwise, and fills in *error
60
+ // with a message describing the problem.
61
+ bool IsValid(std::string* error) const;
62
+
63
+ // Minimizer options ----------------------------------------
64
+ LineSearchDirectionType line_search_direction_type = LBFGS;
65
+ LineSearchType line_search_type = WOLFE;
66
+ NonlinearConjugateGradientType nonlinear_conjugate_gradient_type =
67
+ FLETCHER_REEVES;
68
+
69
+ // The LBFGS hessian approximation is a low rank approximation to
70
+ // the inverse of the Hessian matrix. The rank of the
71
+ // approximation determines (linearly) the space and time
72
+ // complexity of using the approximation. Higher the rank, the
73
+ // better is the quality of the approximation. The increase in
74
+ // quality is however is bounded for a number of reasons.
75
+ //
76
+ // 1. The method only uses secant information and not actual
77
+ // derivatives.
78
+ //
79
+ // 2. The Hessian approximation is constrained to be positive
80
+ // definite.
81
+ //
82
+ // So increasing this rank to a large number will cost time and
83
+ // space complexity without the corresponding increase in solution
84
+ // quality. There are no hard and fast rules for choosing the
85
+ // maximum rank. The best choice usually requires some problem
86
+ // specific experimentation.
87
+ //
88
+ // For more theoretical and implementation details of the LBFGS
89
+ // method, please see:
90
+ //
91
+ // Nocedal, J. (1980). "Updating Quasi-Newton Matrices with
92
+ // Limited Storage". Mathematics of Computation 35 (151): 773-782.
93
+ int max_lbfgs_rank = 20;
94
+
95
+ // As part of the (L)BFGS update step (BFGS) / right-multiply step (L-BFGS),
96
+ // the initial inverse Hessian approximation is taken to be the Identity.
97
+ // However, Oren showed that using instead I * \gamma, where \gamma is
98
+ // chosen to approximate an eigenvalue of the true inverse Hessian can
99
+ // result in improved convergence in a wide variety of cases. Setting
100
+ // use_approximate_eigenvalue_bfgs_scaling to true enables this scaling.
101
+ //
102
+ // It is important to note that approximate eigenvalue scaling does not
103
+ // always improve convergence, and that it can in fact significantly degrade
104
+ // performance for certain classes of problem, which is why it is disabled
105
+ // by default. In particular it can degrade performance when the
106
+ // sensitivity of the problem to different parameters varies significantly,
107
+ // as in this case a single scalar factor fails to capture this variation
108
+ // and detrimentally downscales parts of the jacobian approximation which
109
+ // correspond to low-sensitivity parameters. It can also reduce the
110
+ // robustness of the solution to errors in the jacobians.
111
+ //
112
+ // Oren S.S., Self-scaling variable metric (SSVM) algorithms
113
+ // Part II: Implementation and experiments, Management Science,
114
+ // 20(5), 863-874, 1974.
115
+ bool use_approximate_eigenvalue_bfgs_scaling = false;
116
+
117
+ // Degree of the polynomial used to approximate the objective
118
+ // function. Valid values are BISECTION, QUADRATIC and CUBIC.
119
+ //
120
+ // BISECTION corresponds to pure backtracking search with no
121
+ // interpolation.
122
+ LineSearchInterpolationType line_search_interpolation_type = CUBIC;
123
+
124
+ // If during the line search, the step_size falls below this
125
+ // value, it is truncated to zero.
126
+ double min_line_search_step_size = 1e-9;
127
+
128
+ // Line search parameters.
129
+
130
+ // Solving the line search problem exactly is computationally
131
+ // prohibitive. Fortunately, line search based optimization
132
+ // algorithms can still guarantee convergence if instead of an
133
+ // exact solution, the line search algorithm returns a solution
134
+ // which decreases the value of the objective function
135
+ // sufficiently. More precisely, we are looking for a step_size
136
+ // s.t.
137
+ //
138
+ // f(step_size) <= f(0) + sufficient_decrease * f'(0) * step_size
139
+ //
140
+ double line_search_sufficient_function_decrease = 1e-4;
141
+
142
+ // In each iteration of the line search,
143
+ //
144
+ // new_step_size >= max_line_search_step_contraction * step_size
145
+ //
146
+ // Note that by definition, for contraction:
147
+ //
148
+ // 0 < max_step_contraction < min_step_contraction < 1
149
+ //
150
+ double max_line_search_step_contraction = 1e-3;
151
+
152
+ // In each iteration of the line search,
153
+ //
154
+ // new_step_size <= min_line_search_step_contraction * step_size
155
+ //
156
+ // Note that by definition, for contraction:
157
+ //
158
+ // 0 < max_step_contraction < min_step_contraction < 1
159
+ //
160
+ double min_line_search_step_contraction = 0.6;
161
+
162
+ // Maximum number of trial step size iterations during each line search,
163
+ // if a step size satisfying the search conditions cannot be found within
164
+ // this number of trials, the line search will terminate.
165
+ int max_num_line_search_step_size_iterations = 20;
166
+
167
+ // Maximum number of restarts of the line search direction algorithm before
168
+ // terminating the optimization. Restarts of the line search direction
169
+ // algorithm occur when the current algorithm fails to produce a new descent
170
+ // direction. This typically indicates a numerical failure, or a breakdown
171
+ // in the validity of the approximations used.
172
+ int max_num_line_search_direction_restarts = 5;
173
+
174
+ // The strong Wolfe conditions consist of the Armijo sufficient
175
+ // decrease condition, and an additional requirement that the
176
+ // step-size be chosen s.t. the _magnitude_ ('strong' Wolfe
177
+ // conditions) of the gradient along the search direction
178
+ // decreases sufficiently. Precisely, this second condition
179
+ // is that we seek a step_size s.t.
180
+ //
181
+ // |f'(step_size)| <= sufficient_curvature_decrease * |f'(0)|
182
+ //
183
+ // Where f() is the line search objective and f'() is the derivative
184
+ // of f w.r.t step_size (d f / d step_size).
185
+ double line_search_sufficient_curvature_decrease = 0.9;
186
+
187
+ // During the bracketing phase of the Wolfe search, the step size is
188
+ // increased until either a point satisfying the Wolfe conditions is
189
+ // found, or an upper bound for a bracket containing a point satisfying
190
+ // the conditions is found. Precisely, at each iteration of the
191
+ // expansion:
192
+ //
193
+ // new_step_size <= max_step_expansion * step_size.
194
+ //
195
+ // By definition for expansion, max_step_expansion > 1.0.
196
+ double max_line_search_step_expansion = 10.0;
197
+
198
+ // Maximum number of iterations for the minimizer to run for.
199
+ int max_num_iterations = 50;
200
+
201
+ // Maximum time for which the minimizer should run for.
202
+ double max_solver_time_in_seconds = 1e9;
203
+
204
+ // Minimizer terminates when
205
+ //
206
+ // (new_cost - old_cost) < function_tolerance * old_cost;
207
+ //
208
+ double function_tolerance = 1e-6;
209
+
210
+ // Minimizer terminates when
211
+ //
212
+ // max_i |x - Project(Plus(x, -g(x))| < gradient_tolerance
213
+ //
214
+ // This value should typically be 1e-4 * function_tolerance.
215
+ double gradient_tolerance = 1e-10;
216
+
217
+ // Minimizer terminates when
218
+ //
219
+ // |step|_2 <= parameter_tolerance * ( |x|_2 + parameter_tolerance)
220
+ //
221
+ double parameter_tolerance = 1e-8;
222
+
223
+ // Logging options ---------------------------------------------------------
224
+
225
+ LoggingType logging_type = PER_MINIMIZER_ITERATION;
226
+
227
+ // By default the Minimizer progress is logged to VLOG(1), which
228
+ // is sent to STDERR depending on the vlog level. If this flag is
229
+ // set to true, and logging_type is not SILENT, the logging output
230
+ // is sent to STDOUT.
231
+ bool minimizer_progress_to_stdout = false;
232
+
233
+ // If true, the user's parameter blocks are updated at the end of
234
+ // every Minimizer iteration, otherwise they are updated when the
235
+ // Minimizer terminates. This is useful if, for example, the user
236
+ // wishes to visualize the state of the optimization every
237
+ // iteration.
238
+ bool update_state_every_iteration = false;
239
+
240
+ // Callbacks that are executed at the end of each iteration of the
241
+ // Minimizer. An iteration may terminate midway, either due to
242
+ // numerical failures or because one of the convergence tests has
243
+ // been satisfied. In this case none of the callbacks are
244
+ // executed.
245
+
246
+ // Callbacks are executed in the order that they are specified in
247
+ // this vector. By default, parameter blocks are updated only at
248
+ // the end of the optimization, i.e when the Minimizer
249
+ // terminates. This behaviour is controlled by
250
+ // update_state_every_variable. If the user wishes to have access
251
+ // to the update parameter blocks when his/her callbacks are
252
+ // executed, then set update_state_every_iteration to true.
253
+ //
254
+ // The solver does NOT take ownership of these pointers.
255
+ std::vector<IterationCallback*> callbacks;
256
+ };
257
+
258
+ struct CERES_EXPORT Summary {
259
+ // A brief one line description of the state of the solver after
260
+ // termination.
261
+ std::string BriefReport() const;
262
+
263
+ // A full multiline description of the state of the solver after
264
+ // termination.
265
+ std::string FullReport() const;
266
+
267
+ bool IsSolutionUsable() const;
268
+
269
+ // Minimizer summary -------------------------------------------------
270
+ TerminationType termination_type = FAILURE;
271
+
272
+ // Reason why the solver terminated.
273
+ std::string message = "ceres::GradientProblemSolve was not called.";
274
+
275
+ // Cost of the problem (value of the objective function) before
276
+ // the optimization.
277
+ double initial_cost = -1.0;
278
+
279
+ // Cost of the problem (value of the objective function) after the
280
+ // optimization.
281
+ double final_cost = -1.0;
282
+
283
+ // IterationSummary for each minimizer iteration in order.
284
+ std::vector<IterationSummary> iterations;
285
+
286
+ // Number of times the cost (and not the gradient) was evaluated.
287
+ int num_cost_evaluations = -1;
288
+
289
+ // Number of times the gradient (and the cost) were evaluated.
290
+ int num_gradient_evaluations = -1;
291
+
292
+ // Sum total of all time spent inside Ceres when Solve is called.
293
+ double total_time_in_seconds = -1.0;
294
+
295
+ // Time (in seconds) spent evaluating the cost.
296
+ double cost_evaluation_time_in_seconds = -1.0;
297
+
298
+ // Time (in seconds) spent evaluating the gradient.
299
+ double gradient_evaluation_time_in_seconds = -1.0;
300
+
301
+ // Time (in seconds) spent minimizing the interpolating polynomial
302
+ // to compute the next candidate step size as part of a line search.
303
+ double line_search_polynomial_minimization_time_in_seconds = -1.0;
304
+
305
+ // Number of parameters in the problem.
306
+ int num_parameters = -1;
307
+
308
+ // Dimension of the tangent space of the problem.
309
+ CERES_DEPRECATED_WITH_MSG("Use num_tangent_parameters.")
310
+ int num_local_parameters = -1;
311
+
312
+ // Dimension of the tangent space of the problem.
313
+ int num_tangent_parameters = -1;
314
+
315
+ // Type of line search direction used.
316
+ LineSearchDirectionType line_search_direction_type = LBFGS;
317
+
318
+ // Type of the line search algorithm used.
319
+ LineSearchType line_search_type = WOLFE;
320
+
321
+ // When performing line search, the degree of the polynomial used
322
+ // to approximate the objective function.
323
+ LineSearchInterpolationType line_search_interpolation_type = CUBIC;
324
+
325
+ // If the line search direction is NONLINEAR_CONJUGATE_GRADIENT,
326
+ // then this indicates the particular variant of non-linear
327
+ // conjugate gradient used.
328
+ NonlinearConjugateGradientType nonlinear_conjugate_gradient_type =
329
+ FLETCHER_REEVES;
330
+
331
+ // If the type of the line search direction is LBFGS, then this
332
+ // indicates the rank of the Hessian approximation.
333
+ int max_lbfgs_rank = -1;
334
+ };
335
+
336
+ // Once a least squares problem has been built, this function takes
337
+ // the problem and optimizes it based on the values of the options
338
+ // parameters. Upon return, a detailed summary of the work performed
339
+ // by the preprocessor, the non-linear minimizer and the linear
340
+ // solver are reported in the summary object.
341
+ virtual void Solve(const GradientProblemSolver::Options& options,
342
+ const GradientProblem& problem,
343
+ double* parameters,
344
+ GradientProblemSolver::Summary* summary);
345
+ };
346
+
347
+ // Helper function which avoids going through the interface.
348
+ CERES_EXPORT void Solve(const GradientProblemSolver::Options& options,
349
+ const GradientProblem& problem,
350
+ double* parameters,
351
+ GradientProblemSolver::Summary* summary);
352
+
353
+ } // namespace ceres
354
+
355
+ #include "ceres/internal/reenable_warnings.h"
356
+
357
+ #endif // CERES_PUBLIC_GRADIENT_PROBLEM_SOLVER_H_
ceres-v2/include/internal/array_selector.h ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2020 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: darius.rueckert@fau.de (Darius Rueckert)
30
+ //
31
+
32
+ #ifndef CERES_PUBLIC_INTERNAL_ARRAY_SELECTOR_H_
33
+ #define CERES_PUBLIC_INTERNAL_ARRAY_SELECTOR_H_
34
+
35
+ #include <array>
36
+ #include <vector>
37
+
38
+ #include "ceres/internal/fixed_array.h"
39
+ #include "ceres/types.h"
40
+
41
+ namespace ceres {
42
+ namespace internal {
43
+
44
+ // StaticFixedArray selects the best array implementation based on template
45
+ // arguments. If the size is not known at compile-time, pass
46
+ // ceres::DYNAMIC as a size-template argument.
47
+ //
48
+ // Three different containers are selected in different scenarios:
49
+ //
50
+ // num_elements == DYNAMIC:
51
+ // -> ceres::internal::FixedArray<T, max_stack_size>(size)
52
+
53
+ // num_elements != DYNAMIC && num_elements <= max_stack_size
54
+ // -> std::array<T,num_elements>
55
+
56
+ // num_elements != DYNAMIC && num_elements > max_stack_size
57
+ // -> std::vector<T>(num_elements)
58
+ //
59
+ template <typename T,
60
+ int num_elements,
61
+ int max_num_elements_on_stack,
62
+ bool dynamic = (num_elements == DYNAMIC),
63
+ bool fits_on_stack = (num_elements <= max_num_elements_on_stack)>
64
+ struct ArraySelector {};
65
+
66
+ template <typename T,
67
+ int num_elements,
68
+ int max_num_elements_on_stack,
69
+ bool fits_on_stack>
70
+ struct ArraySelector<T,
71
+ num_elements,
72
+ max_num_elements_on_stack,
73
+ true,
74
+ fits_on_stack>
75
+ : ceres::internal::FixedArray<T, max_num_elements_on_stack> {
76
+ explicit ArraySelector(int s)
77
+ : ceres::internal::FixedArray<T, max_num_elements_on_stack>(s) {}
78
+ };
79
+
80
+ template <typename T, int num_elements, int max_num_elements_on_stack>
81
+ struct ArraySelector<T, num_elements, max_num_elements_on_stack, false, true>
82
+ : std::array<T, num_elements> {
83
+ explicit ArraySelector(int s) { CHECK_EQ(s, num_elements); }
84
+ };
85
+
86
+ template <typename T, int num_elements, int max_num_elements_on_stack>
87
+ struct ArraySelector<T, num_elements, max_num_elements_on_stack, false, false>
88
+ : std::vector<T> {
89
+ explicit ArraySelector(int s) : std::vector<T>(s) {
90
+ CHECK_EQ(s, num_elements);
91
+ }
92
+ };
93
+
94
+ } // namespace internal
95
+ } // namespace ceres
96
+
97
+ #endif // CERES_PUBLIC_INTERNAL_ARRAY_SELECTOR_H_
ceres-v2/include/internal/autodiff.h ADDED
@@ -0,0 +1,365 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: keir@google.com (Keir Mierle)
30
+ //
31
+ // Computation of the Jacobian matrix for vector-valued functions of multiple
32
+ // variables, using automatic differentiation based on the implementation of
33
+ // dual numbers in jet.h. Before reading the rest of this file, it is advisable
34
+ // to read jet.h's header comment in detail.
35
+ //
36
+ // The helper wrapper AutoDifferentiate() computes the jacobian of
37
+ // functors with templated operator() taking this form:
38
+ //
39
+ // struct F {
40
+ // template<typename T>
41
+ // bool operator()(const T *x, const T *y, ..., T *z) {
42
+ // // Compute z[] based on x[], y[], ...
43
+ // // return true if computation succeeded, false otherwise.
44
+ // }
45
+ // };
46
+ //
47
+ // All inputs and outputs may be vector-valued.
48
+ //
49
+ // To understand how jets are used to compute the jacobian, a
50
+ // picture may help. Consider a vector-valued function, F, returning 3
51
+ // dimensions and taking a vector-valued parameter of 4 dimensions:
52
+ //
53
+ // y x
54
+ // [ * ] F [ * ]
55
+ // [ * ] <--- [ * ]
56
+ // [ * ] [ * ]
57
+ // [ * ]
58
+ //
59
+ // Similar to the 2-parameter example for f described in jet.h, computing the
60
+ // jacobian dy/dx is done by substituting a suitable jet object for x and all
61
+ // intermediate steps of the computation of F. Since x is has 4 dimensions, use
62
+ // a Jet<double, 4>.
63
+ //
64
+ // Before substituting a jet object for x, the dual components are set
65
+ // appropriately for each dimension of x:
66
+ //
67
+ // y x
68
+ // [ * | * * * * ] f [ * | 1 0 0 0 ] x0
69
+ // [ * | * * * * ] <--- [ * | 0 1 0 0 ] x1
70
+ // [ * | * * * * ] [ * | 0 0 1 0 ] x2
71
+ // ---+--- [ * | 0 0 0 1 ] x3
72
+ // | ^ ^ ^ ^
73
+ // dy/dx | | | +----- infinitesimal for x3
74
+ // | | +------- infinitesimal for x2
75
+ // | +--------- infinitesimal for x1
76
+ // +----------- infinitesimal for x0
77
+ //
78
+ // The reason to set the internal 4x4 submatrix to the identity is that we wish
79
+ // to take the derivative of y separately with respect to each dimension of x.
80
+ // Each column of the 4x4 identity is therefore for a single component of the
81
+ // independent variable x.
82
+ //
83
+ // Then the jacobian of the mapping, dy/dx, is the 3x4 sub-matrix of the
84
+ // extended y vector, indicated in the above diagram.
85
+ //
86
+ // Functors with multiple parameters
87
+ // ---------------------------------
88
+ // In practice, it is often convenient to use a function f of two or more
89
+ // vector-valued parameters, for example, x[3] and z[6]. Unfortunately, the jet
90
+ // framework is designed for a single-parameter vector-valued input. The wrapper
91
+ // in this file addresses this issue adding support for functions with one or
92
+ // more parameter vectors.
93
+ //
94
+ // To support multiple parameters, all the parameter vectors are concatenated
95
+ // into one and treated as a single parameter vector, except that since the
96
+ // functor expects different inputs, we need to construct the jets as if they
97
+ // were part of a single parameter vector. The extended jets are passed
98
+ // separately for each parameter.
99
+ //
100
+ // For example, consider a functor F taking two vector parameters, p[2] and
101
+ // q[3], and producing an output y[4]:
102
+ //
103
+ // struct F {
104
+ // template<typename T>
105
+ // bool operator()(const T *p, const T *q, T *z) {
106
+ // // ...
107
+ // }
108
+ // };
109
+ //
110
+ // In this case, the necessary jet type is Jet<double, 5>. Here is a
111
+ // visualization of the jet objects in this case:
112
+ //
113
+ // Dual components for p ----+
114
+ // |
115
+ // -+-
116
+ // y [ * | 1 0 | 0 0 0 ] --- p[0]
117
+ // [ * | 0 1 | 0 0 0 ] --- p[1]
118
+ // [ * | . . | + + + ] |
119
+ // [ * | . . | + + + ] v
120
+ // [ * | . . | + + + ] <--- F(p, q)
121
+ // [ * | . . | + + + ] ^
122
+ // ^^^ ^^^^^ |
123
+ // dy/dp dy/dq [ * | 0 0 | 1 0 0 ] --- q[0]
124
+ // [ * | 0 0 | 0 1 0 ] --- q[1]
125
+ // [ * | 0 0 | 0 0 1 ] --- q[2]
126
+ // --+--
127
+ // |
128
+ // Dual components for q --------------+
129
+ //
130
+ // where the 4x2 submatrix (marked with ".") and 4x3 submatrix (marked with "+"
131
+ // of y in the above diagram are the derivatives of y with respect to p and q
132
+ // respectively. This is how autodiff works for functors taking multiple vector
133
+ // valued arguments (up to 6).
134
+ //
135
+ // Jacobian null pointers (nullptr)
136
+ // --------------------------------
137
+ // In general, the functions below will accept nullptr for all or some of the
138
+ // Jacobian parameters, meaning that those Jacobians will not be computed.
139
+
140
+ #ifndef CERES_PUBLIC_INTERNAL_AUTODIFF_H_
141
+ #define CERES_PUBLIC_INTERNAL_AUTODIFF_H_
142
+
143
+ #include <array>
144
+ #include <cstddef>
145
+ #include <utility>
146
+
147
+ #include "ceres/internal/array_selector.h"
148
+ #include "ceres/internal/eigen.h"
149
+ #include "ceres/internal/fixed_array.h"
150
+ #include "ceres/internal/parameter_dims.h"
151
+ #include "ceres/internal/variadic_evaluate.h"
152
+ #include "ceres/jet.h"
153
+ #include "ceres/types.h"
154
+ #include "glog/logging.h"
155
+
156
+ // If the number of parameters exceeds this values, the corresponding jets are
157
+ // placed on the heap. This will reduce performance by a factor of 2-5 on
158
+ // current compilers.
159
+ #ifndef CERES_AUTODIFF_MAX_PARAMETERS_ON_STACK
160
+ #define CERES_AUTODIFF_MAX_PARAMETERS_ON_STACK 50
161
+ #endif
162
+
163
+ #ifndef CERES_AUTODIFF_MAX_RESIDUALS_ON_STACK
164
+ #define CERES_AUTODIFF_MAX_RESIDUALS_ON_STACK 20
165
+ #endif
166
+
167
+ namespace ceres {
168
+ namespace internal {
169
+
170
+ // Extends src by a 1st order perturbation for every dimension and puts it in
171
+ // dst. The size of src is N. Since this is also used for perturbations in
172
+ // blocked arrays, offset is used to shift which part of the jet the
173
+ // perturbation occurs. This is used to set up the extended x augmented by an
174
+ // identity matrix. The JetT type should be a Jet type, and T should be a
175
+ // numeric type (e.g. double). For example,
176
+ //
177
+ // 0 1 2 3 4 5 6 7 8
178
+ // dst[0] [ * | . . | 1 0 0 | . . . ]
179
+ // dst[1] [ * | . . | 0 1 0 | . . . ]
180
+ // dst[2] [ * | . . | 0 0 1 | . . . ]
181
+ //
182
+ // is what would get put in dst if N was 3, offset was 3, and the jet type JetT
183
+ // was 8-dimensional.
184
+ template <int j, int N, int Offset, typename T, typename JetT>
185
+ struct Make1stOrderPerturbation {
186
+ public:
187
+ inline static void Apply(const T* src, JetT* dst) {
188
+ if (j == 0) {
189
+ DCHECK(src);
190
+ DCHECK(dst);
191
+ }
192
+ dst[j] = JetT(src[j], j + Offset);
193
+ Make1stOrderPerturbation<j + 1, N, Offset, T, JetT>::Apply(src, dst);
194
+ }
195
+ };
196
+
197
+ template <int N, int Offset, typename T, typename JetT>
198
+ struct Make1stOrderPerturbation<N, N, Offset, T, JetT> {
199
+ public:
200
+ static void Apply(const T* /* NOT USED */, JetT* /* NOT USED */) {}
201
+ };
202
+
203
+ // Calls Make1stOrderPerturbation for every parameter block.
204
+ //
205
+ // Example:
206
+ // If one having three parameter blocks with dimensions (3, 2, 4), the call
207
+ // Make1stOrderPerturbations<integer_sequence<3, 2, 4>::Apply(params, x);
208
+ // will result in the following calls to Make1stOrderPerturbation:
209
+ // Make1stOrderPerturbation<0, 3, 0>::Apply(params[0], x + 0);
210
+ // Make1stOrderPerturbation<0, 2, 3>::Apply(params[1], x + 3);
211
+ // Make1stOrderPerturbation<0, 4, 5>::Apply(params[2], x + 5);
212
+ template <typename Seq, int ParameterIdx = 0, int Offset = 0>
213
+ struct Make1stOrderPerturbations;
214
+
215
+ template <int N, int... Ns, int ParameterIdx, int Offset>
216
+ struct Make1stOrderPerturbations<std::integer_sequence<int, N, Ns...>,
217
+ ParameterIdx,
218
+ Offset> {
219
+ template <typename T, typename JetT>
220
+ inline static void Apply(T const* const* parameters, JetT* x) {
221
+ Make1stOrderPerturbation<0, N, Offset, T, JetT>::Apply(
222
+ parameters[ParameterIdx], x + Offset);
223
+ Make1stOrderPerturbations<std::integer_sequence<int, Ns...>,
224
+ ParameterIdx + 1,
225
+ Offset + N>::Apply(parameters, x);
226
+ }
227
+ };
228
+
229
+ // End of 'recursion'. Nothing more to do.
230
+ template <int ParameterIdx, int Total>
231
+ struct Make1stOrderPerturbations<std::integer_sequence<int>,
232
+ ParameterIdx,
233
+ Total> {
234
+ template <typename T, typename JetT>
235
+ static void Apply(T const* const* /* NOT USED */, JetT* /* NOT USED */) {}
236
+ };
237
+
238
+ // Takes the 0th order part of src, assumed to be a Jet type, and puts it in
239
+ // dst. This is used to pick out the "vector" part of the extended y.
240
+ template <typename JetT, typename T>
241
+ inline void Take0thOrderPart(int M, const JetT* src, T dst) {
242
+ DCHECK(src);
243
+ for (int i = 0; i < M; ++i) {
244
+ dst[i] = src[i].a;
245
+ }
246
+ }
247
+
248
+ // Takes N 1st order parts, starting at index N0, and puts them in the M x N
249
+ // matrix 'dst'. This is used to pick out the "matrix" parts of the extended y.
250
+ template <int N0, int N, typename JetT, typename T>
251
+ inline void Take1stOrderPart(const int M, const JetT* src, T* dst) {
252
+ DCHECK(src);
253
+ DCHECK(dst);
254
+ for (int i = 0; i < M; ++i) {
255
+ Eigen::Map<Eigen::Matrix<T, N, 1>>(dst + N * i, N) =
256
+ src[i].v.template segment<N>(N0);
257
+ }
258
+ }
259
+
260
+ // Calls Take1stOrderPart for every parameter block.
261
+ //
262
+ // Example:
263
+ // If one having three parameter blocks with dimensions (3, 2, 4), the call
264
+ // Take1stOrderParts<integer_sequence<3, 2, 4>::Apply(num_outputs,
265
+ // output,
266
+ // jacobians);
267
+ // will result in the following calls to Take1stOrderPart:
268
+ // if (jacobians[0]) {
269
+ // Take1stOrderPart<0, 3>(num_outputs, output, jacobians[0]);
270
+ // }
271
+ // if (jacobians[1]) {
272
+ // Take1stOrderPart<3, 2>(num_outputs, output, jacobians[1]);
273
+ // }
274
+ // if (jacobians[2]) {
275
+ // Take1stOrderPart<5, 4>(num_outputs, output, jacobians[2]);
276
+ // }
277
+ template <typename Seq, int ParameterIdx = 0, int Offset = 0>
278
+ struct Take1stOrderParts;
279
+
280
+ template <int N, int... Ns, int ParameterIdx, int Offset>
281
+ struct Take1stOrderParts<std::integer_sequence<int, N, Ns...>,
282
+ ParameterIdx,
283
+ Offset> {
284
+ template <typename JetT, typename T>
285
+ inline static void Apply(int num_outputs, JetT* output, T** jacobians) {
286
+ if (jacobians[ParameterIdx]) {
287
+ Take1stOrderPart<Offset, N>(num_outputs, output, jacobians[ParameterIdx]);
288
+ }
289
+ Take1stOrderParts<std::integer_sequence<int, Ns...>,
290
+ ParameterIdx + 1,
291
+ Offset + N>::Apply(num_outputs, output, jacobians);
292
+ }
293
+ };
294
+
295
+ // End of 'recursion'. Nothing more to do.
296
+ template <int ParameterIdx, int Offset>
297
+ struct Take1stOrderParts<std::integer_sequence<int>, ParameterIdx, Offset> {
298
+ template <typename T, typename JetT>
299
+ static void Apply(int /* NOT USED*/,
300
+ JetT* /* NOT USED*/,
301
+ T** /* NOT USED */) {}
302
+ };
303
+
304
+ template <int kNumResiduals,
305
+ typename ParameterDims,
306
+ typename Functor,
307
+ typename T>
308
+ inline bool AutoDifferentiate(const Functor& functor,
309
+ T const* const* parameters,
310
+ int dynamic_num_outputs,
311
+ T* function_value,
312
+ T** jacobians) {
313
+ using JetT = Jet<T, ParameterDims::kNumParameters>;
314
+ using Parameters = typename ParameterDims::Parameters;
315
+
316
+ if (kNumResiduals != DYNAMIC) {
317
+ DCHECK_EQ(kNumResiduals, dynamic_num_outputs);
318
+ }
319
+
320
+ ArraySelector<JetT,
321
+ ParameterDims::kNumParameters,
322
+ CERES_AUTODIFF_MAX_PARAMETERS_ON_STACK>
323
+ parameters_as_jets(ParameterDims::kNumParameters);
324
+
325
+ // Pointers to the beginning of each parameter block
326
+ std::array<JetT*, ParameterDims::kNumParameterBlocks> unpacked_parameters =
327
+ ParameterDims::GetUnpackedParameters(parameters_as_jets.data());
328
+
329
+ // If the number of residuals is fixed, we use the template argument as the
330
+ // number of outputs. Otherwise we use the num_outputs parameter. Note: The
331
+ // ?-operator here is compile-time evaluated, therefore num_outputs is also
332
+ // a compile-time constant for functors with fixed residuals.
333
+ const int num_outputs =
334
+ kNumResiduals == DYNAMIC ? dynamic_num_outputs : kNumResiduals;
335
+ DCHECK_GT(num_outputs, 0);
336
+
337
+ ArraySelector<JetT, kNumResiduals, CERES_AUTODIFF_MAX_RESIDUALS_ON_STACK>
338
+ residuals_as_jets(num_outputs);
339
+
340
+ // Invalidate the output Jets, so that we can detect if the user
341
+ // did not assign values to all of them.
342
+ for (int i = 0; i < num_outputs; ++i) {
343
+ residuals_as_jets[i].a = kImpossibleValue;
344
+ residuals_as_jets[i].v.setConstant(kImpossibleValue);
345
+ }
346
+
347
+ Make1stOrderPerturbations<Parameters>::Apply(parameters,
348
+ parameters_as_jets.data());
349
+
350
+ if (!VariadicEvaluate<ParameterDims>(
351
+ functor, unpacked_parameters.data(), residuals_as_jets.data())) {
352
+ return false;
353
+ }
354
+
355
+ Take0thOrderPart(num_outputs, residuals_as_jets.data(), function_value);
356
+ Take1stOrderParts<Parameters>::Apply(
357
+ num_outputs, residuals_as_jets.data(), jacobians);
358
+
359
+ return true;
360
+ }
361
+
362
+ } // namespace internal
363
+ } // namespace ceres
364
+
365
+ #endif // CERES_PUBLIC_INTERNAL_AUTODIFF_H_
ceres-v2/include/internal/config.h ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: alexs.mac@gmail.com (Alex Stewart)
30
+
31
+ // Configuration options for Ceres.
32
+ //
33
+ // Do not edit this file, it was automatically configured by CMake when
34
+ // Ceres was compiled with the relevant configuration for the machine
35
+ // on which Ceres was compiled.
36
+ //
37
+ // Ceres Developers: All options should have the same name as their mapped
38
+ // CMake options, in the preconfigured version of this file
39
+ // all options should be enclosed in '@'.
40
+
41
+ #ifndef CERES_PUBLIC_INTERNAL_CONFIG_H_
42
+ #define CERES_PUBLIC_INTERNAL_CONFIG_H_
43
+
44
+ // If defined, use the LGPL code in Eigen.
45
+ #define CERES_USE_EIGEN_SPARSE
46
+
47
+ // If defined, Ceres was compiled without LAPACK.
48
+ // #define CERES_NO_LAPACK
49
+
50
+ // If defined, Ceres was compiled without SuiteSparse.
51
+ // #define CERES_NO_SUITESPARSE
52
+
53
+ // If defined, Ceres was compiled without CXSparse.
54
+ // #define CERES_NO_CXSPARSE
55
+
56
+ // If defined, Ceres was compiled without CUDA.
57
+ // #define CERES_NO_CUDA
58
+
59
+ // If defined, Ceres was compiled without Apple's Accelerate framework solvers.
60
+ #define CERES_NO_ACCELERATE_SPARSE
61
+
62
+ #if defined(CERES_NO_SUITESPARSE) && \
63
+ defined(CERES_NO_ACCELERATE_SPARSE) && \
64
+ defined(CERES_NO_CXSPARSE) && \
65
+ !defined(CERES_USE_EIGEN_SPARSE) // NOLINT
66
+ // If defined Ceres was compiled without any sparse linear algebra support.
67
+ #define CERES_NO_SPARSE
68
+ #endif
69
+
70
+ // If defined, Ceres was compiled without Schur specializations.
71
+ // #define CERES_RESTRICT_SCHUR_SPECIALIZATION
72
+
73
+ // If defined, Ceres was compiled to use Eigen instead of hardcoded BLAS
74
+ // routines.
75
+ // #define CERES_NO_CUSTOM_BLAS
76
+
77
+ // If defined, Ceres was compiled without multithreading support.
78
+ // #define CERES_NO_THREADS
79
+ // If defined Ceres was compiled with OpenMP multithreading.
80
+ // #define CERES_USE_OPENMP
81
+ // If defined Ceres was compiled with modern C++ multithreading.
82
+ #define CERES_USE_CXX_THREADS
83
+
84
+ // If defined, Ceres was compiled with a version MSVC >= 2005 which
85
+ // deprecated the standard POSIX names for bessel functions, replacing them
86
+ // with underscore prefixed versions (e.g. j0() -> _j0()).
87
+ // #define CERES_MSVC_USE_UNDERSCORE_PREFIXED_BESSEL_FUNCTIONS
88
+
89
+ #if defined(CERES_USE_OPENMP)
90
+ #if defined(CERES_USE_CXX_THREADS) || defined(CERES_NO_THREADS)
91
+ #error CERES_USE_OPENMP is mutually exclusive to CERES_USE_CXX_THREADS and CERES_NO_THREADS
92
+ #endif
93
+ #elif defined(CERES_USE_CXX_THREADS)
94
+ #if defined(CERES_USE_OPENMP) || defined(CERES_NO_THREADS)
95
+ #error CERES_USE_CXX_THREADS is mutually exclusive to CERES_USE_OPENMP, CERES_USE_CXX_THREADS and CERES_NO_THREADS
96
+ #endif
97
+ #elif defined(CERES_NO_THREADS)
98
+ #if defined(CERES_USE_OPENMP) || defined(CERES_USE_CXX_THREADS)
99
+ #error CERES_NO_THREADS is mutually exclusive to CERES_USE_OPENMP and CERES_USE_CXX_THREADS
100
+ #endif
101
+ #else
102
+ # error One of CERES_USE_OPENMP, CERES_USE_CXX_THREADS or CERES_NO_THREADS must be defined.
103
+ #endif
104
+
105
+ // CERES_NO_SPARSE should be automatically defined by config.h if Ceres was
106
+ // compiled without any sparse back-end. Verify that it has not subsequently
107
+ // been inconsistently redefined.
108
+ #if defined(CERES_NO_SPARSE)
109
+ #if !defined(CERES_NO_SUITESPARSE)
110
+ #error CERES_NO_SPARSE requires CERES_NO_SUITESPARSE.
111
+ #endif
112
+ #if !defined(CERES_NO_CXSPARSE)
113
+ #error CERES_NO_SPARSE requires CERES_NO_CXSPARSE
114
+ #endif
115
+ #if !defined(CERES_NO_ACCELERATE_SPARSE)
116
+ #error CERES_NO_SPARSE requires CERES_NO_ACCELERATE_SPARSE
117
+ #endif
118
+ #if defined(CERES_USE_EIGEN_SPARSE)
119
+ #error CERES_NO_SPARSE requires !CERES_USE_EIGEN_SPARSE
120
+ #endif
121
+ #endif
122
+
123
+ #endif // CERES_PUBLIC_INTERNAL_CONFIG_H_
ceres-v2/include/internal/disable_warnings.h ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2015 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // This file has the sole purpose to silence warnings when including Ceres.
30
+
31
+ // This is not your usual header guard. The macro CERES_WARNINGS_DISABLED
32
+ // shows up again in reenable_warnings.h.
33
+ #ifndef CERES_WARNINGS_DISABLED
34
+ #define CERES_WARNINGS_DISABLED
35
+
36
+ #ifdef _MSC_VER
37
+ #pragma warning(push)
38
+ // Disable the warning C4251 which is triggered by stl classes in
39
+ // Ceres' public interface. To quote MSDN: "C4251 can be ignored "
40
+ // "if you are deriving from a type in the Standard C++ Library"
41
+ #pragma warning(disable : 4251)
42
+ #endif
43
+
44
+ #endif // CERES_WARNINGS_DISABLED
ceres-v2/include/internal/eigen.h ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2015 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #ifndef CERES_INTERNAL_EIGEN_H_
32
+ #define CERES_INTERNAL_EIGEN_H_
33
+
34
+ #include "Eigen/Core"
35
+
36
+ namespace ceres {
37
+
38
+ using Vector = Eigen::Matrix<double, Eigen::Dynamic, 1>;
39
+ using Matrix =
40
+ Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
41
+ using VectorRef = Eigen::Map<Vector>;
42
+ using MatrixRef = Eigen::Map<Matrix>;
43
+ using ConstVectorRef = Eigen::Map<const Vector>;
44
+ using ConstMatrixRef = Eigen::Map<const Matrix>;
45
+
46
+ // Column major matrices for DenseSparseMatrix/DenseQRSolver
47
+ using ColMajorMatrix =
48
+ Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
49
+
50
+ using ColMajorMatrixRef =
51
+ Eigen::Map<ColMajorMatrix, 0, Eigen::Stride<Eigen::Dynamic, 1>>;
52
+
53
+ using ConstColMajorMatrixRef =
54
+ Eigen::Map<const ColMajorMatrix, 0, Eigen::Stride<Eigen::Dynamic, 1>>;
55
+
56
+ // C++ does not support templated typdefs, thus the need for this
57
+ // struct so that we can support statically sized Matrix and Maps.
58
+ template <int num_rows = Eigen::Dynamic, int num_cols = Eigen::Dynamic>
59
+ struct EigenTypes {
60
+ using Matrix =
61
+ Eigen::Matrix<double,
62
+ num_rows,
63
+ num_cols,
64
+ num_cols == 1 ? Eigen::ColMajor : Eigen::RowMajor>;
65
+
66
+ using MatrixRef = Eigen::Map<Matrix>;
67
+ using ConstMatrixRef = Eigen::Map<const Matrix>;
68
+ using Vector = Eigen::Matrix<double, num_rows, 1>;
69
+ using VectorRef = Eigen::Map<Eigen::Matrix<double, num_rows, 1>>;
70
+ using ConstVectorRef = Eigen::Map<const Eigen::Matrix<double, num_rows, 1>>;
71
+ };
72
+
73
+ } // namespace ceres
74
+
75
+ #endif // CERES_INTERNAL_EIGEN_H_
ceres-v2/include/internal/export.h ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #ifndef CERES_EXPORT_H
3
+ #define CERES_EXPORT_H
4
+
5
+ #ifdef CERES_STATIC_DEFINE
6
+ # define CERES_EXPORT
7
+ # define CERES_NO_EXPORT
8
+ #else
9
+ # ifndef CERES_EXPORT
10
+ # ifdef ceres_EXPORTS
11
+ /* We are building this library */
12
+ # define CERES_EXPORT
13
+ # else
14
+ /* We are using this library */
15
+ # define CERES_EXPORT
16
+ # endif
17
+ # endif
18
+
19
+ # ifndef CERES_NO_EXPORT
20
+ # define CERES_NO_EXPORT
21
+ # endif
22
+ #endif
23
+
24
+ #ifndef CERES_DEPRECATED
25
+ # define CERES_DEPRECATED __attribute__ ((__deprecated__))
26
+ #endif
27
+
28
+ #ifndef CERES_DEPRECATED_EXPORT
29
+ # define CERES_DEPRECATED_EXPORT CERES_EXPORT CERES_DEPRECATED
30
+ #endif
31
+
32
+ #ifndef CERES_DEPRECATED_NO_EXPORT
33
+ # define CERES_DEPRECATED_NO_EXPORT CERES_NO_EXPORT CERES_DEPRECATED
34
+ #endif
35
+
36
+ #if 0 /* DEFINE_NO_DEPRECATED */
37
+ # ifndef CERES_NO_DEPRECATED
38
+ # define CERES_NO_DEPRECATED
39
+ # endif
40
+ #endif
41
+
42
+ #endif /* CERES_EXPORT_H */
ceres-v2/include/internal/fixed_array.h ADDED
@@ -0,0 +1,467 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2018 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // -----------------------------------------------------------------------------
16
+ // File: fixed_array.h
17
+ // -----------------------------------------------------------------------------
18
+ //
19
+ // A `FixedArray<T>` represents a non-resizable array of `T` where the length of
20
+ // the array can be determined at run-time. It is a good replacement for
21
+ // non-standard and deprecated uses of `alloca()` and variable length arrays
22
+ // within the GCC extension. (See
23
+ // https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html).
24
+ //
25
+ // `FixedArray` allocates small arrays inline, keeping performance fast by
26
+ // avoiding heap operations. It also helps reduce the chances of
27
+ // accidentally overflowing your stack if large input is passed to
28
+ // your function.
29
+
30
+ #ifndef CERES_PUBLIC_INTERNAL_FIXED_ARRAY_H_
31
+ #define CERES_PUBLIC_INTERNAL_FIXED_ARRAY_H_
32
+
33
+ #include <Eigen/Core> // For Eigen::aligned_allocator
34
+ #include <algorithm>
35
+ #include <array>
36
+ #include <cstddef>
37
+ #include <memory>
38
+ #include <tuple>
39
+ #include <type_traits>
40
+
41
+ #include "ceres/internal/memory.h"
42
+ #include "glog/logging.h"
43
+
44
+ namespace ceres {
45
+ namespace internal {
46
+
47
+ constexpr static auto kFixedArrayUseDefault = static_cast<size_t>(-1);
48
+
49
+ // The default fixed array allocator.
50
+ //
51
+ // As one can not easily detect if a struct contains or inherits from a fixed
52
+ // size Eigen type, to be safe the Eigen::aligned_allocator is used by default.
53
+ // But trivial types can never contain Eigen types, so std::allocator is used to
54
+ // safe some heap memory.
55
+ template <typename T>
56
+ using FixedArrayDefaultAllocator =
57
+ typename std::conditional<std::is_trivial<T>::value,
58
+ std::allocator<T>,
59
+ Eigen::aligned_allocator<T>>::type;
60
+
61
+ // -----------------------------------------------------------------------------
62
+ // FixedArray
63
+ // -----------------------------------------------------------------------------
64
+ //
65
+ // A `FixedArray` provides a run-time fixed-size array, allocating a small array
66
+ // inline for efficiency.
67
+ //
68
+ // Most users should not specify an `inline_elements` argument and let
69
+ // `FixedArray` automatically determine the number of elements
70
+ // to store inline based on `sizeof(T)`. If `inline_elements` is specified, the
71
+ // `FixedArray` implementation will use inline storage for arrays with a
72
+ // length <= `inline_elements`.
73
+ //
74
+ // Note that a `FixedArray` constructed with a `size_type` argument will
75
+ // default-initialize its values by leaving trivially constructible types
76
+ // uninitialized (e.g. int, int[4], double), and others default-constructed.
77
+ // This matches the behavior of c-style arrays and `std::array`, but not
78
+ // `std::vector`.
79
+ //
80
+ // Note that `FixedArray` does not provide a public allocator; if it requires a
81
+ // heap allocation, it will do so with global `::operator new[]()` and
82
+ // `::operator delete[]()`, even if T provides class-scope overrides for these
83
+ // operators.
84
+ template <typename T,
85
+ size_t N = kFixedArrayUseDefault,
86
+ typename A = FixedArrayDefaultAllocator<T>>
87
+ class FixedArray {
88
+ static_assert(!std::is_array<T>::value || std::extent<T>::value > 0,
89
+ "Arrays with unknown bounds cannot be used with FixedArray.");
90
+
91
+ static constexpr size_t kInlineBytesDefault = 256;
92
+
93
+ using AllocatorTraits = std::allocator_traits<A>;
94
+ // std::iterator_traits isn't guaranteed to be SFINAE-friendly until C++17,
95
+ // but this seems to be mostly pedantic.
96
+ template <typename Iterator>
97
+ using EnableIfForwardIterator = typename std::enable_if<std::is_convertible<
98
+ typename std::iterator_traits<Iterator>::iterator_category,
99
+ std::forward_iterator_tag>::value>::type;
100
+ static constexpr bool DefaultConstructorIsNonTrivial() {
101
+ return !std::is_trivially_default_constructible<StorageElement>::value;
102
+ }
103
+
104
+ public:
105
+ using allocator_type = typename AllocatorTraits::allocator_type;
106
+ using value_type = typename AllocatorTraits::value_type;
107
+ using pointer = typename AllocatorTraits::pointer;
108
+ using const_pointer = typename AllocatorTraits::const_pointer;
109
+ using reference = value_type&;
110
+ using const_reference = const value_type&;
111
+ using size_type = typename AllocatorTraits::size_type;
112
+ using difference_type = typename AllocatorTraits::difference_type;
113
+ using iterator = pointer;
114
+ using const_iterator = const_pointer;
115
+ using reverse_iterator = std::reverse_iterator<iterator>;
116
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
117
+
118
+ static constexpr size_type inline_elements =
119
+ (N == kFixedArrayUseDefault ? kInlineBytesDefault / sizeof(value_type)
120
+ : static_cast<size_type>(N));
121
+
122
+ FixedArray(const FixedArray& other,
123
+ const allocator_type& a = allocator_type())
124
+ : FixedArray(other.begin(), other.end(), a) {}
125
+
126
+ FixedArray(FixedArray&& other, const allocator_type& a = allocator_type())
127
+ : FixedArray(std::make_move_iterator(other.begin()),
128
+ std::make_move_iterator(other.end()),
129
+ a) {}
130
+
131
+ // Creates an array object that can store `n` elements.
132
+ // Note that trivially constructible elements will be uninitialized.
133
+ explicit FixedArray(size_type n, const allocator_type& a = allocator_type())
134
+ : storage_(n, a) {
135
+ if (DefaultConstructorIsNonTrivial()) {
136
+ ConstructRange(storage_.alloc(), storage_.begin(), storage_.end());
137
+ }
138
+ }
139
+
140
+ // Creates an array initialized with `n` copies of `val`.
141
+ FixedArray(size_type n,
142
+ const value_type& val,
143
+ const allocator_type& a = allocator_type())
144
+ : storage_(n, a) {
145
+ ConstructRange(storage_.alloc(), storage_.begin(), storage_.end(), val);
146
+ }
147
+
148
+ // Creates an array initialized with the size and contents of `init_list`.
149
+ FixedArray(std::initializer_list<value_type> init_list,
150
+ const allocator_type& a = allocator_type())
151
+ : FixedArray(init_list.begin(), init_list.end(), a) {}
152
+
153
+ // Creates an array initialized with the elements from the input
154
+ // range. The array's size will always be `std::distance(first, last)`.
155
+ // REQUIRES: Iterator must be a forward_iterator or better.
156
+ template <typename Iterator, EnableIfForwardIterator<Iterator>* = nullptr>
157
+ FixedArray(Iterator first,
158
+ Iterator last,
159
+ const allocator_type& a = allocator_type())
160
+ : storage_(std::distance(first, last), a) {
161
+ CopyRange(storage_.alloc(), storage_.begin(), first, last);
162
+ }
163
+
164
+ ~FixedArray() noexcept {
165
+ for (auto* cur = storage_.begin(); cur != storage_.end(); ++cur) {
166
+ AllocatorTraits::destroy(storage_.alloc(), cur);
167
+ }
168
+ }
169
+
170
+ // Assignments are deleted because they break the invariant that the size of a
171
+ // `FixedArray` never changes.
172
+ void operator=(FixedArray&&) = delete;
173
+ void operator=(const FixedArray&) = delete;
174
+
175
+ // FixedArray::size()
176
+ //
177
+ // Returns the length of the fixed array.
178
+ size_type size() const { return storage_.size(); }
179
+
180
+ // FixedArray::max_size()
181
+ //
182
+ // Returns the largest possible value of `std::distance(begin(), end())` for a
183
+ // `FixedArray<T>`. This is equivalent to the most possible addressable bytes
184
+ // over the number of bytes taken by T.
185
+ constexpr size_type max_size() const {
186
+ return (std::numeric_limits<difference_type>::max)() / sizeof(value_type);
187
+ }
188
+
189
+ // FixedArray::empty()
190
+ //
191
+ // Returns whether or not the fixed array is empty.
192
+ bool empty() const { return size() == 0; }
193
+
194
+ // FixedArray::memsize()
195
+ //
196
+ // Returns the memory size of the fixed array in bytes.
197
+ size_t memsize() const { return size() * sizeof(value_type); }
198
+
199
+ // FixedArray::data()
200
+ //
201
+ // Returns a const T* pointer to elements of the `FixedArray`. This pointer
202
+ // can be used to access (but not modify) the contained elements.
203
+ const_pointer data() const { return AsValueType(storage_.begin()); }
204
+
205
+ // Overload of FixedArray::data() to return a T* pointer to elements of the
206
+ // fixed array. This pointer can be used to access and modify the contained
207
+ // elements.
208
+ pointer data() { return AsValueType(storage_.begin()); }
209
+
210
+ // FixedArray::operator[]
211
+ //
212
+ // Returns a reference the ith element of the fixed array.
213
+ // REQUIRES: 0 <= i < size()
214
+ reference operator[](size_type i) {
215
+ DCHECK_LT(i, size());
216
+ return data()[i];
217
+ }
218
+
219
+ // Overload of FixedArray::operator()[] to return a const reference to the
220
+ // ith element of the fixed array.
221
+ // REQUIRES: 0 <= i < size()
222
+ const_reference operator[](size_type i) const {
223
+ DCHECK_LT(i, size());
224
+ return data()[i];
225
+ }
226
+
227
+ // FixedArray::front()
228
+ //
229
+ // Returns a reference to the first element of the fixed array.
230
+ reference front() { return *begin(); }
231
+
232
+ // Overload of FixedArray::front() to return a reference to the first element
233
+ // of a fixed array of const values.
234
+ const_reference front() const { return *begin(); }
235
+
236
+ // FixedArray::back()
237
+ //
238
+ // Returns a reference to the last element of the fixed array.
239
+ reference back() { return *(end() - 1); }
240
+
241
+ // Overload of FixedArray::back() to return a reference to the last element
242
+ // of a fixed array of const values.
243
+ const_reference back() const { return *(end() - 1); }
244
+
245
+ // FixedArray::begin()
246
+ //
247
+ // Returns an iterator to the beginning of the fixed array.
248
+ iterator begin() { return data(); }
249
+
250
+ // Overload of FixedArray::begin() to return a const iterator to the
251
+ // beginning of the fixed array.
252
+ const_iterator begin() const { return data(); }
253
+
254
+ // FixedArray::cbegin()
255
+ //
256
+ // Returns a const iterator to the beginning of the fixed array.
257
+ const_iterator cbegin() const { return begin(); }
258
+
259
+ // FixedArray::end()
260
+ //
261
+ // Returns an iterator to the end of the fixed array.
262
+ iterator end() { return data() + size(); }
263
+
264
+ // Overload of FixedArray::end() to return a const iterator to the end of the
265
+ // fixed array.
266
+ const_iterator end() const { return data() + size(); }
267
+
268
+ // FixedArray::cend()
269
+ //
270
+ // Returns a const iterator to the end of the fixed array.
271
+ const_iterator cend() const { return end(); }
272
+
273
+ // FixedArray::rbegin()
274
+ //
275
+ // Returns a reverse iterator from the end of the fixed array.
276
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
277
+
278
+ // Overload of FixedArray::rbegin() to return a const reverse iterator from
279
+ // the end of the fixed array.
280
+ const_reverse_iterator rbegin() const {
281
+ return const_reverse_iterator(end());
282
+ }
283
+
284
+ // FixedArray::crbegin()
285
+ //
286
+ // Returns a const reverse iterator from the end of the fixed array.
287
+ const_reverse_iterator crbegin() const { return rbegin(); }
288
+
289
+ // FixedArray::rend()
290
+ //
291
+ // Returns a reverse iterator from the beginning of the fixed array.
292
+ reverse_iterator rend() { return reverse_iterator(begin()); }
293
+
294
+ // Overload of FixedArray::rend() for returning a const reverse iterator
295
+ // from the beginning of the fixed array.
296
+ const_reverse_iterator rend() const {
297
+ return const_reverse_iterator(begin());
298
+ }
299
+
300
+ // FixedArray::crend()
301
+ //
302
+ // Returns a reverse iterator from the beginning of the fixed array.
303
+ const_reverse_iterator crend() const { return rend(); }
304
+
305
+ // FixedArray::fill()
306
+ //
307
+ // Assigns the given `value` to all elements in the fixed array.
308
+ void fill(const value_type& val) { std::fill(begin(), end(), val); }
309
+
310
+ // Relational operators. Equality operators are elementwise using
311
+ // `operator==`, while order operators order FixedArrays lexicographically.
312
+ friend bool operator==(const FixedArray& lhs, const FixedArray& rhs) {
313
+ return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
314
+ }
315
+
316
+ friend bool operator!=(const FixedArray& lhs, const FixedArray& rhs) {
317
+ return !(lhs == rhs);
318
+ }
319
+
320
+ friend bool operator<(const FixedArray& lhs, const FixedArray& rhs) {
321
+ return std::lexicographical_compare(
322
+ lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
323
+ }
324
+
325
+ friend bool operator>(const FixedArray& lhs, const FixedArray& rhs) {
326
+ return rhs < lhs;
327
+ }
328
+
329
+ friend bool operator<=(const FixedArray& lhs, const FixedArray& rhs) {
330
+ return !(rhs < lhs);
331
+ }
332
+
333
+ friend bool operator>=(const FixedArray& lhs, const FixedArray& rhs) {
334
+ return !(lhs < rhs);
335
+ }
336
+
337
+ private:
338
+ // StorageElement
339
+ //
340
+ // For FixedArrays with a C-style-array value_type, StorageElement is a POD
341
+ // wrapper struct called StorageElementWrapper that holds the value_type
342
+ // instance inside. This is needed for construction and destruction of the
343
+ // entire array regardless of how many dimensions it has. For all other cases,
344
+ // StorageElement is just an alias of value_type.
345
+ //
346
+ // Maintainer's Note: The simpler solution would be to simply wrap value_type
347
+ // in a struct whether it's an array or not. That causes some paranoid
348
+ // diagnostics to misfire, believing that 'data()' returns a pointer to a
349
+ // single element, rather than the packed array that it really is.
350
+ // e.g.:
351
+ //
352
+ // FixedArray<char> buf(1);
353
+ // sprintf(buf.data(), "foo");
354
+ //
355
+ // error: call to int __builtin___sprintf_chk(etc...)
356
+ // will always overflow destination buffer [-Werror]
357
+ //
358
+ template <typename OuterT,
359
+ typename InnerT = typename std::remove_extent<OuterT>::type,
360
+ size_t InnerN = std::extent<OuterT>::value>
361
+ struct StorageElementWrapper {
362
+ InnerT array[InnerN];
363
+ };
364
+
365
+ using StorageElement =
366
+ typename std::conditional<std::is_array<value_type>::value,
367
+ StorageElementWrapper<value_type>,
368
+ value_type>::type;
369
+
370
+ static pointer AsValueType(pointer ptr) { return ptr; }
371
+ static pointer AsValueType(StorageElementWrapper<value_type>* ptr) {
372
+ return std::addressof(ptr->array);
373
+ }
374
+
375
+ static_assert(sizeof(StorageElement) == sizeof(value_type), "");
376
+ static_assert(alignof(StorageElement) == alignof(value_type), "");
377
+
378
+ class NonEmptyInlinedStorage {
379
+ public:
380
+ StorageElement* data() { return reinterpret_cast<StorageElement*>(buff_); }
381
+ void AnnotateConstruct(size_type) {}
382
+ void AnnotateDestruct(size_type) {}
383
+
384
+ // #ifdef ADDRESS_SANITIZER
385
+ // void* RedzoneBegin() { return &redzone_begin_; }
386
+ // void* RedzoneEnd() { return &redzone_end_ + 1; }
387
+ // #endif // ADDRESS_SANITIZER
388
+
389
+ private:
390
+ // ADDRESS_SANITIZER_REDZONE(redzone_begin_);
391
+ alignas(StorageElement) char buff_[sizeof(StorageElement[inline_elements])];
392
+ // ADDRESS_SANITIZER_REDZONE(redzone_end_);
393
+ };
394
+
395
+ class EmptyInlinedStorage {
396
+ public:
397
+ StorageElement* data() { return nullptr; }
398
+ void AnnotateConstruct(size_type) {}
399
+ void AnnotateDestruct(size_type) {}
400
+ };
401
+
402
+ using InlinedStorage =
403
+ typename std::conditional<inline_elements == 0,
404
+ EmptyInlinedStorage,
405
+ NonEmptyInlinedStorage>::type;
406
+
407
+ // Storage
408
+ //
409
+ // An instance of Storage manages the inline and out-of-line memory for
410
+ // instances of FixedArray. This guarantees that even when construction of
411
+ // individual elements fails in the FixedArray constructor body, the
412
+ // destructor for Storage will still be called and out-of-line memory will be
413
+ // properly deallocated.
414
+ //
415
+ class Storage : public InlinedStorage {
416
+ public:
417
+ Storage(size_type n, const allocator_type& a)
418
+ : size_alloc_(n, a), data_(InitializeData()) {}
419
+
420
+ ~Storage() noexcept {
421
+ if (UsingInlinedStorage(size())) {
422
+ InlinedStorage::AnnotateDestruct(size());
423
+ } else {
424
+ AllocatorTraits::deallocate(alloc(), AsValueType(begin()), size());
425
+ }
426
+ }
427
+
428
+ size_type size() const { return std::get<0>(size_alloc_); }
429
+ StorageElement* begin() const { return data_; }
430
+ StorageElement* end() const { return begin() + size(); }
431
+ allocator_type& alloc() { return std::get<1>(size_alloc_); }
432
+
433
+ private:
434
+ static bool UsingInlinedStorage(size_type n) {
435
+ return n <= inline_elements;
436
+ }
437
+
438
+ StorageElement* InitializeData() {
439
+ if (UsingInlinedStorage(size())) {
440
+ InlinedStorage::AnnotateConstruct(size());
441
+ return InlinedStorage::data();
442
+ } else {
443
+ return reinterpret_cast<StorageElement*>(
444
+ AllocatorTraits::allocate(alloc(), size()));
445
+ }
446
+ }
447
+
448
+ // Using std::tuple and not absl::CompressedTuple, as it has a lot of
449
+ // dependencies to other absl headers.
450
+ std::tuple<size_type, allocator_type> size_alloc_;
451
+ StorageElement* data_;
452
+ };
453
+
454
+ Storage storage_;
455
+ };
456
+
457
+ template <typename T, size_t N, typename A>
458
+ constexpr size_t FixedArray<T, N, A>::kInlineBytesDefault;
459
+
460
+ template <typename T, size_t N, typename A>
461
+ constexpr typename FixedArray<T, N, A>::size_type
462
+ FixedArray<T, N, A>::inline_elements;
463
+
464
+ } // namespace internal
465
+ } // namespace ceres
466
+
467
+ #endif // CERES_PUBLIC_INTERNAL_FIXED_ARRAY_H_
ceres-v2/include/internal/householder_vector.h ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2015 Google Inc. All rights reserved.
3
+ // http://code.google.com/p/ceres-solver/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: vitus@google.com (Michael Vitus)
30
+
31
+ #ifndef CERES_PUBLIC_INTERNAL_HOUSEHOLDER_VECTOR_H_
32
+ #define CERES_PUBLIC_INTERNAL_HOUSEHOLDER_VECTOR_H_
33
+
34
+ #include "Eigen/Core"
35
+ #include "glog/logging.h"
36
+
37
+ namespace ceres {
38
+ namespace internal {
39
+
40
+ // Algorithm 5.1.1 from 'Matrix Computations' by Golub et al. (Johns Hopkins
41
+ // Studies in Mathematical Sciences) but using the nth element of the input
42
+ // vector as pivot instead of first. This computes the vector v with v(n) = 1
43
+ // and beta such that H = I - beta * v * v^T is orthogonal and
44
+ // H * x = ||x||_2 * e_n.
45
+ //
46
+ // NOTE: Some versions of MSVC have trouble deducing the type of v if
47
+ // you do not specify all the template arguments explicitly.
48
+ template <typename XVectorType, typename Scalar, int N>
49
+ void ComputeHouseholderVector(const XVectorType& x,
50
+ Eigen::Matrix<Scalar, N, 1>* v,
51
+ Scalar* beta) {
52
+ CHECK(beta != nullptr);
53
+ CHECK(v != nullptr);
54
+ CHECK_GT(x.rows(), 1);
55
+ CHECK_EQ(x.rows(), v->rows());
56
+
57
+ Scalar sigma = x.head(x.rows() - 1).squaredNorm();
58
+ *v = x;
59
+ (*v)(v->rows() - 1) = Scalar(1.0);
60
+
61
+ *beta = Scalar(0.0);
62
+ const Scalar& x_pivot = x(x.rows() - 1);
63
+
64
+ if (sigma <= Scalar(std::numeric_limits<double>::epsilon())) {
65
+ if (x_pivot < Scalar(0.0)) {
66
+ *beta = Scalar(2.0);
67
+ }
68
+ return;
69
+ }
70
+
71
+ const Scalar mu = sqrt(x_pivot * x_pivot + sigma);
72
+ Scalar v_pivot = Scalar(1.0);
73
+
74
+ if (x_pivot <= Scalar(0.0)) {
75
+ v_pivot = x_pivot - mu;
76
+ } else {
77
+ v_pivot = -sigma / (x_pivot + mu);
78
+ }
79
+
80
+ *beta = Scalar(2.0) * v_pivot * v_pivot / (sigma + v_pivot * v_pivot);
81
+
82
+ v->head(v->rows() - 1) /= v_pivot;
83
+ }
84
+
85
+ template <typename XVectorType, typename Derived>
86
+ typename Derived::PlainObject ApplyHouseholderVector(
87
+ const XVectorType& y,
88
+ const Eigen::MatrixBase<Derived>& v,
89
+ const typename Derived::Scalar& beta) {
90
+ return (y - v * (beta * (v.transpose() * y)));
91
+ }
92
+
93
+ } // namespace internal
94
+ } // namespace ceres
95
+
96
+ #endif // CERES_PUBLIC_INTERNAL_HOUSEHOLDER_VECTOR_H_
ceres-v2/include/internal/integer_sequence_algorithm.h ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: jodebo_beck@gmx.de (Johannes Beck)
30
+ // sergiu.deitsch@gmail.com (Sergiu Deitsch)
31
+ //
32
+ // Algorithms to be used together with integer_sequence, like computing the sum
33
+ // or the exclusive scan (sometimes called exclusive prefix sum) at compile
34
+ // time.
35
+
36
+ #ifndef CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_ALGORITHM_H_
37
+ #define CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_ALGORITHM_H_
38
+
39
+ #include <utility>
40
+
41
+ #include "ceres/jet_fwd.h"
42
+
43
+ namespace ceres {
44
+ namespace internal {
45
+
46
+ // Implementation of calculating the sum of an integer sequence.
47
+ // Recursively instantiate SumImpl and calculate the sum of the N first
48
+ // numbers. This reduces the number of instantiations and speeds up
49
+ // compilation.
50
+ //
51
+ // Examples:
52
+ // 1) integer_sequence<int, 5>:
53
+ // Value = 5
54
+ //
55
+ // 2) integer_sequence<int, 4, 2>:
56
+ // Value = 4 + 2 + SumImpl<integer_sequence<int>>::Value
57
+ // Value = 4 + 2 + 0
58
+ //
59
+ // 3) integer_sequence<int, 2, 1, 4>:
60
+ // Value = 2 + 1 + SumImpl<integer_sequence<int, 4>>::Value
61
+ // Value = 2 + 1 + 4
62
+ template <typename Seq>
63
+ struct SumImpl;
64
+
65
+ // Strip of and sum the first number.
66
+ template <typename T, T N, T... Ns>
67
+ struct SumImpl<std::integer_sequence<T, N, Ns...>> {
68
+ static constexpr T Value =
69
+ N + SumImpl<std::integer_sequence<T, Ns...>>::Value;
70
+ };
71
+
72
+ // Strip of and sum the first two numbers.
73
+ template <typename T, T N1, T N2, T... Ns>
74
+ struct SumImpl<std::integer_sequence<T, N1, N2, Ns...>> {
75
+ static constexpr T Value =
76
+ N1 + N2 + SumImpl<std::integer_sequence<T, Ns...>>::Value;
77
+ };
78
+
79
+ // Strip of and sum the first four numbers.
80
+ template <typename T, T N1, T N2, T N3, T N4, T... Ns>
81
+ struct SumImpl<std::integer_sequence<T, N1, N2, N3, N4, Ns...>> {
82
+ static constexpr T Value =
83
+ N1 + N2 + N3 + N4 + SumImpl<std::integer_sequence<T, Ns...>>::Value;
84
+ };
85
+
86
+ // Only one number is left. 'Value' is just that number ('recursion' ends).
87
+ template <typename T, T N>
88
+ struct SumImpl<std::integer_sequence<T, N>> {
89
+ static constexpr T Value = N;
90
+ };
91
+
92
+ // No number is left. 'Value' is the identity element (for sum this is zero).
93
+ template <typename T>
94
+ struct SumImpl<std::integer_sequence<T>> {
95
+ static constexpr T Value = T(0);
96
+ };
97
+
98
+ // Calculate the sum of an integer sequence. The resulting sum will be stored in
99
+ // 'Value'.
100
+ template <typename Seq>
101
+ class Sum {
102
+ using T = typename Seq::value_type;
103
+
104
+ public:
105
+ static constexpr T Value = SumImpl<Seq>::Value;
106
+ };
107
+
108
+ // Implementation of calculating an exclusive scan (exclusive prefix sum) of an
109
+ // integer sequence. Exclusive means that the i-th input element is not included
110
+ // in the i-th sum. Calculating the exclusive scan for an input array I results
111
+ // in the following output R:
112
+ //
113
+ // R[0] = 0
114
+ // R[1] = I[0];
115
+ // R[2] = I[0] + I[1];
116
+ // R[3] = I[0] + I[1] + I[2];
117
+ // ...
118
+ //
119
+ // In C++17 std::exclusive_scan does the same operation at runtime (but
120
+ // cannot be used to calculate the prefix sum at compile time). See
121
+ // https://en.cppreference.com/w/cpp/algorithm/exclusive_scan for a more
122
+ // detailed description.
123
+ //
124
+ // Example for integer_sequence<int, 1, 4, 3> (seq := integer_sequence):
125
+ // T , Sum, Ns... , Rs...
126
+ // ExclusiveScanImpl<int, 0, seq<int, 1, 4, 3>, seq<int >>
127
+ // ExclusiveScanImpl<int, 1, seq<int, 4, 3>, seq<int, 0 >>
128
+ // ExclusiveScanImpl<int, 5, seq<int, 3>, seq<int, 0, 1 >>
129
+ // ExclusiveScanImpl<int, 8, seq<int >, seq<int, 0, 1, 5>>
130
+ // ^^^^^^^^^^^^^^^^^
131
+ // resulting sequence
132
+ template <typename T, T Sum, typename SeqIn, typename SeqOut>
133
+ struct ExclusiveScanImpl;
134
+
135
+ template <typename T, T Sum, T N, T... Ns, T... Rs>
136
+ struct ExclusiveScanImpl<T,
137
+ Sum,
138
+ std::integer_sequence<T, N, Ns...>,
139
+ std::integer_sequence<T, Rs...>> {
140
+ using Type =
141
+ typename ExclusiveScanImpl<T,
142
+ Sum + N,
143
+ std::integer_sequence<T, Ns...>,
144
+ std::integer_sequence<T, Rs..., Sum>>::Type;
145
+ };
146
+
147
+ // End of 'recursion'. The resulting type is SeqOut.
148
+ template <typename T, T Sum, typename SeqOut>
149
+ struct ExclusiveScanImpl<T, Sum, std::integer_sequence<T>, SeqOut> {
150
+ using Type = SeqOut;
151
+ };
152
+
153
+ // Calculates the exclusive scan of the specified integer sequence. The last
154
+ // element (the total) is not included in the resulting sequence so they have
155
+ // same length. This means the exclusive scan of integer_sequence<int, 1, 2, 3>
156
+ // will be integer_sequence<int, 0, 1, 3>.
157
+ template <typename Seq>
158
+ class ExclusiveScanT {
159
+ using T = typename Seq::value_type;
160
+
161
+ public:
162
+ using Type =
163
+ typename ExclusiveScanImpl<T, T(0), Seq, std::integer_sequence<T>>::Type;
164
+ };
165
+
166
+ // Helper to use exclusive scan without typename.
167
+ template <typename Seq>
168
+ using ExclusiveScan = typename ExclusiveScanT<Seq>::Type;
169
+
170
+ // Removes all elements from a integer sequence corresponding to specified
171
+ // ValueToRemove.
172
+ //
173
+ // This type should not be used directly but instead RemoveValue.
174
+ template <typename T, T ValueToRemove, typename... Sequence>
175
+ struct RemoveValueImpl;
176
+
177
+ // Final filtered sequence
178
+ template <typename T, T ValueToRemove, T... Values>
179
+ struct RemoveValueImpl<T,
180
+ ValueToRemove,
181
+ std::integer_sequence<T, Values...>,
182
+ std::integer_sequence<T>> {
183
+ using type = std::integer_sequence<T, Values...>;
184
+ };
185
+
186
+ // Found a matching value
187
+ template <typename T, T ValueToRemove, T... Head, T... Tail>
188
+ struct RemoveValueImpl<T,
189
+ ValueToRemove,
190
+ std::integer_sequence<T, Head...>,
191
+ std::integer_sequence<T, ValueToRemove, Tail...>>
192
+ : RemoveValueImpl<T,
193
+ ValueToRemove,
194
+ std::integer_sequence<T, Head...>,
195
+ std::integer_sequence<T, Tail...>> {};
196
+
197
+ // Move one element from the tail to the head
198
+ template <typename T, T ValueToRemove, T... Head, T MiddleValue, T... Tail>
199
+ struct RemoveValueImpl<T,
200
+ ValueToRemove,
201
+ std::integer_sequence<T, Head...>,
202
+ std::integer_sequence<T, MiddleValue, Tail...>>
203
+ : RemoveValueImpl<T,
204
+ ValueToRemove,
205
+ std::integer_sequence<T, Head..., MiddleValue>,
206
+ std::integer_sequence<T, Tail...>> {};
207
+
208
+ // Start recursion by splitting the integer sequence into two separate ones
209
+ template <typename T, T ValueToRemove, T... Tail>
210
+ struct RemoveValueImpl<T, ValueToRemove, std::integer_sequence<T, Tail...>>
211
+ : RemoveValueImpl<T,
212
+ ValueToRemove,
213
+ std::integer_sequence<T>,
214
+ std::integer_sequence<T, Tail...>> {};
215
+
216
+ // RemoveValue takes an integer Sequence of arbitrary type and removes all
217
+ // elements matching ValueToRemove.
218
+ //
219
+ // In contrast to RemoveValueImpl, this implementation deduces the value type
220
+ // eliminating the need to specify it explicitly.
221
+ //
222
+ // As an example, RemoveValue<std::integer_sequence<int, 1, 2, 3>, 4>::type will
223
+ // not transform the type of the original sequence. However,
224
+ // RemoveValue<std::integer_sequence<int, 0, 0, 2>, 2>::type will generate a new
225
+ // sequence of type std::integer_sequence<int, 0, 0> by removing the value 2.
226
+ template <typename Sequence, typename Sequence::value_type ValueToRemove>
227
+ struct RemoveValue
228
+ : RemoveValueImpl<typename Sequence::value_type, ValueToRemove, Sequence> {
229
+ };
230
+
231
+ // Convenience template alias for RemoveValue.
232
+ template <typename Sequence, typename Sequence::value_type ValueToRemove>
233
+ using RemoveValue_t = typename RemoveValue<Sequence, ValueToRemove>::type;
234
+
235
+ // Determines whether the values of an integer sequence are all the same.
236
+ //
237
+ // The integer sequence must contain at least one value. The predicate is
238
+ // undefined for empty sequences. The evaluation result of the predicate for a
239
+ // sequence containing only one value is defined to be true.
240
+ template <typename... Sequence>
241
+ struct AreAllEqual;
242
+
243
+ // The predicate result for a sequence containing one element is defined to be
244
+ // true.
245
+ template <typename T, T Value>
246
+ struct AreAllEqual<std::integer_sequence<T, Value>> : std::true_type {};
247
+
248
+ // Recursion end.
249
+ template <typename T, T Value1, T Value2>
250
+ struct AreAllEqual<std::integer_sequence<T, Value1, Value2>>
251
+ : std::integral_constant<bool, Value1 == Value2> {};
252
+
253
+ // Recursion for sequences containing at least two elements.
254
+ template <typename T, T Value1, T Value2, T... Values>
255
+ // clang-format off
256
+ struct AreAllEqual<std::integer_sequence<T, Value1, Value2, Values...> >
257
+ : std::integral_constant
258
+ <
259
+ bool,
260
+ AreAllEqual<std::integer_sequence<T, Value1, Value2> >::value &&
261
+ AreAllEqual<std::integer_sequence<T, Value2, Values...> >::value
262
+ >
263
+ // clang-format on
264
+ {};
265
+
266
+ // Convenience variable template for AreAllEqual.
267
+ template <class Sequence>
268
+ constexpr bool AreAllEqual_v = AreAllEqual<Sequence>::value;
269
+
270
+ // Predicate determining whether an integer sequence is either empty or all
271
+ // values are equal.
272
+ template <typename Sequence>
273
+ struct IsEmptyOrAreAllEqual;
274
+
275
+ // Empty case.
276
+ template <typename T>
277
+ struct IsEmptyOrAreAllEqual<std::integer_sequence<T>> : std::true_type {};
278
+
279
+ // General case for sequences containing at least one value.
280
+ template <typename T, T HeadValue, T... Values>
281
+ struct IsEmptyOrAreAllEqual<std::integer_sequence<T, HeadValue, Values...>>
282
+ : AreAllEqual<std::integer_sequence<T, HeadValue, Values...>> {};
283
+
284
+ // Convenience variable template for IsEmptyOrAreAllEqual.
285
+ template <class Sequence>
286
+ constexpr bool IsEmptyOrAreAllEqual_v = IsEmptyOrAreAllEqual<Sequence>::value;
287
+
288
+ } // namespace internal
289
+ } // namespace ceres
290
+
291
+ #endif // CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_ALGORITHM_H_
ceres-v2/include/internal/jet_traits.h ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sergiu.deitsch@gmail.com (Sergiu Deitsch)
30
+ //
31
+
32
+ #ifndef CERES_PUBLIC_INTERNAL_JET_TRAITS_H_
33
+ #define CERES_PUBLIC_INTERNAL_JET_TRAITS_H_
34
+
35
+ #include <tuple>
36
+ #include <type_traits>
37
+ #include <utility>
38
+
39
+ #include "ceres/internal/integer_sequence_algorithm.h"
40
+ #include "ceres/jet_fwd.h"
41
+
42
+ namespace ceres {
43
+ namespace internal {
44
+
45
+ // Predicate that determines whether T is a Jet.
46
+ template <typename T, typename E = void>
47
+ struct IsJet : std::false_type {};
48
+
49
+ template <typename T, int N>
50
+ struct IsJet<Jet<T, N>> : std::true_type {};
51
+
52
+ // Convenience variable template for IsJet.
53
+ template <typename T>
54
+ constexpr bool IsJet_v = IsJet<T>::value;
55
+
56
+ // Predicate that determines whether any of the Types is a Jet.
57
+ template <typename... Types>
58
+ struct AreAnyJet : std::false_type {};
59
+
60
+ template <typename T, typename... Types>
61
+ struct AreAnyJet<T, Types...> : AreAnyJet<Types...> {};
62
+
63
+ template <typename T, int N, typename... Types>
64
+ struct AreAnyJet<Jet<T, N>, Types...> : std::true_type {};
65
+
66
+ // Convenience variable template for AreAnyJet.
67
+ template <typename... Types>
68
+ constexpr bool AreAnyJet_v = AreAnyJet<Types...>::value;
69
+
70
+ // Extracts the underlying floating-point from a type T.
71
+ template <typename T, typename E = void>
72
+ struct UnderlyingScalar {
73
+ using type = T;
74
+ };
75
+
76
+ template <typename T, int N>
77
+ struct UnderlyingScalar<Jet<T, N>> : UnderlyingScalar<T> {};
78
+
79
+ // Convenience template alias for UnderlyingScalar type trait.
80
+ template <typename T>
81
+ using UnderlyingScalar_t = typename UnderlyingScalar<T>::type;
82
+
83
+ // Predicate determining whether all Types in the pack are the same.
84
+ //
85
+ // Specifically, the predicate applies std::is_same recursively to pairs of
86
+ // Types in the pack.
87
+ //
88
+ // The predicate is defined only for template packs containing at least two
89
+ // types.
90
+ template <typename T1, typename T2, typename... Types>
91
+ // clang-format off
92
+ struct AreAllSame : std::integral_constant
93
+ <
94
+ bool,
95
+ AreAllSame<T1, T2>::value &&
96
+ AreAllSame<T2, Types...>::value
97
+ >
98
+ // clang-format on
99
+ {};
100
+
101
+ // AreAllSame pairwise test.
102
+ template <typename T1, typename T2>
103
+ struct AreAllSame<T1, T2> : std::is_same<T1, T2> {};
104
+
105
+ // Convenience variable template for AreAllSame.
106
+ template <typename... Types>
107
+ constexpr bool AreAllSame_v = AreAllSame<Types...>::value;
108
+
109
+ // Determines the rank of a type. This allows to ensure that types passed as
110
+ // arguments are compatible to each other. The rank of Jet is determined by the
111
+ // dimensions of the dual part. The rank of a scalar is always 0.
112
+ // Non-specialized types default to a rank of -1.
113
+ template <typename T, typename E = void>
114
+ struct Rank : std::integral_constant<int, -1> {};
115
+
116
+ // The rank of a scalar is 0.
117
+ template <typename T>
118
+ struct Rank<T, std::enable_if_t<std::is_scalar<T>::value>>
119
+ : std::integral_constant<int, 0> {};
120
+
121
+ // The rank of a Jet is given by its dimensionality.
122
+ template <typename T, int N>
123
+ struct Rank<Jet<T, N>> : std::integral_constant<int, N> {};
124
+
125
+ // Convenience variable template for Rank.
126
+ template <typename T>
127
+ constexpr int Rank_v = Rank<T>::value;
128
+
129
+ // Constructs an integer sequence of ranks for each of the Types in the pack.
130
+ template <typename... Types>
131
+ using Ranks_t = std::integer_sequence<int, Rank_v<Types>...>;
132
+
133
+ // Returns the scalar part of a type. This overload acts as an identity.
134
+ template <typename T>
135
+ constexpr decltype(auto) AsScalar(T&& value) noexcept {
136
+ return std::forward<T>(value);
137
+ }
138
+
139
+ // Recursively unwraps the scalar part of a Jet until a non-Jet scalar type is
140
+ // encountered.
141
+ template <typename T, int N>
142
+ constexpr decltype(auto) AsScalar(const Jet<T, N>& value) noexcept(
143
+ noexcept(AsScalar(value.a))) {
144
+ return AsScalar(value.a);
145
+ }
146
+
147
+ } // namespace internal
148
+
149
+ // Type trait ensuring at least one of the types is a Jet,
150
+ // the underlying scalar types are the same and Jet dimensions match.
151
+ //
152
+ // The type trait can be further specialized if necessary.
153
+ //
154
+ // This trait is a candidate for a concept definition once C++20 features can
155
+ // be used.
156
+ template <typename... Types>
157
+ // clang-format off
158
+ struct CompatibleJetOperands : std::integral_constant
159
+ <
160
+ bool,
161
+ // At least one of the types is a Jet
162
+ internal::AreAnyJet_v<Types...> &&
163
+ // The underlying floating-point types are exactly the same
164
+ internal::AreAllSame_v<internal::UnderlyingScalar_t<Types>...> &&
165
+ // Non-zero ranks of types are equal
166
+ internal::IsEmptyOrAreAllEqual_v<internal::RemoveValue_t<internal::Ranks_t<Types...>, 0>>
167
+ >
168
+ // clang-format on
169
+ {};
170
+
171
+ // Single Jet operand is always compatible.
172
+ template <typename T, int N>
173
+ struct CompatibleJetOperands<Jet<T, N>> : std::true_type {};
174
+
175
+ // Single non-Jet operand is always incompatible.
176
+ template <typename T>
177
+ struct CompatibleJetOperands<T> : std::false_type {};
178
+
179
+ // Empty operands are always incompatible.
180
+ template <>
181
+ struct CompatibleJetOperands<> : std::false_type {};
182
+
183
+ // Convenience variable template ensuring at least one of the types is a Jet,
184
+ // the underlying scalar types are the same and Jet dimensions match.
185
+ //
186
+ // This trait is a candidate for a concept definition once C++20 features can
187
+ // be used.
188
+ template <typename... Types>
189
+ constexpr bool CompatibleJetOperands_v = CompatibleJetOperands<Types...>::value;
190
+
191
+ // Type trait ensuring at least one of the types is a Jet,
192
+ // the underlying scalar types are compatible among each other and Jet
193
+ // dimensions match.
194
+ //
195
+ // The type trait can be further specialized if necessary.
196
+ //
197
+ // This trait is a candidate for a concept definition once C++20 features can
198
+ // be used.
199
+ template <typename... Types>
200
+ // clang-format off
201
+ struct PromotableJetOperands : std::integral_constant
202
+ <
203
+ bool,
204
+ // Types can be compatible among each other
205
+ internal::AreAnyJet_v<Types...> &&
206
+ // Non-zero ranks of types are equal
207
+ internal::IsEmptyOrAreAllEqual_v<internal::RemoveValue_t<internal::Ranks_t<Types...>, 0>>
208
+ >
209
+ // clang-format on
210
+ {};
211
+
212
+ // Convenience variable template ensuring at least one of the types is a Jet,
213
+ // the underlying scalar types are compatible among each other and Jet
214
+ // dimensions match.
215
+ //
216
+ // This trait is a candidate for a concept definition once C++20 features can
217
+ // be used.
218
+ template <typename... Types>
219
+ constexpr bool PromotableJetOperands_v = PromotableJetOperands<Types...>::value;
220
+
221
+ } // namespace ceres
222
+
223
+ #endif // CERES_PUBLIC_INTERNAL_JET_TRAITS_H_
ceres-v2/include/internal/line_parameterization.h ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2020 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: jodebo_beck@gmx.de (Johannes Beck)
30
+ //
31
+
32
+ #ifndef CERES_PUBLIC_INTERNAL_LINE_PARAMETERIZATION_H_
33
+ #define CERES_PUBLIC_INTERNAL_LINE_PARAMETERIZATION_H_
34
+
35
+ #include "householder_vector.h"
36
+
37
+ namespace ceres {
38
+
39
+ template <int AmbientSpaceDimension>
40
+ bool LineParameterization<AmbientSpaceDimension>::Plus(
41
+ const double* x_ptr,
42
+ const double* delta_ptr,
43
+ double* x_plus_delta_ptr) const {
44
+ // We seek a box plus operator of the form
45
+ //
46
+ // [o*, d*] = Plus([o, d], [delta_o, delta_d])
47
+ //
48
+ // where o is the origin point, d is the direction vector, delta_o is
49
+ // the delta of the origin point and delta_d the delta of the direction and
50
+ // o* and d* is the updated origin point and direction.
51
+ //
52
+ // We separate the Plus operator into the origin point and directional part
53
+ // d* = Plus_d(d, delta_d)
54
+ // o* = Plus_o(o, d, delta_o)
55
+ //
56
+ // The direction update function Plus_d is the same as for the homogeneous
57
+ // vector parameterization:
58
+ //
59
+ // d* = H_{v(d)} [0.5 sinc(0.5 |delta_d|) delta_d, cos(0.5 |delta_d|)]^T
60
+ //
61
+ // where H is the householder matrix
62
+ // H_{v} = I - (2 / |v|^2) v v^T
63
+ // and
64
+ // v(d) = d - sign(d_n) |d| e_n.
65
+ //
66
+ // The origin point update function Plus_o is defined as
67
+ //
68
+ // o* = o + H_{v(d)} [0.5 delta_o, 0]^T.
69
+
70
+ static constexpr int kDim = AmbientSpaceDimension;
71
+ using AmbientVector = Eigen::Matrix<double, kDim, 1>;
72
+ using AmbientVectorRef = Eigen::Map<Eigen::Matrix<double, kDim, 1>>;
73
+ using ConstAmbientVectorRef =
74
+ Eigen::Map<const Eigen::Matrix<double, kDim, 1>>;
75
+ using ConstTangentVectorRef =
76
+ Eigen::Map<const Eigen::Matrix<double, kDim - 1, 1>>;
77
+
78
+ ConstAmbientVectorRef o(x_ptr);
79
+ ConstAmbientVectorRef d(x_ptr + kDim);
80
+
81
+ ConstTangentVectorRef delta_o(delta_ptr);
82
+ ConstTangentVectorRef delta_d(delta_ptr + kDim - 1);
83
+ AmbientVectorRef o_plus_delta(x_plus_delta_ptr);
84
+ AmbientVectorRef d_plus_delta(x_plus_delta_ptr + kDim);
85
+
86
+ const double norm_delta_d = delta_d.norm();
87
+
88
+ o_plus_delta = o;
89
+
90
+ // Shortcut for zero delta direction.
91
+ if (norm_delta_d == 0.0) {
92
+ d_plus_delta = d;
93
+
94
+ if (delta_o.isZero(0.0)) {
95
+ return true;
96
+ }
97
+ }
98
+
99
+ // Calculate the householder transformation which is needed for f_d and f_o.
100
+ AmbientVector v;
101
+ double beta;
102
+
103
+ // NOTE: The explicit template arguments are needed here because
104
+ // ComputeHouseholderVector is templated and some versions of MSVC
105
+ // have trouble deducing the type of v automatically.
106
+ internal::ComputeHouseholderVector<ConstAmbientVectorRef, double, kDim>(
107
+ d, &v, &beta);
108
+
109
+ if (norm_delta_d != 0.0) {
110
+ // Map the delta from the minimum representation to the over parameterized
111
+ // homogeneous vector. See section A6.9.2 on page 624 of Hartley & Zisserman
112
+ // (2nd Edition) for a detailed description. Note there is a typo on Page
113
+ // 625, line 4 so check the book errata.
114
+ const double norm_delta_div_2 = 0.5 * norm_delta_d;
115
+ const double sin_delta_by_delta =
116
+ std::sin(norm_delta_div_2) / norm_delta_div_2;
117
+
118
+ // Apply the delta update to remain on the unit sphere. See section A6.9.3
119
+ // on page 625 of Hartley & Zisserman (2nd Edition) for a detailed
120
+ // description.
121
+ AmbientVector y;
122
+ y.template head<kDim - 1>() = 0.5 * sin_delta_by_delta * delta_d;
123
+ y[kDim - 1] = std::cos(norm_delta_div_2);
124
+
125
+ d_plus_delta = d.norm() * (y - v * (beta * (v.transpose() * y)));
126
+ }
127
+
128
+ // The null space is in the direction of the line, so the tangent space is
129
+ // perpendicular to the line direction. This is achieved by using the
130
+ // householder matrix of the direction and allow only movements
131
+ // perpendicular to e_n.
132
+ //
133
+ // The factor of 0.5 is used to be consistent with the line direction
134
+ // update.
135
+ AmbientVector y;
136
+ y << 0.5 * delta_o, 0;
137
+ o_plus_delta += y - v * (beta * (v.transpose() * y));
138
+
139
+ return true;
140
+ }
141
+
142
+ template <int AmbientSpaceDimension>
143
+ bool LineParameterization<AmbientSpaceDimension>::ComputeJacobian(
144
+ const double* x_ptr, double* jacobian_ptr) const {
145
+ static constexpr int kDim = AmbientSpaceDimension;
146
+ using AmbientVector = Eigen::Matrix<double, kDim, 1>;
147
+ using ConstAmbientVectorRef =
148
+ Eigen::Map<const Eigen::Matrix<double, kDim, 1>>;
149
+ using MatrixRef = Eigen::Map<
150
+ Eigen::Matrix<double, 2 * kDim, 2 * (kDim - 1), Eigen::RowMajor>>;
151
+
152
+ ConstAmbientVectorRef d(x_ptr + kDim);
153
+ MatrixRef jacobian(jacobian_ptr);
154
+
155
+ // Clear the Jacobian as only half of the matrix is not zero.
156
+ jacobian.setZero();
157
+
158
+ AmbientVector v;
159
+ double beta;
160
+
161
+ // NOTE: The explicit template arguments are needed here because
162
+ // ComputeHouseholderVector is templated and some versions of MSVC
163
+ // have trouble deducing the type of v automatically.
164
+ internal::ComputeHouseholderVector<ConstAmbientVectorRef, double, kDim>(
165
+ d, &v, &beta);
166
+
167
+ // The Jacobian is equal to J = 0.5 * H.leftCols(kDim - 1) where H is
168
+ // the Householder matrix (H = I - beta * v * v') for the origin point. For
169
+ // the line direction part the Jacobian is scaled by the norm of the
170
+ // direction.
171
+ for (int i = 0; i < kDim - 1; ++i) {
172
+ jacobian.block(0, i, kDim, 1) = -0.5 * beta * v(i) * v;
173
+ jacobian.col(i)(i) += 0.5;
174
+ }
175
+
176
+ jacobian.template block<kDim, kDim - 1>(kDim, kDim - 1) =
177
+ jacobian.template block<kDim, kDim - 1>(0, 0) * d.norm();
178
+ return true;
179
+ }
180
+
181
+ } // namespace ceres
182
+
183
+ #endif // CERES_PUBLIC_INTERNAL_LINE_PARAMETERIZATION_H_
ceres-v2/include/internal/memory.h ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // -----------------------------------------------------------------------------
16
+ // File: memory.h
17
+ // -----------------------------------------------------------------------------
18
+ //
19
+ // This header file contains utility functions for managing the creation and
20
+ // conversion of smart pointers. This file is an extension to the C++
21
+ // standard <memory> library header file.
22
+
23
+ #ifndef CERES_PUBLIC_INTERNAL_MEMORY_H_
24
+ #define CERES_PUBLIC_INTERNAL_MEMORY_H_
25
+
26
+ #include <memory>
27
+
28
+ #ifdef CERES_HAVE_EXCEPTIONS
29
+ #define CERES_INTERNAL_TRY try
30
+ #define CERES_INTERNAL_CATCH_ANY catch (...)
31
+ #define CERES_INTERNAL_RETHROW \
32
+ do { \
33
+ throw; \
34
+ } while (false)
35
+ #else // CERES_HAVE_EXCEPTIONS
36
+ #define CERES_INTERNAL_TRY if (true)
37
+ #define CERES_INTERNAL_CATCH_ANY else if (false)
38
+ #define CERES_INTERNAL_RETHROW \
39
+ do { \
40
+ } while (false)
41
+ #endif // CERES_HAVE_EXCEPTIONS
42
+
43
+ namespace ceres {
44
+ namespace internal {
45
+
46
+ template <typename Allocator, typename Iterator, typename... Args>
47
+ void ConstructRange(Allocator& alloc,
48
+ Iterator first,
49
+ Iterator last,
50
+ const Args&... args) {
51
+ for (Iterator cur = first; cur != last; ++cur) {
52
+ CERES_INTERNAL_TRY {
53
+ std::allocator_traits<Allocator>::construct(
54
+ alloc, std::addressof(*cur), args...);
55
+ }
56
+ CERES_INTERNAL_CATCH_ANY {
57
+ while (cur != first) {
58
+ --cur;
59
+ std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
60
+ }
61
+ CERES_INTERNAL_RETHROW;
62
+ }
63
+ }
64
+ }
65
+
66
+ template <typename Allocator, typename Iterator, typename InputIterator>
67
+ void CopyRange(Allocator& alloc,
68
+ Iterator destination,
69
+ InputIterator first,
70
+ InputIterator last) {
71
+ for (Iterator cur = destination; first != last;
72
+ static_cast<void>(++cur), static_cast<void>(++first)) {
73
+ CERES_INTERNAL_TRY {
74
+ std::allocator_traits<Allocator>::construct(
75
+ alloc, std::addressof(*cur), *first);
76
+ }
77
+ CERES_INTERNAL_CATCH_ANY {
78
+ while (cur != destination) {
79
+ --cur;
80
+ std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
81
+ }
82
+ CERES_INTERNAL_RETHROW;
83
+ }
84
+ }
85
+ }
86
+
87
+ } // namespace internal
88
+ } // namespace ceres
89
+
90
+ #endif // CERES_PUBLIC_INTERNAL_MEMORY_H_
ceres-v2/include/internal/numeric_diff.h ADDED
@@ -0,0 +1,508 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2015 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+ // mierle@gmail.com (Keir Mierle)
31
+ // tbennun@gmail.com (Tal Ben-Nun)
32
+ //
33
+ // Finite differencing routines used by NumericDiffCostFunction.
34
+
35
+ #ifndef CERES_PUBLIC_INTERNAL_NUMERIC_DIFF_H_
36
+ #define CERES_PUBLIC_INTERNAL_NUMERIC_DIFF_H_
37
+
38
+ #include <cstring>
39
+ #include <utility>
40
+
41
+ #include "Eigen/Dense"
42
+ #include "Eigen/StdVector"
43
+ #include "ceres/cost_function.h"
44
+ #include "ceres/internal/fixed_array.h"
45
+ #include "ceres/internal/variadic_evaluate.h"
46
+ #include "ceres/numeric_diff_options.h"
47
+ #include "ceres/types.h"
48
+ #include "glog/logging.h"
49
+
50
+ namespace ceres {
51
+ namespace internal {
52
+
53
+ // This is split from the main class because C++ doesn't allow partial template
54
+ // specializations for member functions. The alternative is to repeat the main
55
+ // class for differing numbers of parameters, which is also unfortunate.
56
+ template <typename CostFunctor,
57
+ NumericDiffMethodType kMethod,
58
+ int kNumResiduals,
59
+ typename ParameterDims,
60
+ int kParameterBlock,
61
+ int kParameterBlockSize>
62
+ struct NumericDiff {
63
+ // Mutates parameters but must restore them before return.
64
+ static bool EvaluateJacobianForParameterBlock(
65
+ const CostFunctor* functor,
66
+ const double* residuals_at_eval_point,
67
+ const NumericDiffOptions& options,
68
+ int num_residuals,
69
+ int parameter_block_index,
70
+ int parameter_block_size,
71
+ double** parameters,
72
+ double* jacobian) {
73
+ using Eigen::ColMajor;
74
+ using Eigen::Map;
75
+ using Eigen::Matrix;
76
+ using Eigen::RowMajor;
77
+
78
+ DCHECK(jacobian);
79
+
80
+ const int num_residuals_internal =
81
+ (kNumResiduals != ceres::DYNAMIC ? kNumResiduals : num_residuals);
82
+ const int parameter_block_index_internal =
83
+ (kParameterBlock != ceres::DYNAMIC ? kParameterBlock
84
+ : parameter_block_index);
85
+ const int parameter_block_size_internal =
86
+ (kParameterBlockSize != ceres::DYNAMIC ? kParameterBlockSize
87
+ : parameter_block_size);
88
+
89
+ using ResidualVector = Matrix<double, kNumResiduals, 1>;
90
+ using ParameterVector = Matrix<double, kParameterBlockSize, 1>;
91
+
92
+ // The convoluted reasoning for choosing the Row/Column major
93
+ // ordering of the matrix is an artifact of the restrictions in
94
+ // Eigen that prevent it from creating RowMajor matrices with a
95
+ // single column. In these cases, we ask for a ColMajor matrix.
96
+ using JacobianMatrix =
97
+ Matrix<double,
98
+ kNumResiduals,
99
+ kParameterBlockSize,
100
+ (kParameterBlockSize == 1) ? ColMajor : RowMajor>;
101
+
102
+ Map<JacobianMatrix> parameter_jacobian(
103
+ jacobian, num_residuals_internal, parameter_block_size_internal);
104
+
105
+ Map<ParameterVector> x_plus_delta(
106
+ parameters[parameter_block_index_internal],
107
+ parameter_block_size_internal);
108
+ ParameterVector x(x_plus_delta);
109
+ ParameterVector step_size =
110
+ x.array().abs() * ((kMethod == RIDDERS)
111
+ ? options.ridders_relative_initial_step_size
112
+ : options.relative_step_size);
113
+
114
+ // It is not a good idea to make the step size arbitrarily
115
+ // small. This will lead to problems with round off and numerical
116
+ // instability when dividing by the step size. The general
117
+ // recommendation is to not go down below sqrt(epsilon).
118
+ double min_step_size = std::sqrt(std::numeric_limits<double>::epsilon());
119
+
120
+ // For Ridders' method, the initial step size is required to be large,
121
+ // thus ridders_relative_initial_step_size is used.
122
+ if (kMethod == RIDDERS) {
123
+ min_step_size =
124
+ (std::max)(min_step_size, options.ridders_relative_initial_step_size);
125
+ }
126
+
127
+ // For each parameter in the parameter block, use finite differences to
128
+ // compute the derivative for that parameter.
129
+ FixedArray<double> temp_residual_array(num_residuals_internal);
130
+ FixedArray<double> residual_array(num_residuals_internal);
131
+ Map<ResidualVector> residuals(residual_array.data(),
132
+ num_residuals_internal);
133
+
134
+ for (int j = 0; j < parameter_block_size_internal; ++j) {
135
+ const double delta = (std::max)(min_step_size, step_size(j));
136
+
137
+ if (kMethod == RIDDERS) {
138
+ if (!EvaluateRiddersJacobianColumn(functor,
139
+ j,
140
+ delta,
141
+ options,
142
+ num_residuals_internal,
143
+ parameter_block_size_internal,
144
+ x.data(),
145
+ residuals_at_eval_point,
146
+ parameters,
147
+ x_plus_delta.data(),
148
+ temp_residual_array.data(),
149
+ residual_array.data())) {
150
+ return false;
151
+ }
152
+ } else {
153
+ if (!EvaluateJacobianColumn(functor,
154
+ j,
155
+ delta,
156
+ num_residuals_internal,
157
+ parameter_block_size_internal,
158
+ x.data(),
159
+ residuals_at_eval_point,
160
+ parameters,
161
+ x_plus_delta.data(),
162
+ temp_residual_array.data(),
163
+ residual_array.data())) {
164
+ return false;
165
+ }
166
+ }
167
+
168
+ parameter_jacobian.col(j).matrix() = residuals;
169
+ }
170
+ return true;
171
+ }
172
+
173
+ static bool EvaluateJacobianColumn(const CostFunctor* functor,
174
+ int parameter_index,
175
+ double delta,
176
+ int num_residuals,
177
+ int parameter_block_size,
178
+ const double* x_ptr,
179
+ const double* residuals_at_eval_point,
180
+ double** parameters,
181
+ double* x_plus_delta_ptr,
182
+ double* temp_residuals_ptr,
183
+ double* residuals_ptr) {
184
+ using Eigen::Map;
185
+ using Eigen::Matrix;
186
+
187
+ using ResidualVector = Matrix<double, kNumResiduals, 1>;
188
+ using ParameterVector = Matrix<double, kParameterBlockSize, 1>;
189
+
190
+ Map<const ParameterVector> x(x_ptr, parameter_block_size);
191
+ Map<ParameterVector> x_plus_delta(x_plus_delta_ptr, parameter_block_size);
192
+
193
+ Map<ResidualVector> residuals(residuals_ptr, num_residuals);
194
+ Map<ResidualVector> temp_residuals(temp_residuals_ptr, num_residuals);
195
+
196
+ // Mutate 1 element at a time and then restore.
197
+ x_plus_delta(parameter_index) = x(parameter_index) + delta;
198
+
199
+ if (!VariadicEvaluate<ParameterDims>(
200
+ *functor, parameters, residuals.data())) {
201
+ return false;
202
+ }
203
+
204
+ // Compute this column of the jacobian in 3 steps:
205
+ // 1. Store residuals for the forward part.
206
+ // 2. Subtract residuals for the backward (or 0) part.
207
+ // 3. Divide out the run.
208
+ double one_over_delta = 1.0 / delta;
209
+ if (kMethod == CENTRAL || kMethod == RIDDERS) {
210
+ // Compute the function on the other side of x(parameter_index).
211
+ x_plus_delta(parameter_index) = x(parameter_index) - delta;
212
+
213
+ if (!VariadicEvaluate<ParameterDims>(
214
+ *functor, parameters, temp_residuals.data())) {
215
+ return false;
216
+ }
217
+
218
+ residuals -= temp_residuals;
219
+ one_over_delta /= 2;
220
+ } else {
221
+ // Forward difference only; reuse existing residuals evaluation.
222
+ residuals -=
223
+ Map<const ResidualVector>(residuals_at_eval_point, num_residuals);
224
+ }
225
+
226
+ // Restore x_plus_delta.
227
+ x_plus_delta(parameter_index) = x(parameter_index);
228
+
229
+ // Divide out the run to get slope.
230
+ residuals *= one_over_delta;
231
+
232
+ return true;
233
+ }
234
+
235
+ // This numeric difference implementation uses adaptive differentiation
236
+ // on the parameters to obtain the Jacobian matrix. The adaptive algorithm
237
+ // is based on Ridders' method for adaptive differentiation, which creates
238
+ // a Romberg tableau from varying step sizes and extrapolates the
239
+ // intermediate results to obtain the current computational error.
240
+ //
241
+ // References:
242
+ // C.J.F. Ridders, Accurate computation of F'(x) and F'(x) F"(x), Advances
243
+ // in Engineering Software (1978), Volume 4, Issue 2, April 1982,
244
+ // Pages 75-76, ISSN 0141-1195,
245
+ // http://dx.doi.org/10.1016/S0141-1195(82)80057-0.
246
+ static bool EvaluateRiddersJacobianColumn(
247
+ const CostFunctor* functor,
248
+ int parameter_index,
249
+ double delta,
250
+ const NumericDiffOptions& options,
251
+ int num_residuals,
252
+ int parameter_block_size,
253
+ const double* x_ptr,
254
+ const double* residuals_at_eval_point,
255
+ double** parameters,
256
+ double* x_plus_delta_ptr,
257
+ double* temp_residuals_ptr,
258
+ double* residuals_ptr) {
259
+ using Eigen::aligned_allocator;
260
+ using Eigen::Map;
261
+ using Eigen::Matrix;
262
+
263
+ using ResidualVector = Matrix<double, kNumResiduals, 1>;
264
+ using ResidualCandidateMatrix =
265
+ Matrix<double, kNumResiduals, Eigen::Dynamic>;
266
+ using ParameterVector = Matrix<double, kParameterBlockSize, 1>;
267
+
268
+ Map<const ParameterVector> x(x_ptr, parameter_block_size);
269
+ Map<ParameterVector> x_plus_delta(x_plus_delta_ptr, parameter_block_size);
270
+
271
+ Map<ResidualVector> residuals(residuals_ptr, num_residuals);
272
+ Map<ResidualVector> temp_residuals(temp_residuals_ptr, num_residuals);
273
+
274
+ // In order for the algorithm to converge, the step size should be
275
+ // initialized to a value that is large enough to produce a significant
276
+ // change in the function.
277
+ // As the derivative is estimated, the step size decreases.
278
+ // By default, the step sizes are chosen so that the middle column
279
+ // of the Romberg tableau uses the input delta.
280
+ double current_step_size =
281
+ delta * pow(options.ridders_step_shrink_factor,
282
+ options.max_num_ridders_extrapolations / 2);
283
+
284
+ // Double-buffering temporary differential candidate vectors
285
+ // from previous step size.
286
+ ResidualCandidateMatrix stepsize_candidates_a(
287
+ num_residuals, options.max_num_ridders_extrapolations);
288
+ ResidualCandidateMatrix stepsize_candidates_b(
289
+ num_residuals, options.max_num_ridders_extrapolations);
290
+ ResidualCandidateMatrix* current_candidates = &stepsize_candidates_a;
291
+ ResidualCandidateMatrix* previous_candidates = &stepsize_candidates_b;
292
+
293
+ // Represents the computational error of the derivative. This variable is
294
+ // initially set to a large value, and is set to the difference between
295
+ // current and previous finite difference extrapolations.
296
+ // norm_error is supposed to decrease as the finite difference tableau
297
+ // generation progresses, serving both as an estimate for differentiation
298
+ // error and as a measure of differentiation numerical stability.
299
+ double norm_error = (std::numeric_limits<double>::max)();
300
+
301
+ // Loop over decreasing step sizes until:
302
+ // 1. Error is smaller than a given value (ridders_epsilon),
303
+ // 2. Maximal order of extrapolation reached, or
304
+ // 3. Extrapolation becomes numerically unstable.
305
+ for (int i = 0; i < options.max_num_ridders_extrapolations; ++i) {
306
+ // Compute the numerical derivative at this step size.
307
+ if (!EvaluateJacobianColumn(functor,
308
+ parameter_index,
309
+ current_step_size,
310
+ num_residuals,
311
+ parameter_block_size,
312
+ x.data(),
313
+ residuals_at_eval_point,
314
+ parameters,
315
+ x_plus_delta.data(),
316
+ temp_residuals.data(),
317
+ current_candidates->col(0).data())) {
318
+ // Something went wrong; bail.
319
+ return false;
320
+ }
321
+
322
+ // Store initial results.
323
+ if (i == 0) {
324
+ residuals = current_candidates->col(0);
325
+ }
326
+
327
+ // Shrink differentiation step size.
328
+ current_step_size /= options.ridders_step_shrink_factor;
329
+
330
+ // Extrapolation factor for Richardson acceleration method (see below).
331
+ double richardson_factor = options.ridders_step_shrink_factor *
332
+ options.ridders_step_shrink_factor;
333
+ for (int k = 1; k <= i; ++k) {
334
+ // Extrapolate the various orders of finite differences using
335
+ // the Richardson acceleration method.
336
+ current_candidates->col(k) =
337
+ (richardson_factor * current_candidates->col(k - 1) -
338
+ previous_candidates->col(k - 1)) /
339
+ (richardson_factor - 1.0);
340
+
341
+ richardson_factor *= options.ridders_step_shrink_factor *
342
+ options.ridders_step_shrink_factor;
343
+
344
+ // Compute the difference between the previous value and the current.
345
+ double candidate_error = (std::max)(
346
+ (current_candidates->col(k) - current_candidates->col(k - 1))
347
+ .norm(),
348
+ (current_candidates->col(k) - previous_candidates->col(k - 1))
349
+ .norm());
350
+
351
+ // If the error has decreased, update results.
352
+ if (candidate_error <= norm_error) {
353
+ norm_error = candidate_error;
354
+ residuals = current_candidates->col(k);
355
+
356
+ // If the error is small enough, stop.
357
+ if (norm_error < options.ridders_epsilon) {
358
+ break;
359
+ }
360
+ }
361
+ }
362
+
363
+ // After breaking out of the inner loop, declare convergence.
364
+ if (norm_error < options.ridders_epsilon) {
365
+ break;
366
+ }
367
+
368
+ // Check to see if the current gradient estimate is numerically unstable.
369
+ // If so, bail out and return the last stable result.
370
+ if (i > 0) {
371
+ double tableau_error =
372
+ (current_candidates->col(i) - previous_candidates->col(i - 1))
373
+ .norm();
374
+
375
+ // Compare current error to the chosen candidate's error.
376
+ if (tableau_error >= 2 * norm_error) {
377
+ break;
378
+ }
379
+ }
380
+
381
+ std::swap(current_candidates, previous_candidates);
382
+ }
383
+ return true;
384
+ }
385
+ };
386
+
387
+ // This function calls NumericDiff<...>::EvaluateJacobianForParameterBlock for
388
+ // each parameter block.
389
+ //
390
+ // Example:
391
+ // A call to
392
+ // EvaluateJacobianForParameterBlocks<StaticParameterDims<2, 3>>(
393
+ // functor,
394
+ // residuals_at_eval_point,
395
+ // options,
396
+ // num_residuals,
397
+ // parameters,
398
+ // jacobians);
399
+ // will result in the following calls to
400
+ // NumericDiff<...>::EvaluateJacobianForParameterBlock:
401
+ //
402
+ // if (jacobians[0] != nullptr) {
403
+ // if (!NumericDiff<
404
+ // CostFunctor,
405
+ // method,
406
+ // kNumResiduals,
407
+ // StaticParameterDims<2, 3>,
408
+ // 0,
409
+ // 2>::EvaluateJacobianForParameterBlock(functor,
410
+ // residuals_at_eval_point,
411
+ // options,
412
+ // num_residuals,
413
+ // 0,
414
+ // 2,
415
+ // parameters,
416
+ // jacobians[0])) {
417
+ // return false;
418
+ // }
419
+ // }
420
+ // if (jacobians[1] != nullptr) {
421
+ // if (!NumericDiff<
422
+ // CostFunctor,
423
+ // method,
424
+ // kNumResiduals,
425
+ // StaticParameterDims<2, 3>,
426
+ // 1,
427
+ // 3>::EvaluateJacobianForParameterBlock(functor,
428
+ // residuals_at_eval_point,
429
+ // options,
430
+ // num_residuals,
431
+ // 1,
432
+ // 3,
433
+ // parameters,
434
+ // jacobians[1])) {
435
+ // return false;
436
+ // }
437
+ // }
438
+ template <typename ParameterDims,
439
+ typename Parameters = typename ParameterDims::Parameters,
440
+ int ParameterIdx = 0>
441
+ struct EvaluateJacobianForParameterBlocks;
442
+
443
+ template <typename ParameterDims, int N, int... Ns, int ParameterIdx>
444
+ struct EvaluateJacobianForParameterBlocks<ParameterDims,
445
+ std::integer_sequence<int, N, Ns...>,
446
+ ParameterIdx> {
447
+ template <NumericDiffMethodType method,
448
+ int kNumResiduals,
449
+ typename CostFunctor>
450
+ static bool Apply(const CostFunctor* functor,
451
+ const double* residuals_at_eval_point,
452
+ const NumericDiffOptions& options,
453
+ int num_residuals,
454
+ double** parameters,
455
+ double** jacobians) {
456
+ if (jacobians[ParameterIdx] != nullptr) {
457
+ if (!NumericDiff<
458
+ CostFunctor,
459
+ method,
460
+ kNumResiduals,
461
+ ParameterDims,
462
+ ParameterIdx,
463
+ N>::EvaluateJacobianForParameterBlock(functor,
464
+ residuals_at_eval_point,
465
+ options,
466
+ num_residuals,
467
+ ParameterIdx,
468
+ N,
469
+ parameters,
470
+ jacobians[ParameterIdx])) {
471
+ return false;
472
+ }
473
+ }
474
+
475
+ return EvaluateJacobianForParameterBlocks<ParameterDims,
476
+ std::integer_sequence<int, Ns...>,
477
+ ParameterIdx + 1>::
478
+ template Apply<method, kNumResiduals>(functor,
479
+ residuals_at_eval_point,
480
+ options,
481
+ num_residuals,
482
+ parameters,
483
+ jacobians);
484
+ }
485
+ };
486
+
487
+ // End of 'recursion'. Nothing more to do.
488
+ template <typename ParameterDims, int ParameterIdx>
489
+ struct EvaluateJacobianForParameterBlocks<ParameterDims,
490
+ std::integer_sequence<int>,
491
+ ParameterIdx> {
492
+ template <NumericDiffMethodType method,
493
+ int kNumResiduals,
494
+ typename CostFunctor>
495
+ static bool Apply(const CostFunctor* /* NOT USED*/,
496
+ const double* /* NOT USED*/,
497
+ const NumericDiffOptions& /* NOT USED*/,
498
+ int /* NOT USED*/,
499
+ double** /* NOT USED*/,
500
+ double** /* NOT USED*/) {
501
+ return true;
502
+ }
503
+ };
504
+
505
+ } // namespace internal
506
+ } // namespace ceres
507
+
508
+ #endif // CERES_PUBLIC_INTERNAL_NUMERIC_DIFF_H_
ceres-v2/include/internal/parameter_dims.h ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2018 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: jodebo_beck@gmx.de (Johannes Beck)
30
+
31
+ #ifndef CERES_PUBLIC_INTERNAL_PARAMETER_DIMS_H_
32
+ #define CERES_PUBLIC_INTERNAL_PARAMETER_DIMS_H_
33
+
34
+ #include <array>
35
+ #include <utility>
36
+
37
+ #include "ceres/internal/integer_sequence_algorithm.h"
38
+
39
+ namespace ceres {
40
+ namespace internal {
41
+
42
+ // Checks, whether the given parameter block sizes are valid. Valid means every
43
+ // dimension is bigger than zero.
44
+ constexpr bool IsValidParameterDimensionSequence(std::integer_sequence<int>) {
45
+ return true;
46
+ }
47
+
48
+ template <int N, int... Ts>
49
+ constexpr bool IsValidParameterDimensionSequence(
50
+ std::integer_sequence<int, N, Ts...>) {
51
+ return (N <= 0) ? false
52
+ : IsValidParameterDimensionSequence(
53
+ std::integer_sequence<int, Ts...>());
54
+ }
55
+
56
+ // Helper class that represents the parameter dimensions. The parameter
57
+ // dimensions are either dynamic or the sizes are known at compile time. It is
58
+ // used to pass parameter block dimensions around (e.g. between functions or
59
+ // classes).
60
+ //
61
+ // As an example if one have three parameter blocks with dimensions (2, 4, 1),
62
+ // one would use 'StaticParameterDims<2, 4, 1>' which is a synonym for
63
+ // 'ParameterDims<false, 2, 4, 1>'.
64
+ // For dynamic parameter dims, one would just use 'DynamicParameterDims', which
65
+ // is a synonym for 'ParameterDims<true>'.
66
+ template <bool IsDynamic, int... Ns>
67
+ class ParameterDims {
68
+ public:
69
+ using Parameters = std::integer_sequence<int, Ns...>;
70
+
71
+ // The parameter dimensions are only valid if all parameter block dimensions
72
+ // are greater than zero.
73
+ static constexpr bool kIsValid =
74
+ IsValidParameterDimensionSequence(Parameters());
75
+ static_assert(kIsValid,
76
+ "Invalid parameter block dimension detected. Each parameter "
77
+ "block dimension must be bigger than zero.");
78
+
79
+ static constexpr bool kIsDynamic = IsDynamic;
80
+ static constexpr int kNumParameterBlocks = sizeof...(Ns);
81
+ static_assert(kIsDynamic || kNumParameterBlocks > 0,
82
+ "At least one parameter block must be specified.");
83
+
84
+ static constexpr int kNumParameters =
85
+ Sum<std::integer_sequence<int, Ns...>>::Value;
86
+
87
+ static constexpr int GetDim(int dim) { return params_[dim]; }
88
+
89
+ // If one has all parameters packed into a single array this function unpacks
90
+ // the parameters.
91
+ template <typename T>
92
+ static inline std::array<T*, kNumParameterBlocks> GetUnpackedParameters(
93
+ T* ptr) {
94
+ using Offsets = ExclusiveScan<Parameters>;
95
+ return GetUnpackedParameters(ptr, Offsets());
96
+ }
97
+
98
+ private:
99
+ template <typename T, int... Indices>
100
+ static inline std::array<T*, kNumParameterBlocks> GetUnpackedParameters(
101
+ T* ptr, std::integer_sequence<int, Indices...>) {
102
+ return std::array<T*, kNumParameterBlocks>{{ptr + Indices...}};
103
+ }
104
+
105
+ static constexpr std::array<int, kNumParameterBlocks> params_{Ns...};
106
+ };
107
+
108
+ // Even static constexpr member variables needs to be defined (not only
109
+ // declared). As the ParameterDims class is tempalted this definition must
110
+ // be in the header file.
111
+ template <bool IsDynamic, int... Ns>
112
+ constexpr std::array<int, ParameterDims<IsDynamic, Ns...>::kNumParameterBlocks>
113
+ ParameterDims<IsDynamic, Ns...>::params_;
114
+
115
+ // Using declarations for static and dynamic parameter dims. This makes client
116
+ // code easier to read.
117
+ template <int... Ns>
118
+ using StaticParameterDims = ParameterDims<false, Ns...>;
119
+ using DynamicParameterDims = ParameterDims<true>;
120
+
121
+ } // namespace internal
122
+ } // namespace ceres
123
+
124
+ #endif // CERES_PUBLIC_INTERNAL_PARAMETER_DIMS_H_
ceres-v2/include/internal/port.h ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: keir@google.com (Keir Mierle)
30
+
31
+ #ifndef CERES_PUBLIC_INTERNAL_PORT_H_
32
+ #define CERES_PUBLIC_INTERNAL_PORT_H_
33
+
34
+ // A macro to mark a function/variable/class as deprecated.
35
+ // We use compiler specific attributes rather than the c++
36
+ // attribute because they do not mix well with each other.
37
+ #if defined(_MSC_VER)
38
+ #define CERES_DEPRECATED_WITH_MSG(message) __declspec(deprecated(message))
39
+ #elif defined(__GNUC__)
40
+ #define CERES_DEPRECATED_WITH_MSG(message) __attribute__((deprecated(message)))
41
+ #else
42
+ // In the worst case fall back to c++ attribute.
43
+ #define CERES_DEPRECATED_WITH_MSG(message) [[deprecated(message)]]
44
+ #endif
45
+
46
+ #ifndef CERES_GET_FLAG
47
+ #define CERES_GET_FLAG(X) X
48
+ #endif
49
+
50
+ // Indicates whether C++17 is currently active
51
+ #ifndef CERES_HAS_CPP17
52
+ #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
53
+ #define CERES_HAS_CPP17
54
+ #endif // __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >=
55
+ // 201703L)
56
+ #endif // !defined(CERES_HAS_CPP17)
57
+
58
+ // Indicates whether C++20 is currently active
59
+ #ifndef CERES_HAS_CPP20
60
+ #if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
61
+ #define CERES_HAS_CPP20
62
+ #endif // __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >=
63
+ // 202002L)
64
+ #endif // !defined(CERES_HAS_CPP20)
65
+
66
+ // Prevents symbols from being substituted by the corresponding macro definition
67
+ // under the same name. For instance, min and max are defined as macros on
68
+ // Windows (unless NOMINMAX is defined) which causes compilation errors when
69
+ // defining or referencing symbols under the same name.
70
+ //
71
+ // To be robust in all cases particularly when NOMINMAX cannot be used, use this
72
+ // macro to annotate min/max declarations/definitions. Examples:
73
+ //
74
+ // int max CERES_PREVENT_MACRO_SUBSTITUTION();
75
+ // min CERES_PREVENT_MACRO_SUBSTITUTION(a, b);
76
+ // max CERES_PREVENT_MACRO_SUBSTITUTION(a, b);
77
+ //
78
+ // NOTE: In case the symbols for which the substitution must be prevented are
79
+ // used within another macro, the substitution must be inhibited using parens as
80
+ //
81
+ // (std::numerical_limits<double>::max)()
82
+ //
83
+ // since the helper macro will not work here. Do not use this technique in
84
+ // general case, because it will prevent argument-dependent lookup (ADL).
85
+ //
86
+ #define CERES_PREVENT_MACRO_SUBSTITUTION // Yes, it's empty
87
+
88
+ #endif // CERES_PUBLIC_INTERNAL_PORT_H_
ceres-v2/include/internal/reenable_warnings.h ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2015 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+
30
+ // This is not your usual header guard. See disable_warnings.h
31
+ #ifdef CERES_WARNINGS_DISABLED
32
+ #undef CERES_WARNINGS_DISABLED
33
+
34
+ #ifdef _MSC_VER
35
+ #pragma warning(pop)
36
+ #endif
37
+
38
+ #endif // CERES_WARNINGS_DISABLED
ceres-v2/include/internal/sphere_manifold_functions.h ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: vitus@google.com (Mike Vitus)
30
+ // jodebo_beck@gmx.de (Johannes Beck)
31
+
32
+ #ifndef CERES_PUBLIC_INTERNAL_SPHERE_MANIFOLD_HELPERS_H_
33
+ #define CERES_PUBLIC_INTERNAL_SPHERE_MANIFOLD_HELPERS_H_
34
+
35
+ #include "ceres/internal/householder_vector.h"
36
+
37
+ // This module contains functions to compute the SphereManifold plus and minus
38
+ // operator and their Jacobians.
39
+ //
40
+ // As the parameters to these functions are shared between them, they are
41
+ // described here: The following variable names are used:
42
+ // Plus(x, delta) = x + delta = x_plus_delta,
43
+ // Minus(y, x) = y - x = y_minus_x.
44
+ //
45
+ // The remaining ones are v and beta which describe the Householder
46
+ // transformation of x, and norm_delta which is the norm of delta.
47
+ //
48
+ // The types of x, y, x_plus_delta and y_minus_x need to be equivalent to
49
+ // Eigen::Matrix<double, AmbientSpaceDimension, 1> and the type of delta needs
50
+ // to be equivalent to Eigen::Matrix<double, TangentSpaceDimension, 1>.
51
+ //
52
+ // The type of Jacobian plus needs to be equivalent to Eigen::Matrix<double,
53
+ // AmbientSpaceDimension, TangentSpaceDimension, Eigen::RowMajor> and for
54
+ // Jacobian minus Eigen::Matrix<double, TangentSpaceDimension,
55
+ // AmbientSpaceDimension, Eigen::RowMajor>.
56
+ //
57
+ // For all vector / matrix inputs and outputs, template parameters are
58
+ // used in order to allow also Eigen::Ref and Eigen block expressions to
59
+ // be passed to the function.
60
+
61
+ namespace ceres {
62
+ namespace internal {
63
+
64
+ template <typename VT, typename XT, typename DeltaT, typename XPlusDeltaT>
65
+ inline void ComputeSphereManifoldPlus(const VT& v,
66
+ double beta,
67
+ const XT& x,
68
+ const DeltaT& delta,
69
+ double norm_delta,
70
+ XPlusDeltaT* x_plus_delta) {
71
+ constexpr int AmbientDim = VT::RowsAtCompileTime;
72
+
73
+ // Map the delta from the minimum representation to the over parameterized
74
+ // homogeneous vector. See B.2 p.25 equation (106) - (107) for more details.
75
+ const double norm_delta_div_2 = 0.5 * norm_delta;
76
+ const double sin_delta_by_delta =
77
+ std::sin(norm_delta_div_2) / norm_delta_div_2;
78
+
79
+ Eigen::Matrix<double, AmbientDim, 1> y(v.size());
80
+ y << 0.5 * sin_delta_by_delta * delta, std::cos(norm_delta_div_2);
81
+
82
+ // Apply the delta update to remain on the sphere.
83
+ *x_plus_delta = x.norm() * ApplyHouseholderVector(y, v, beta);
84
+ }
85
+
86
+ template <typename VT, typename JacobianT>
87
+ inline void ComputeSphereManifoldPlusJacobian(const VT& x,
88
+ JacobianT* jacobian) {
89
+ constexpr int AmbientSpaceDim = VT::RowsAtCompileTime;
90
+ using AmbientVector = Eigen::Matrix<double, AmbientSpaceDim, 1>;
91
+ const int ambient_size = x.size();
92
+ const int tangent_size = x.size() - 1;
93
+
94
+ AmbientVector v(ambient_size);
95
+ double beta;
96
+
97
+ // NOTE: The explicit template arguments are needed here because
98
+ // ComputeHouseholderVector is templated and some versions of MSVC
99
+ // have trouble deducing the type of v automatically.
100
+ ComputeHouseholderVector<VT, double, AmbientSpaceDim>(x, &v, &beta);
101
+
102
+ // The Jacobian is equal to J = 0.5 * H.leftCols(size_ - 1) where H is the
103
+ // Householder matrix (H = I - beta * v * v').
104
+ for (int i = 0; i < tangent_size; ++i) {
105
+ (*jacobian).col(i) = -0.5 * beta * v(i) * v;
106
+ (*jacobian)(i, i) += 0.5;
107
+ }
108
+ (*jacobian) *= x.norm();
109
+ }
110
+
111
+ template <typename VT, typename XT, typename YT, typename YMinusXT>
112
+ inline void ComputeSphereManifoldMinus(
113
+ const VT& v, double beta, const XT& x, const YT& y, YMinusXT* y_minus_x) {
114
+ constexpr int AmbientSpaceDim = VT::RowsAtCompileTime;
115
+ constexpr int TangentSpaceDim =
116
+ AmbientSpaceDim == Eigen::Dynamic ? Eigen::Dynamic : AmbientSpaceDim - 1;
117
+ using AmbientVector = Eigen::Matrix<double, AmbientSpaceDim, 1>;
118
+
119
+ const int tanget_size = v.size() - 1;
120
+
121
+ const AmbientVector hy = ApplyHouseholderVector(y, v, beta) / x.norm();
122
+
123
+ // Calculate y - x. See B.2 p.25 equation (108).
124
+ double y_last = hy[tanget_size];
125
+ double hy_norm = hy.template head<TangentSpaceDim>(tanget_size).norm();
126
+ if (hy_norm == 0.0) {
127
+ y_minus_x->setZero();
128
+ } else {
129
+ *y_minus_x = 2.0 * std::atan2(hy_norm, y_last) / hy_norm *
130
+ hy.template head<TangentSpaceDim>(tanget_size);
131
+ }
132
+ }
133
+
134
+ template <typename VT, typename JacobianT>
135
+ inline void ComputeSphereManifoldMinusJacobian(const VT& x,
136
+ JacobianT* jacobian) {
137
+ constexpr int AmbientSpaceDim = VT::RowsAtCompileTime;
138
+ using AmbientVector = Eigen::Matrix<double, AmbientSpaceDim, 1>;
139
+ const int ambient_size = x.size();
140
+ const int tangent_size = x.size() - 1;
141
+
142
+ AmbientVector v(ambient_size);
143
+ double beta;
144
+
145
+ // NOTE: The explicit template arguments are needed here because
146
+ // ComputeHouseholderVector is templated and some versions of MSVC
147
+ // have trouble deducing the type of v automatically.
148
+ ComputeHouseholderVector<VT, double, AmbientSpaceDim>(x, &v, &beta);
149
+
150
+ // The Jacobian is equal to J = 2.0 * H.leftCols(size_ - 1) where H is the
151
+ // Householder matrix (H = I - beta * v * v').
152
+ for (int i = 0; i < tangent_size; ++i) {
153
+ (*jacobian).row(i) = -2.0 * beta * v(i) * v;
154
+ (*jacobian)(i, i) += 2.0;
155
+ }
156
+ (*jacobian) /= x.norm();
157
+ }
158
+
159
+ } // namespace internal
160
+ } // namespace ceres
161
+
162
+ #endif
ceres-v2/include/internal/variadic_evaluate.h ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2015 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+ // mierle@gmail.com (Keir Mierle)
31
+ // jodebo_beck@gmx.de (Johannes Beck)
32
+
33
+ #ifndef CERES_PUBLIC_INTERNAL_VARIADIC_EVALUATE_H_
34
+ #define CERES_PUBLIC_INTERNAL_VARIADIC_EVALUATE_H_
35
+
36
+ #include <cstddef>
37
+ #include <type_traits>
38
+ #include <utility>
39
+
40
+ #include "ceres/cost_function.h"
41
+ #include "ceres/internal/parameter_dims.h"
42
+
43
+ namespace ceres {
44
+ namespace internal {
45
+
46
+ // For fixed size cost functors
47
+ template <typename Functor, typename T, int... Indices>
48
+ inline bool VariadicEvaluateImpl(const Functor& functor,
49
+ T const* const* input,
50
+ T* output,
51
+ std::false_type /*is_dynamic*/,
52
+ std::integer_sequence<int, Indices...>) {
53
+ static_assert(sizeof...(Indices),
54
+ "Invalid number of parameter blocks. At least one parameter "
55
+ "block must be specified.");
56
+ return functor(input[Indices]..., output);
57
+ }
58
+
59
+ // For dynamic sized cost functors
60
+ template <typename Functor, typename T>
61
+ inline bool VariadicEvaluateImpl(const Functor& functor,
62
+ T const* const* input,
63
+ T* output,
64
+ std::true_type /*is_dynamic*/,
65
+ std::integer_sequence<int>) {
66
+ return functor(input, output);
67
+ }
68
+
69
+ // For ceres cost functors (not ceres::CostFunction)
70
+ template <typename ParameterDims, typename Functor, typename T>
71
+ inline bool VariadicEvaluateImpl(const Functor& functor,
72
+ T const* const* input,
73
+ T* output,
74
+ const void* /* NOT USED */) {
75
+ using ParameterBlockIndices =
76
+ std::make_integer_sequence<int, ParameterDims::kNumParameterBlocks>;
77
+ using IsDynamic = std::integral_constant<bool, ParameterDims::kIsDynamic>;
78
+ return VariadicEvaluateImpl(
79
+ functor, input, output, IsDynamic(), ParameterBlockIndices());
80
+ }
81
+
82
+ // For ceres::CostFunction
83
+ template <typename ParameterDims, typename Functor, typename T>
84
+ inline bool VariadicEvaluateImpl(const Functor& functor,
85
+ T const* const* input,
86
+ T* output,
87
+ const CostFunction* /* NOT USED */) {
88
+ return functor.Evaluate(input, output, nullptr);
89
+ }
90
+
91
+ // Variadic evaluate is a helper function to evaluate ceres cost function or
92
+ // functors using an input, output and the parameter dimensions. There are
93
+ // several ways different possibilities:
94
+ // 1) If the passed functor is a 'ceres::CostFunction' its evaluate method is
95
+ // called.
96
+ // 2) If the functor is not a 'ceres::CostFunction' and the specified parameter
97
+ // dims is dynamic, the functor must have the following signature
98
+ // 'bool(T const* const* input, T* output)'.
99
+ // 3) If the functor is not a 'ceres::CostFunction' and the specified parameter
100
+ // dims is not dynamic, the input is expanded by using the number of parameter
101
+ // blocks. The signature of the functor must have the following signature
102
+ // 'bool()(const T* i_1, const T* i_2, ... const T* i_n, T* output)'.
103
+ template <typename ParameterDims, typename Functor, typename T>
104
+ inline bool VariadicEvaluate(const Functor& functor,
105
+ T const* const* input,
106
+ T* output) {
107
+ return VariadicEvaluateImpl<ParameterDims>(functor, input, output, &functor);
108
+ }
109
+
110
+ } // namespace internal
111
+ } // namespace ceres
112
+
113
+ #endif // CERES_PUBLIC_INTERNAL_VARIADIC_EVALUATE_H_
ceres-v2/include/iteration_callback.h ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+ //
31
+ // When an iteration callback is specified, Ceres calls the callback
32
+ // after each minimizer step (if the minimizer has not converged) and
33
+ // passes it an IterationSummary object, defined below.
34
+
35
+ #ifndef CERES_PUBLIC_ITERATION_CALLBACK_H_
36
+ #define CERES_PUBLIC_ITERATION_CALLBACK_H_
37
+
38
+ #include "ceres/internal/disable_warnings.h"
39
+ #include "ceres/internal/export.h"
40
+ #include "ceres/types.h"
41
+
42
+ namespace ceres {
43
+
44
+ // This struct describes the state of the optimizer after each
45
+ // iteration of the minimization.
46
+ struct CERES_EXPORT IterationSummary {
47
+ // Current iteration number.
48
+ int iteration = 0;
49
+
50
+ // Step was numerically valid, i.e., all values are finite and the
51
+ // step reduces the value of the linearized model.
52
+ //
53
+ // Note: step_is_valid is always true when iteration = 0.
54
+ bool step_is_valid = false;
55
+
56
+ // Step did not reduce the value of the objective function
57
+ // sufficiently, but it was accepted because of the relaxed
58
+ // acceptance criterion used by the non-monotonic trust region
59
+ // algorithm.
60
+ //
61
+ // Note: step_is_nonmonotonic is always false when iteration = 0;
62
+ bool step_is_nonmonotonic = false;
63
+
64
+ // Whether or not the minimizer accepted this step or not. If the
65
+ // ordinary trust region algorithm is used, this means that the
66
+ // relative reduction in the objective function value was greater
67
+ // than Solver::Options::min_relative_decrease. However, if the
68
+ // non-monotonic trust region algorithm is used
69
+ // (Solver::Options:use_nonmonotonic_steps = true), then even if the
70
+ // relative decrease is not sufficient, the algorithm may accept the
71
+ // step and the step is declared successful.
72
+ //
73
+ // Note: step_is_successful is always true when iteration = 0.
74
+ bool step_is_successful = false;
75
+
76
+ // Value of the objective function.
77
+ double cost = 0.0;
78
+
79
+ // Change in the value of the objective function in this
80
+ // iteration. This can be positive or negative.
81
+ double cost_change = 0.0;
82
+
83
+ // Infinity norm of the gradient vector.
84
+ double gradient_max_norm = 0.0;
85
+
86
+ // 2-norm of the gradient vector.
87
+ double gradient_norm = 0.0;
88
+
89
+ // 2-norm of the size of the step computed by the optimization
90
+ // algorithm.
91
+ double step_norm = 0.0;
92
+
93
+ // For trust region algorithms, the ratio of the actual change in
94
+ // cost and the change in the cost of the linearized approximation.
95
+ double relative_decrease = 0.0;
96
+
97
+ // Size of the trust region at the end of the current iteration. For
98
+ // the Levenberg-Marquardt algorithm, the regularization parameter
99
+ // mu = 1.0 / trust_region_radius.
100
+ double trust_region_radius = 0.0;
101
+
102
+ // For the inexact step Levenberg-Marquardt algorithm, this is the
103
+ // relative accuracy with which the Newton(LM) step is solved. This
104
+ // number affects only the iterative solvers capable of solving
105
+ // linear systems inexactly. Factorization-based exact solvers
106
+ // ignore it.
107
+ double eta = 0.0;
108
+
109
+ // Step sized computed by the line search algorithm.
110
+ double step_size = 0.0;
111
+
112
+ // Number of function value evaluations used by the line search algorithm.
113
+ int line_search_function_evaluations = 0;
114
+
115
+ // Number of function gradient evaluations used by the line search algorithm.
116
+ int line_search_gradient_evaluations = 0;
117
+
118
+ // Number of iterations taken by the line search algorithm.
119
+ int line_search_iterations = 0;
120
+
121
+ // Number of iterations taken by the linear solver to solve for the
122
+ // Newton step.
123
+ int linear_solver_iterations = 0;
124
+
125
+ // All times reported below are wall times.
126
+
127
+ // Time (in seconds) spent inside the minimizer loop in the current
128
+ // iteration.
129
+ double iteration_time_in_seconds = 0.0;
130
+
131
+ // Time (in seconds) spent inside the trust region step solver.
132
+ double step_solver_time_in_seconds = 0.0;
133
+
134
+ // Time (in seconds) since the user called Solve().
135
+ double cumulative_time_in_seconds = 0.0;
136
+ };
137
+
138
+ // Interface for specifying callbacks that are executed at the end of
139
+ // each iteration of the Minimizer. The solver uses the return value
140
+ // of operator() to decide whether to continue solving or to
141
+ // terminate. The user can return three values.
142
+ //
143
+ // SOLVER_ABORT indicates that the callback detected an abnormal
144
+ // situation. The solver returns without updating the parameter blocks
145
+ // (unless Solver::Options::update_state_every_iteration is set
146
+ // true). Solver returns with Solver::Summary::termination_type set to
147
+ // USER_ABORT.
148
+ //
149
+ // SOLVER_TERMINATE_SUCCESSFULLY indicates that there is no need to
150
+ // optimize anymore (some user specified termination criterion has
151
+ // been met). Solver returns with Solver::Summary::termination_type
152
+ // set to USER_SUCCESS.
153
+ //
154
+ // SOLVER_CONTINUE indicates that the solver should continue
155
+ // optimizing.
156
+ //
157
+ // For example, the following Callback is used internally by Ceres to
158
+ // log the progress of the optimization.
159
+ //
160
+ // Callback for logging the state of the minimizer to STDERR or STDOUT
161
+ // depending on the user's preferences and logging level.
162
+ //
163
+ // class LoggingCallback : public IterationCallback {
164
+ // public:
165
+ // explicit LoggingCallback(bool log_to_stdout)
166
+ // : log_to_stdout_(log_to_stdout) {}
167
+ //
168
+ // CallbackReturnType operator()(const IterationSummary& summary) {
169
+ // const char* kReportRowFormat =
170
+ // "% 4d: f:% 8e d:% 3.2e g:% 3.2e h:% 3.2e "
171
+ // "rho:% 3.2e mu:% 3.2e eta:% 3.2e li:% 3d";
172
+ // string output = StringPrintf(kReportRowFormat,
173
+ // summary.iteration,
174
+ // summary.cost,
175
+ // summary.cost_change,
176
+ // summary.gradient_max_norm,
177
+ // summary.step_norm,
178
+ // summary.relative_decrease,
179
+ // summary.trust_region_radius,
180
+ // summary.eta,
181
+ // summary.linear_solver_iterations);
182
+ // if (log_to_stdout_) {
183
+ // cout << output << endl;
184
+ // } else {
185
+ // VLOG(1) << output;
186
+ // }
187
+ // return SOLVER_CONTINUE;
188
+ // }
189
+ //
190
+ // private:
191
+ // const bool log_to_stdout_;
192
+ // };
193
+ //
194
+ class CERES_EXPORT IterationCallback {
195
+ public:
196
+ virtual ~IterationCallback();
197
+ virtual CallbackReturnType operator()(const IterationSummary& summary) = 0;
198
+ };
199
+
200
+ } // namespace ceres
201
+
202
+ #include "ceres/internal/reenable_warnings.h"
203
+
204
+ #endif // CERES_PUBLIC_ITERATION_CALLBACK_H_
ceres-v2/include/jet.h ADDED
@@ -0,0 +1,1387 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: keir@google.com (Keir Mierle)
30
+ //
31
+ // A simple implementation of N-dimensional dual numbers, for automatically
32
+ // computing exact derivatives of functions.
33
+ //
34
+ // While a complete treatment of the mechanics of automatic differentiation is
35
+ // beyond the scope of this header (see
36
+ // http://en.wikipedia.org/wiki/Automatic_differentiation for details), the
37
+ // basic idea is to extend normal arithmetic with an extra element, "e," often
38
+ // denoted with the greek symbol epsilon, such that e != 0 but e^2 = 0. Dual
39
+ // numbers are extensions of the real numbers analogous to complex numbers:
40
+ // whereas complex numbers augment the reals by introducing an imaginary unit i
41
+ // such that i^2 = -1, dual numbers introduce an "infinitesimal" unit e such
42
+ // that e^2 = 0. Dual numbers have two components: the "real" component and the
43
+ // "infinitesimal" component, generally written as x + y*e. Surprisingly, this
44
+ // leads to a convenient method for computing exact derivatives without needing
45
+ // to manipulate complicated symbolic expressions.
46
+ //
47
+ // For example, consider the function
48
+ //
49
+ // f(x) = x^2 ,
50
+ //
51
+ // evaluated at 10. Using normal arithmetic, f(10) = 100, and df/dx(10) = 20.
52
+ // Next, argument 10 with an infinitesimal to get:
53
+ //
54
+ // f(10 + e) = (10 + e)^2
55
+ // = 100 + 2 * 10 * e + e^2
56
+ // = 100 + 20 * e -+-
57
+ // -- |
58
+ // | +--- This is zero, since e^2 = 0
59
+ // |
60
+ // +----------------- This is df/dx!
61
+ //
62
+ // Note that the derivative of f with respect to x is simply the infinitesimal
63
+ // component of the value of f(x + e). So, in order to take the derivative of
64
+ // any function, it is only necessary to replace the numeric "object" used in
65
+ // the function with one extended with infinitesimals. The class Jet, defined in
66
+ // this header, is one such example of this, where substitution is done with
67
+ // templates.
68
+ //
69
+ // To handle derivatives of functions taking multiple arguments, different
70
+ // infinitesimals are used, one for each variable to take the derivative of. For
71
+ // example, consider a scalar function of two scalar parameters x and y:
72
+ //
73
+ // f(x, y) = x^2 + x * y
74
+ //
75
+ // Following the technique above, to compute the derivatives df/dx and df/dy for
76
+ // f(1, 3) involves doing two evaluations of f, the first time replacing x with
77
+ // x + e, the second time replacing y with y + e.
78
+ //
79
+ // For df/dx:
80
+ //
81
+ // f(1 + e, y) = (1 + e)^2 + (1 + e) * 3
82
+ // = 1 + 2 * e + 3 + 3 * e
83
+ // = 4 + 5 * e
84
+ //
85
+ // --> df/dx = 5
86
+ //
87
+ // For df/dy:
88
+ //
89
+ // f(1, 3 + e) = 1^2 + 1 * (3 + e)
90
+ // = 1 + 3 + e
91
+ // = 4 + e
92
+ //
93
+ // --> df/dy = 1
94
+ //
95
+ // To take the gradient of f with the implementation of dual numbers ("jets") in
96
+ // this file, it is necessary to create a single jet type which has components
97
+ // for the derivative in x and y, and passing them to a templated version of f:
98
+ //
99
+ // template<typename T>
100
+ // T f(const T &x, const T &y) {
101
+ // return x * x + x * y;
102
+ // }
103
+ //
104
+ // // The "2" means there should be 2 dual number components.
105
+ // // It computes the partial derivative at x=10, y=20.
106
+ // Jet<double, 2> x(10, 0); // Pick the 0th dual number for x.
107
+ // Jet<double, 2> y(20, 1); // Pick the 1st dual number for y.
108
+ // Jet<double, 2> z = f(x, y);
109
+ //
110
+ // LOG(INFO) << "df/dx = " << z.v[0]
111
+ // << "df/dy = " << z.v[1];
112
+ //
113
+ // Most users should not use Jet objects directly; a wrapper around Jet objects,
114
+ // which makes computing the derivative, gradient, or jacobian of templated
115
+ // functors simple, is in autodiff.h. Even autodiff.h should not be used
116
+ // directly; instead autodiff_cost_function.h is typically the file of interest.
117
+ //
118
+ // For the more mathematically inclined, this file implements first-order
119
+ // "jets". A 1st order jet is an element of the ring
120
+ //
121
+ // T[N] = T[t_1, ..., t_N] / (t_1, ..., t_N)^2
122
+ //
123
+ // which essentially means that each jet consists of a "scalar" value 'a' from T
124
+ // and a 1st order perturbation vector 'v' of length N:
125
+ //
126
+ // x = a + \sum_i v[i] t_i
127
+ //
128
+ // A shorthand is to write an element as x = a + u, where u is the perturbation.
129
+ // Then, the main point about the arithmetic of jets is that the product of
130
+ // perturbations is zero:
131
+ //
132
+ // (a + u) * (b + v) = ab + av + bu + uv
133
+ // = ab + (av + bu) + 0
134
+ //
135
+ // which is what operator* implements below. Addition is simpler:
136
+ //
137
+ // (a + u) + (b + v) = (a + b) + (u + v).
138
+ //
139
+ // The only remaining question is how to evaluate the function of a jet, for
140
+ // which we use the chain rule:
141
+ //
142
+ // f(a + u) = f(a) + f'(a) u
143
+ //
144
+ // where f'(a) is the (scalar) derivative of f at a.
145
+ //
146
+ // By pushing these things through sufficiently and suitably templated
147
+ // functions, we can do automatic differentiation. Just be sure to turn on
148
+ // function inlining and common-subexpression elimination, or it will be very
149
+ // slow!
150
+ //
151
+ // WARNING: Most Ceres users should not directly include this file or know the
152
+ // details of how jets work. Instead the suggested method for automatic
153
+ // derivatives is to use autodiff_cost_function.h, which is a wrapper around
154
+ // both jets.h and autodiff.h to make taking derivatives of cost functions for
155
+ // use in Ceres easier.
156
+
157
+ #ifndef CERES_PUBLIC_JET_H_
158
+ #define CERES_PUBLIC_JET_H_
159
+
160
+ #include <cmath>
161
+ #include <complex>
162
+ #include <iosfwd>
163
+ #include <iostream> // NOLINT
164
+ #include <limits>
165
+ #include <numeric>
166
+ #include <string>
167
+ #include <type_traits>
168
+
169
+ #include "Eigen/Core"
170
+ #include "ceres/internal/jet_traits.h"
171
+ #include "ceres/internal/port.h"
172
+ #include "ceres/jet_fwd.h"
173
+
174
+ // Here we provide partial specializations of std::common_type for the Jet class
175
+ // to allow determining a Jet type with a common underlying arithmetic type.
176
+ // Such an arithmetic type can be either a scalar or an another Jet. An example
177
+ // for a common type, say, between a float and a Jet<double, N> is a Jet<double,
178
+ // N> (i.e., std::common_type_t<float, ceres::Jet<double, N>> and
179
+ // ceres::Jet<double, N> refer to the same type.)
180
+ //
181
+ // The partial specialization are also used for determining compatible types by
182
+ // means of SFINAE and thus allow such types to be expressed as operands of
183
+ // logical comparison operators. Missing (partial) specialization of
184
+ // std::common_type for a particular (custom) type will therefore disable the
185
+ // use of comparison operators defined by Ceres.
186
+ //
187
+ // Since these partial specializations are used as SFINAE constraints, they
188
+ // enable standard promotion rules between various scalar types and consequently
189
+ // their use in comparison against a Jet without providing implicit
190
+ // conversions from a scalar, such as an int, to a Jet (see the implementation
191
+ // of logical comparison operators below).
192
+
193
+ template <typename T, int N, typename U>
194
+ struct std::common_type<T, ceres::Jet<U, N>> {
195
+ using type = ceres::Jet<common_type_t<T, U>, N>;
196
+ };
197
+
198
+ template <typename T, int N, typename U>
199
+ struct std::common_type<ceres::Jet<T, N>, U> {
200
+ using type = ceres::Jet<common_type_t<T, U>, N>;
201
+ };
202
+
203
+ template <typename T, int N, typename U>
204
+ struct std::common_type<ceres::Jet<T, N>, ceres::Jet<U, N>> {
205
+ using type = ceres::Jet<common_type_t<T, U>, N>;
206
+ };
207
+
208
+ namespace ceres {
209
+
210
+ template <typename T, int N>
211
+ struct Jet {
212
+ enum { DIMENSION = N };
213
+ using Scalar = T;
214
+
215
+ // Default-construct "a" because otherwise this can lead to false errors about
216
+ // uninitialized uses when other classes relying on default constructed T
217
+ // (where T is a Jet<T, N>). This usually only happens in opt mode. Note that
218
+ // the C++ standard mandates that e.g. default constructed doubles are
219
+ // initialized to 0.0; see sections 8.5 of the C++03 standard.
220
+ Jet() : a() { v.setConstant(Scalar()); }
221
+
222
+ // Constructor from scalar: a + 0.
223
+ explicit Jet(const T& value) {
224
+ a = value;
225
+ v.setConstant(Scalar());
226
+ }
227
+
228
+ // Constructor from scalar plus variable: a + t_i.
229
+ Jet(const T& value, int k) {
230
+ a = value;
231
+ v.setConstant(Scalar());
232
+ v[k] = T(1.0);
233
+ }
234
+
235
+ // Constructor from scalar and vector part
236
+ // The use of Eigen::DenseBase allows Eigen expressions
237
+ // to be passed in without being fully evaluated until
238
+ // they are assigned to v
239
+ template <typename Derived>
240
+ EIGEN_STRONG_INLINE Jet(const T& a, const Eigen::DenseBase<Derived>& v)
241
+ : a(a), v(v) {}
242
+
243
+ // Compound operators
244
+ Jet<T, N>& operator+=(const Jet<T, N>& y) {
245
+ *this = *this + y;
246
+ return *this;
247
+ }
248
+
249
+ Jet<T, N>& operator-=(const Jet<T, N>& y) {
250
+ *this = *this - y;
251
+ return *this;
252
+ }
253
+
254
+ Jet<T, N>& operator*=(const Jet<T, N>& y) {
255
+ *this = *this * y;
256
+ return *this;
257
+ }
258
+
259
+ Jet<T, N>& operator/=(const Jet<T, N>& y) {
260
+ *this = *this / y;
261
+ return *this;
262
+ }
263
+
264
+ // Compound with scalar operators.
265
+ Jet<T, N>& operator+=(const T& s) {
266
+ *this = *this + s;
267
+ return *this;
268
+ }
269
+
270
+ Jet<T, N>& operator-=(const T& s) {
271
+ *this = *this - s;
272
+ return *this;
273
+ }
274
+
275
+ Jet<T, N>& operator*=(const T& s) {
276
+ *this = *this * s;
277
+ return *this;
278
+ }
279
+
280
+ Jet<T, N>& operator/=(const T& s) {
281
+ *this = *this / s;
282
+ return *this;
283
+ }
284
+
285
+ // The scalar part.
286
+ T a;
287
+
288
+ // The infinitesimal part.
289
+ Eigen::Matrix<T, N, 1> v;
290
+
291
+ // This struct needs to have an Eigen aligned operator new as it contains
292
+ // fixed-size Eigen types.
293
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW
294
+ };
295
+
296
+ // Unary +
297
+ template <typename T, int N>
298
+ inline Jet<T, N> const& operator+(const Jet<T, N>& f) {
299
+ return f;
300
+ }
301
+
302
+ // TODO(keir): Try adding __attribute__((always_inline)) to these functions to
303
+ // see if it causes a performance increase.
304
+
305
+ // Unary -
306
+ template <typename T, int N>
307
+ inline Jet<T, N> operator-(const Jet<T, N>& f) {
308
+ return Jet<T, N>(-f.a, -f.v);
309
+ }
310
+
311
+ // Binary +
312
+ template <typename T, int N>
313
+ inline Jet<T, N> operator+(const Jet<T, N>& f, const Jet<T, N>& g) {
314
+ return Jet<T, N>(f.a + g.a, f.v + g.v);
315
+ }
316
+
317
+ // Binary + with a scalar: x + s
318
+ template <typename T, int N>
319
+ inline Jet<T, N> operator+(const Jet<T, N>& f, T s) {
320
+ return Jet<T, N>(f.a + s, f.v);
321
+ }
322
+
323
+ // Binary + with a scalar: s + x
324
+ template <typename T, int N>
325
+ inline Jet<T, N> operator+(T s, const Jet<T, N>& f) {
326
+ return Jet<T, N>(f.a + s, f.v);
327
+ }
328
+
329
+ // Binary -
330
+ template <typename T, int N>
331
+ inline Jet<T, N> operator-(const Jet<T, N>& f, const Jet<T, N>& g) {
332
+ return Jet<T, N>(f.a - g.a, f.v - g.v);
333
+ }
334
+
335
+ // Binary - with a scalar: x - s
336
+ template <typename T, int N>
337
+ inline Jet<T, N> operator-(const Jet<T, N>& f, T s) {
338
+ return Jet<T, N>(f.a - s, f.v);
339
+ }
340
+
341
+ // Binary - with a scalar: s - x
342
+ template <typename T, int N>
343
+ inline Jet<T, N> operator-(T s, const Jet<T, N>& f) {
344
+ return Jet<T, N>(s - f.a, -f.v);
345
+ }
346
+
347
+ // Binary *
348
+ template <typename T, int N>
349
+ inline Jet<T, N> operator*(const Jet<T, N>& f, const Jet<T, N>& g) {
350
+ return Jet<T, N>(f.a * g.a, f.a * g.v + f.v * g.a);
351
+ }
352
+
353
+ // Binary * with a scalar: x * s
354
+ template <typename T, int N>
355
+ inline Jet<T, N> operator*(const Jet<T, N>& f, T s) {
356
+ return Jet<T, N>(f.a * s, f.v * s);
357
+ }
358
+
359
+ // Binary * with a scalar: s * x
360
+ template <typename T, int N>
361
+ inline Jet<T, N> operator*(T s, const Jet<T, N>& f) {
362
+ return Jet<T, N>(f.a * s, f.v * s);
363
+ }
364
+
365
+ // Binary /
366
+ template <typename T, int N>
367
+ inline Jet<T, N> operator/(const Jet<T, N>& f, const Jet<T, N>& g) {
368
+ // This uses:
369
+ //
370
+ // a + u (a + u)(b - v) (a + u)(b - v)
371
+ // ----- = -------------- = --------------
372
+ // b + v (b + v)(b - v) b^2
373
+ //
374
+ // which holds because v*v = 0.
375
+ const T g_a_inverse = T(1.0) / g.a;
376
+ const T f_a_by_g_a = f.a * g_a_inverse;
377
+ return Jet<T, N>(f_a_by_g_a, (f.v - f_a_by_g_a * g.v) * g_a_inverse);
378
+ }
379
+
380
+ // Binary / with a scalar: s / x
381
+ template <typename T, int N>
382
+ inline Jet<T, N> operator/(T s, const Jet<T, N>& g) {
383
+ const T minus_s_g_a_inverse2 = -s / (g.a * g.a);
384
+ return Jet<T, N>(s / g.a, g.v * minus_s_g_a_inverse2);
385
+ }
386
+
387
+ // Binary / with a scalar: x / s
388
+ template <typename T, int N>
389
+ inline Jet<T, N> operator/(const Jet<T, N>& f, T s) {
390
+ const T s_inverse = T(1.0) / s;
391
+ return Jet<T, N>(f.a * s_inverse, f.v * s_inverse);
392
+ }
393
+
394
+ // Binary comparison operators for both scalars and jets. At least one of the
395
+ // operands must be a Jet. Promotable scalars (e.g., int, float, double etc.)
396
+ // can appear on either side of the operator. std::common_type_t is used as an
397
+ // SFINAE constraint to selectively enable compatible operand types. This allows
398
+ // comparison, for instance, against int literals without implicit conversion.
399
+ // In case the Jet arithmetic type is a Jet itself, a recursive expansion of Jet
400
+ // value is performed.
401
+ #define CERES_DEFINE_JET_COMPARISON_OPERATOR(op) \
402
+ template <typename Lhs, \
403
+ typename Rhs, \
404
+ std::enable_if_t<PromotableJetOperands_v<Lhs, Rhs>>* = nullptr> \
405
+ constexpr bool operator op(const Lhs& f, const Rhs& g) noexcept( \
406
+ noexcept(internal::AsScalar(f) op internal::AsScalar(g))) { \
407
+ using internal::AsScalar; \
408
+ return AsScalar(f) op AsScalar(g); \
409
+ }
410
+ CERES_DEFINE_JET_COMPARISON_OPERATOR(<) // NOLINT
411
+ CERES_DEFINE_JET_COMPARISON_OPERATOR(<=) // NOLINT
412
+ CERES_DEFINE_JET_COMPARISON_OPERATOR(>) // NOLINT
413
+ CERES_DEFINE_JET_COMPARISON_OPERATOR(>=) // NOLINT
414
+ CERES_DEFINE_JET_COMPARISON_OPERATOR(==) // NOLINT
415
+ CERES_DEFINE_JET_COMPARISON_OPERATOR(!=) // NOLINT
416
+ #undef CERES_DEFINE_JET_COMPARISON_OPERATOR
417
+
418
+ // Pull some functions from namespace std.
419
+ //
420
+ // This is necessary because we want to use the same name (e.g. 'sqrt') for
421
+ // double-valued and Jet-valued functions, but we are not allowed to put
422
+ // Jet-valued functions inside namespace std.
423
+ using std::abs;
424
+ using std::acos;
425
+ using std::asin;
426
+ using std::atan;
427
+ using std::atan2;
428
+ using std::cbrt;
429
+ using std::ceil;
430
+ using std::copysign;
431
+ using std::cos;
432
+ using std::cosh;
433
+ using std::erf;
434
+ using std::erfc;
435
+ using std::exp;
436
+ using std::exp2;
437
+ using std::expm1;
438
+ using std::fdim;
439
+ using std::floor;
440
+ using std::fma;
441
+ using std::fmax;
442
+ using std::fmin;
443
+ using std::fpclassify;
444
+ using std::hypot;
445
+ using std::isfinite;
446
+ using std::isinf;
447
+ using std::isnan;
448
+ using std::isnormal;
449
+ using std::log;
450
+ using std::log10;
451
+ using std::log1p;
452
+ using std::log2;
453
+ using std::norm;
454
+ using std::pow;
455
+ using std::signbit;
456
+ using std::sin;
457
+ using std::sinh;
458
+ using std::sqrt;
459
+ using std::tan;
460
+ using std::tanh;
461
+
462
+ // MSVC (up to 1930) defines quiet comparison functions as template functions
463
+ // which causes compilation errors due to ambiguity in the template parameter
464
+ // type resolution for using declarations in the ceres namespace. Workaround the
465
+ // issue by defining specific overload and bypass MSVC standard library
466
+ // definitions.
467
+ #if defined(_MSC_VER)
468
+ inline bool isgreater(double lhs,
469
+ double rhs) noexcept(noexcept(std::isgreater(lhs, rhs))) {
470
+ return std::isgreater(lhs, rhs);
471
+ }
472
+ inline bool isless(double lhs,
473
+ double rhs) noexcept(noexcept(std::isless(lhs, rhs))) {
474
+ return std::isless(lhs, rhs);
475
+ }
476
+ inline bool islessequal(double lhs,
477
+ double rhs) noexcept(noexcept(std::islessequal(lhs,
478
+ rhs))) {
479
+ return std::islessequal(lhs, rhs);
480
+ }
481
+ inline bool isgreaterequal(double lhs, double rhs) noexcept(
482
+ noexcept(std::isgreaterequal(lhs, rhs))) {
483
+ return std::isgreaterequal(lhs, rhs);
484
+ }
485
+ inline bool islessgreater(double lhs, double rhs) noexcept(
486
+ noexcept(std::islessgreater(lhs, rhs))) {
487
+ return std::islessgreater(lhs, rhs);
488
+ }
489
+ inline bool isunordered(double lhs,
490
+ double rhs) noexcept(noexcept(std::isunordered(lhs,
491
+ rhs))) {
492
+ return std::isunordered(lhs, rhs);
493
+ }
494
+ #else
495
+ using std::isgreater;
496
+ using std::isgreaterequal;
497
+ using std::isless;
498
+ using std::islessequal;
499
+ using std::islessgreater;
500
+ using std::isunordered;
501
+ #endif
502
+
503
+ #ifdef CERES_HAS_CPP20
504
+ using std::lerp;
505
+ using std::midpoint;
506
+ #endif // defined(CERES_HAS_CPP20)
507
+
508
+ // Legacy names from pre-C++11 days.
509
+ // clang-format off
510
+ CERES_DEPRECATED_WITH_MSG("ceres::IsFinite will be removed in a future Ceres Solver release. Please use ceres::isfinite.")
511
+ inline bool IsFinite(double x) { return std::isfinite(x); }
512
+ CERES_DEPRECATED_WITH_MSG("ceres::IsInfinite will be removed in a future Ceres Solver release. Please use ceres::isinf.")
513
+ inline bool IsInfinite(double x) { return std::isinf(x); }
514
+ CERES_DEPRECATED_WITH_MSG("ceres::IsNaN will be removed in a future Ceres Solver release. Please use ceres::isnan.")
515
+ inline bool IsNaN(double x) { return std::isnan(x); }
516
+ CERES_DEPRECATED_WITH_MSG("ceres::IsNormal will be removed in a future Ceres Solver release. Please use ceres::isnormal.")
517
+ inline bool IsNormal(double x) { return std::isnormal(x); }
518
+ // clang-format on
519
+
520
+ // In general, f(a + h) ~= f(a) + f'(a) h, via the chain rule.
521
+
522
+ // abs(x + h) ~= abs(x) + sgn(x)h
523
+ template <typename T, int N>
524
+ inline Jet<T, N> abs(const Jet<T, N>& f) {
525
+ return Jet<T, N>(abs(f.a), copysign(T(1), f.a) * f.v);
526
+ }
527
+
528
+ // copysign(a, b) composes a float with the magnitude of a and the sign of b.
529
+ // Therefore, the function can be formally defined as
530
+ //
531
+ // copysign(a, b) = sgn(b)|a|
532
+ //
533
+ // where
534
+ //
535
+ // d/dx |x| = sgn(x)
536
+ // d/dx sgn(x) = 2δ(x)
537
+ //
538
+ // sgn(x) being the signum function. Differentiating copysign(a, b) with respect
539
+ // to a and b gives:
540
+ //
541
+ // d/da sgn(b)|a| = sgn(a) sgn(b)
542
+ // d/db sgn(b)|a| = 2|a|δ(b)
543
+ //
544
+ // with the dual representation given by
545
+ //
546
+ // copysign(a + da, b + db) ~= sgn(b)|a| + (sgn(a)sgn(b) da + 2|a|δ(b) db)
547
+ //
548
+ // where δ(b) is the Dirac delta function.
549
+ template <typename T, int N>
550
+ inline Jet<T, N> copysign(const Jet<T, N>& f, const Jet<T, N> g) {
551
+ // The Dirac delta function δ(b) is undefined at b=0 (here it's
552
+ // infinite) and 0 everywhere else.
553
+ T d = fpclassify(g) == FP_ZERO ? std::numeric_limits<T>::infinity() : T(0);
554
+ T sa = copysign(T(1), f.a); // sgn(a)
555
+ T sb = copysign(T(1), g.a); // sgn(b)
556
+ // The second part of the infinitesimal is 2|a|δ(b) which is either infinity
557
+ // or 0 unless a or any of the values of the b infinitesimal are 0. In the
558
+ // latter case, the corresponding values become NaNs (multiplying 0 by
559
+ // infinity gives NaN). We drop the constant factor 2 since it does not change
560
+ // the result (its values will still be either 0, infinity or NaN).
561
+ return Jet<T, N>(copysign(f.a, g.a), sa * sb * f.v + abs(f.a) * d * g.v);
562
+ }
563
+
564
+ // log(a + h) ~= log(a) + h / a
565
+ template <typename T, int N>
566
+ inline Jet<T, N> log(const Jet<T, N>& f) {
567
+ const T a_inverse = T(1.0) / f.a;
568
+ return Jet<T, N>(log(f.a), f.v * a_inverse);
569
+ }
570
+
571
+ // log10(a + h) ~= log10(a) + h / (a log(10))
572
+ template <typename T, int N>
573
+ inline Jet<T, N> log10(const Jet<T, N>& f) {
574
+ // Most compilers will expand log(10) to a constant.
575
+ const T a_inverse = T(1.0) / (f.a * log(T(10.0)));
576
+ return Jet<T, N>(log10(f.a), f.v * a_inverse);
577
+ }
578
+
579
+ // log1p(a + h) ~= log1p(a) + h / (1 + a)
580
+ template <typename T, int N>
581
+ inline Jet<T, N> log1p(const Jet<T, N>& f) {
582
+ const T a_inverse = T(1.0) / (T(1.0) + f.a);
583
+ return Jet<T, N>(log1p(f.a), f.v * a_inverse);
584
+ }
585
+
586
+ // exp(a + h) ~= exp(a) + exp(a) h
587
+ template <typename T, int N>
588
+ inline Jet<T, N> exp(const Jet<T, N>& f) {
589
+ const T tmp = exp(f.a);
590
+ return Jet<T, N>(tmp, tmp * f.v);
591
+ }
592
+
593
+ // expm1(a + h) ~= expm1(a) + exp(a) h
594
+ template <typename T, int N>
595
+ inline Jet<T, N> expm1(const Jet<T, N>& f) {
596
+ const T tmp = expm1(f.a);
597
+ const T expa = tmp + T(1.0); // exp(a) = expm1(a) + 1
598
+ return Jet<T, N>(tmp, expa * f.v);
599
+ }
600
+
601
+ // sqrt(a + h) ~= sqrt(a) + h / (2 sqrt(a))
602
+ template <typename T, int N>
603
+ inline Jet<T, N> sqrt(const Jet<T, N>& f) {
604
+ const T tmp = sqrt(f.a);
605
+ const T two_a_inverse = T(1.0) / (T(2.0) * tmp);
606
+ return Jet<T, N>(tmp, f.v * two_a_inverse);
607
+ }
608
+
609
+ // cos(a + h) ~= cos(a) - sin(a) h
610
+ template <typename T, int N>
611
+ inline Jet<T, N> cos(const Jet<T, N>& f) {
612
+ return Jet<T, N>(cos(f.a), -sin(f.a) * f.v);
613
+ }
614
+
615
+ // acos(a + h) ~= acos(a) - 1 / sqrt(1 - a^2) h
616
+ template <typename T, int N>
617
+ inline Jet<T, N> acos(const Jet<T, N>& f) {
618
+ const T tmp = -T(1.0) / sqrt(T(1.0) - f.a * f.a);
619
+ return Jet<T, N>(acos(f.a), tmp * f.v);
620
+ }
621
+
622
+ // sin(a + h) ~= sin(a) + cos(a) h
623
+ template <typename T, int N>
624
+ inline Jet<T, N> sin(const Jet<T, N>& f) {
625
+ return Jet<T, N>(sin(f.a), cos(f.a) * f.v);
626
+ }
627
+
628
+ // asin(a + h) ~= asin(a) + 1 / sqrt(1 - a^2) h
629
+ template <typename T, int N>
630
+ inline Jet<T, N> asin(const Jet<T, N>& f) {
631
+ const T tmp = T(1.0) / sqrt(T(1.0) - f.a * f.a);
632
+ return Jet<T, N>(asin(f.a), tmp * f.v);
633
+ }
634
+
635
+ // tan(a + h) ~= tan(a) + (1 + tan(a)^2) h
636
+ template <typename T, int N>
637
+ inline Jet<T, N> tan(const Jet<T, N>& f) {
638
+ const T tan_a = tan(f.a);
639
+ const T tmp = T(1.0) + tan_a * tan_a;
640
+ return Jet<T, N>(tan_a, tmp * f.v);
641
+ }
642
+
643
+ // atan(a + h) ~= atan(a) + 1 / (1 + a^2) h
644
+ template <typename T, int N>
645
+ inline Jet<T, N> atan(const Jet<T, N>& f) {
646
+ const T tmp = T(1.0) / (T(1.0) + f.a * f.a);
647
+ return Jet<T, N>(atan(f.a), tmp * f.v);
648
+ }
649
+
650
+ // sinh(a + h) ~= sinh(a) + cosh(a) h
651
+ template <typename T, int N>
652
+ inline Jet<T, N> sinh(const Jet<T, N>& f) {
653
+ return Jet<T, N>(sinh(f.a), cosh(f.a) * f.v);
654
+ }
655
+
656
+ // cosh(a + h) ~= cosh(a) + sinh(a) h
657
+ template <typename T, int N>
658
+ inline Jet<T, N> cosh(const Jet<T, N>& f) {
659
+ return Jet<T, N>(cosh(f.a), sinh(f.a) * f.v);
660
+ }
661
+
662
+ // tanh(a + h) ~= tanh(a) + (1 - tanh(a)^2) h
663
+ template <typename T, int N>
664
+ inline Jet<T, N> tanh(const Jet<T, N>& f) {
665
+ const T tanh_a = tanh(f.a);
666
+ const T tmp = T(1.0) - tanh_a * tanh_a;
667
+ return Jet<T, N>(tanh_a, tmp * f.v);
668
+ }
669
+
670
+ // The floor function should be used with extreme care as this operation will
671
+ // result in a zero derivative which provides no information to the solver.
672
+ //
673
+ // floor(a + h) ~= floor(a) + 0
674
+ template <typename T, int N>
675
+ inline Jet<T, N> floor(const Jet<T, N>& f) {
676
+ return Jet<T, N>(floor(f.a));
677
+ }
678
+
679
+ // The ceil function should be used with extreme care as this operation will
680
+ // result in a zero derivative which provides no information to the solver.
681
+ //
682
+ // ceil(a + h) ~= ceil(a) + 0
683
+ template <typename T, int N>
684
+ inline Jet<T, N> ceil(const Jet<T, N>& f) {
685
+ return Jet<T, N>(ceil(f.a));
686
+ }
687
+
688
+ // Some new additions to C++11:
689
+
690
+ // cbrt(a + h) ~= cbrt(a) + h / (3 a ^ (2/3))
691
+ template <typename T, int N>
692
+ inline Jet<T, N> cbrt(const Jet<T, N>& f) {
693
+ const T derivative = T(1.0) / (T(3.0) * cbrt(f.a * f.a));
694
+ return Jet<T, N>(cbrt(f.a), f.v * derivative);
695
+ }
696
+
697
+ // exp2(x + h) = 2^(x+h) ~= 2^x + h*2^x*log(2)
698
+ template <typename T, int N>
699
+ inline Jet<T, N> exp2(const Jet<T, N>& f) {
700
+ const T tmp = exp2(f.a);
701
+ const T derivative = tmp * log(T(2));
702
+ return Jet<T, N>(tmp, f.v * derivative);
703
+ }
704
+
705
+ // log2(x + h) ~= log2(x) + h / (x * log(2))
706
+ template <typename T, int N>
707
+ inline Jet<T, N> log2(const Jet<T, N>& f) {
708
+ const T derivative = T(1.0) / (f.a * log(T(2)));
709
+ return Jet<T, N>(log2(f.a), f.v * derivative);
710
+ }
711
+
712
+ // Like sqrt(x^2 + y^2),
713
+ // but acts to prevent underflow/overflow for small/large x/y.
714
+ // Note that the function is non-smooth at x=y=0,
715
+ // so the derivative is undefined there.
716
+ template <typename T, int N>
717
+ inline Jet<T, N> hypot(const Jet<T, N>& x, const Jet<T, N>& y) {
718
+ // d/da sqrt(a) = 0.5 / sqrt(a)
719
+ // d/dx x^2 + y^2 = 2x
720
+ // So by the chain rule:
721
+ // d/dx sqrt(x^2 + y^2) = 0.5 / sqrt(x^2 + y^2) * 2x = x / sqrt(x^2 + y^2)
722
+ // d/dy sqrt(x^2 + y^2) = y / sqrt(x^2 + y^2)
723
+ const T tmp = hypot(x.a, y.a);
724
+ return Jet<T, N>(tmp, x.a / tmp * x.v + y.a / tmp * y.v);
725
+ }
726
+
727
+ #ifdef CERES_HAS_CPP17
728
+ // Like sqrt(x^2 + y^2 + z^2),
729
+ // but acts to prevent underflow/overflow for small/large x/y/z.
730
+ // Note that the function is non-smooth at x=y=z=0,
731
+ // so the derivative is undefined there.
732
+ template <typename T, int N>
733
+ inline Jet<T, N> hypot(const Jet<T, N>& x,
734
+ const Jet<T, N>& y,
735
+ const Jet<T, N>& z) {
736
+ // d/da sqrt(a) = 0.5 / sqrt(a)
737
+ // d/dx x^2 + y^2 + z^2 = 2x
738
+ // So by the chain rule:
739
+ // d/dx sqrt(x^2 + y^2 + z^2)
740
+ // = 0.5 / sqrt(x^2 + y^2 + z^2) * 2x
741
+ // = x / sqrt(x^2 + y^2 + z^2)
742
+ // d/dy sqrt(x^2 + y^2 + z^2) = y / sqrt(x^2 + y^2 + z^2)
743
+ // d/dz sqrt(x^2 + y^2 + z^2) = z / sqrt(x^2 + y^2 + z^2)
744
+ const T tmp = hypot(x.a, y.a, z.a);
745
+ return Jet<T, N>(tmp, x.a / tmp * x.v + y.a / tmp * y.v + z.a / tmp * z.v);
746
+ }
747
+ #endif // defined(CERES_HAS_CPP17)
748
+
749
+ // Like x * y + z but rounded only once.
750
+ template <typename T, int N>
751
+ inline Jet<T, N> fma(const Jet<T, N>& x,
752
+ const Jet<T, N>& y,
753
+ const Jet<T, N>& z) {
754
+ // d/dx fma(x, y, z) = y
755
+ // d/dy fma(x, y, z) = x
756
+ // d/dz fma(x, y, z) = 1
757
+ return Jet<T, N>(fma(x.a, y.a, z.a), y.a * x.v + x.a * y.v + z.v);
758
+ }
759
+
760
+ // Returns the larger of the two arguments. NaNs are treated as missing data.
761
+ //
762
+ // NOTE: This function is NOT subject to any of the error conditions specified
763
+ // in `math_errhandling`.
764
+ template <typename Lhs,
765
+ typename Rhs,
766
+ std::enable_if_t<CompatibleJetOperands_v<Lhs, Rhs>>* = nullptr>
767
+ inline decltype(auto) fmax(const Lhs& f, const Rhs& g) {
768
+ using J = std::common_type_t<Lhs, Rhs>;
769
+ return (isnan(g) || isgreater(f, g)) ? J{f} : J{g};
770
+ }
771
+
772
+ // Returns the smaller of the two arguments. NaNs are treated as missing data.
773
+ //
774
+ // NOTE: This function is NOT subject to any of the error conditions specified
775
+ // in `math_errhandling`.
776
+ template <typename Lhs,
777
+ typename Rhs,
778
+ std::enable_if_t<CompatibleJetOperands_v<Lhs, Rhs>>* = nullptr>
779
+ inline decltype(auto) fmin(const Lhs& f, const Rhs& g) {
780
+ using J = std::common_type_t<Lhs, Rhs>;
781
+ return (isnan(f) || isless(g, f)) ? J{g} : J{f};
782
+ }
783
+
784
+ // Returns the positive difference (f - g) of two arguments and zero if f <= g.
785
+ // If at least one argument is NaN, a NaN is return.
786
+ //
787
+ // NOTE At least one of the argument types must be a Jet, the other one can be a
788
+ // scalar. In case both arguments are Jets, their dimensionality must match.
789
+ template <typename Lhs,
790
+ typename Rhs,
791
+ std::enable_if_t<CompatibleJetOperands_v<Lhs, Rhs>>* = nullptr>
792
+ inline decltype(auto) fdim(const Lhs& f, const Rhs& g) {
793
+ using J = std::common_type_t<Lhs, Rhs>;
794
+ if (isnan(f) || isnan(g)) {
795
+ return std::numeric_limits<J>::quiet_NaN();
796
+ }
797
+ return isgreater(f, g) ? J{f - g} : J{};
798
+ }
799
+
800
+ // erf is defined as an integral that cannot be expressed analytically
801
+ // however, the derivative is trivial to compute
802
+ // erf(x + h) = erf(x) + h * 2*exp(-x^2)/sqrt(pi)
803
+ template <typename T, int N>
804
+ inline Jet<T, N> erf(const Jet<T, N>& x) {
805
+ // We evaluate the constant as follows:
806
+ // 2 / sqrt(pi) = 1 / sqrt(atan(1.))
807
+ // On POSIX sytems it is defined as M_2_SQRTPI, but this is not
808
+ // portable and the type may not be T. The above expression
809
+ // evaluates to full precision with IEEE arithmetic and, since it's
810
+ // constant, the compiler can generate exactly the same code. gcc
811
+ // does so even at -O0.
812
+ return Jet<T, N>(erf(x.a), x.v * exp(-x.a * x.a) * (T(1) / sqrt(atan(T(1)))));
813
+ }
814
+
815
+ // erfc(x) = 1-erf(x)
816
+ // erfc(x + h) = erfc(x) + h * (-2*exp(-x^2)/sqrt(pi))
817
+ template <typename T, int N>
818
+ inline Jet<T, N> erfc(const Jet<T, N>& x) {
819
+ // See in erf() above for the evaluation of the constant in the derivative.
820
+ return Jet<T, N>(erfc(x.a),
821
+ -x.v * exp(-x.a * x.a) * (T(1) / sqrt(atan(T(1)))));
822
+ }
823
+
824
+ // Bessel functions of the first kind with integer order equal to 0, 1, n.
825
+ //
826
+ // Microsoft has deprecated the j[0,1,n]() POSIX Bessel functions in favour of
827
+ // _j[0,1,n](). Where available on MSVC, use _j[0,1,n]() to avoid deprecated
828
+ // function errors in client code (the specific warning is suppressed when
829
+ // Ceres itself is built).
830
+ inline double BesselJ0(double x) {
831
+ #if defined(CERES_MSVC_USE_UNDERSCORE_PREFIXED_BESSEL_FUNCTIONS)
832
+ return _j0(x);
833
+ #else
834
+ return j0(x);
835
+ #endif
836
+ }
837
+ inline double BesselJ1(double x) {
838
+ #if defined(CERES_MSVC_USE_UNDERSCORE_PREFIXED_BESSEL_FUNCTIONS)
839
+ return _j1(x);
840
+ #else
841
+ return j1(x);
842
+ #endif
843
+ }
844
+ inline double BesselJn(int n, double x) {
845
+ #if defined(CERES_MSVC_USE_UNDERSCORE_PREFIXED_BESSEL_FUNCTIONS)
846
+ return _jn(n, x);
847
+ #else
848
+ return jn(n, x);
849
+ #endif
850
+ }
851
+
852
+ // For the formulae of the derivatives of the Bessel functions see the book:
853
+ // Olver, Lozier, Boisvert, Clark, NIST Handbook of Mathematical Functions,
854
+ // Cambridge University Press 2010.
855
+ //
856
+ // Formulae are also available at http://dlmf.nist.gov
857
+
858
+ // See formula http://dlmf.nist.gov/10.6#E3
859
+ // j0(a + h) ~= j0(a) - j1(a) h
860
+ template <typename T, int N>
861
+ inline Jet<T, N> BesselJ0(const Jet<T, N>& f) {
862
+ return Jet<T, N>(BesselJ0(f.a), -BesselJ1(f.a) * f.v);
863
+ }
864
+
865
+ // See formula http://dlmf.nist.gov/10.6#E1
866
+ // j1(a + h) ~= j1(a) + 0.5 ( j0(a) - j2(a) ) h
867
+ template <typename T, int N>
868
+ inline Jet<T, N> BesselJ1(const Jet<T, N>& f) {
869
+ return Jet<T, N>(BesselJ1(f.a),
870
+ T(0.5) * (BesselJ0(f.a) - BesselJn(2, f.a)) * f.v);
871
+ }
872
+
873
+ // See formula http://dlmf.nist.gov/10.6#E1
874
+ // j_n(a + h) ~= j_n(a) + 0.5 ( j_{n-1}(a) - j_{n+1}(a) ) h
875
+ template <typename T, int N>
876
+ inline Jet<T, N> BesselJn(int n, const Jet<T, N>& f) {
877
+ return Jet<T, N>(
878
+ BesselJn(n, f.a),
879
+ T(0.5) * (BesselJn(n - 1, f.a) - BesselJn(n + 1, f.a)) * f.v);
880
+ }
881
+
882
+ // Classification and comparison functionality referencing only the scalar part
883
+ // of a Jet. To classify the derivatives (e.g., for sanity checks), the dual
884
+ // part should be referenced explicitly. For instance, to check whether the
885
+ // derivatives of a Jet 'f' are reasonable, one can use
886
+ //
887
+ // isfinite(f.v.array()).all()
888
+ // !isnan(f.v.array()).any()
889
+ //
890
+ // etc., depending on the desired semantics.
891
+ //
892
+ // NOTE: Floating-point classification and comparison functions and operators
893
+ // should be used with care as no derivatives can be propagated by such
894
+ // functions directly but only by expressions resulting from corresponding
895
+ // conditional statements. At the same time, conditional statements can possibly
896
+ // introduce a discontinuity in the cost function making it impossible to
897
+ // evaluate its derivative and thus the optimization problem intractable.
898
+
899
+ // Determines whether the scalar part of the Jet is finite.
900
+ template <typename T, int N>
901
+ inline bool isfinite(const Jet<T, N>& f) {
902
+ return isfinite(f.a);
903
+ }
904
+
905
+ // Determines whether the scalar part of the Jet is infinite.
906
+ template <typename T, int N>
907
+ inline bool isinf(const Jet<T, N>& f) {
908
+ return isinf(f.a);
909
+ }
910
+
911
+ // Determines whether the scalar part of the Jet is NaN.
912
+ template <typename T, int N>
913
+ inline bool isnan(const Jet<T, N>& f) {
914
+ return isnan(f.a);
915
+ }
916
+
917
+ // Determines whether the scalar part of the Jet is neither zero, subnormal,
918
+ // infinite, nor NaN.
919
+ template <typename T, int N>
920
+ inline bool isnormal(const Jet<T, N>& f) {
921
+ return isnormal(f.a);
922
+ }
923
+
924
+ // Determines whether the scalar part of the Jet f is less than the scalar
925
+ // part of g.
926
+ //
927
+ // NOTE: This function does NOT set any floating-point exceptions.
928
+ template <typename Lhs,
929
+ typename Rhs,
930
+ std::enable_if_t<CompatibleJetOperands_v<Lhs, Rhs>>* = nullptr>
931
+ inline bool isless(const Lhs& f, const Rhs& g) {
932
+ using internal::AsScalar;
933
+ return isless(AsScalar(f), AsScalar(g));
934
+ }
935
+
936
+ // Determines whether the scalar part of the Jet f is greater than the scalar
937
+ // part of g.
938
+ //
939
+ // NOTE: This function does NOT set any floating-point exceptions.
940
+ template <typename Lhs,
941
+ typename Rhs,
942
+ std::enable_if_t<CompatibleJetOperands_v<Lhs, Rhs>>* = nullptr>
943
+ inline bool isgreater(const Lhs& f, const Rhs& g) {
944
+ using internal::AsScalar;
945
+ return isgreater(AsScalar(f), AsScalar(g));
946
+ }
947
+
948
+ // Determines whether the scalar part of the Jet f is less than or equal to the
949
+ // scalar part of g.
950
+ //
951
+ // NOTE: This function does NOT set any floating-point exceptions.
952
+ template <typename Lhs,
953
+ typename Rhs,
954
+ std::enable_if_t<CompatibleJetOperands_v<Lhs, Rhs>>* = nullptr>
955
+ inline bool islessequal(const Lhs& f, const Rhs& g) {
956
+ using internal::AsScalar;
957
+ return islessequal(AsScalar(f), AsScalar(g));
958
+ }
959
+
960
+ // Determines whether the scalar part of the Jet f is less than or greater than
961
+ // (f < g || f > g) the scalar part of g.
962
+ //
963
+ // NOTE: This function does NOT set any floating-point exceptions.
964
+ template <typename Lhs,
965
+ typename Rhs,
966
+ std::enable_if_t<CompatibleJetOperands_v<Lhs, Rhs>>* = nullptr>
967
+ inline bool islessgreater(const Lhs& f, const Rhs& g) {
968
+ using internal::AsScalar;
969
+ return islessgreater(AsScalar(f), AsScalar(g));
970
+ }
971
+
972
+ // Determines whether the scalar part of the Jet f is greater than or equal to
973
+ // the scalar part of g.
974
+ //
975
+ // NOTE: This function does NOT set any floating-point exceptions.
976
+ template <typename Lhs,
977
+ typename Rhs,
978
+ std::enable_if_t<CompatibleJetOperands_v<Lhs, Rhs>>* = nullptr>
979
+ inline bool isgreaterequal(const Lhs& f, const Rhs& g) {
980
+ using internal::AsScalar;
981
+ return isgreaterequal(AsScalar(f), AsScalar(g));
982
+ }
983
+
984
+ // Determines if either of the scalar parts of the arguments are NaN and
985
+ // thus cannot be ordered with respect to each other.
986
+ template <typename Lhs,
987
+ typename Rhs,
988
+ std::enable_if_t<CompatibleJetOperands_v<Lhs, Rhs>>* = nullptr>
989
+ inline bool isunordered(const Lhs& f, const Rhs& g) {
990
+ using internal::AsScalar;
991
+ return isunordered(AsScalar(f), AsScalar(g));
992
+ }
993
+
994
+ // Categorize scalar part as zero, subnormal, normal, infinite, NaN, or
995
+ // implementation-defined.
996
+ template <typename T, int N>
997
+ inline int fpclassify(const Jet<T, N>& f) {
998
+ return fpclassify(f.a);
999
+ }
1000
+
1001
+ // Determines whether the scalar part of the argument is negative.
1002
+ template <typename T, int N>
1003
+ inline bool signbit(const Jet<T, N>& f) {
1004
+ return signbit(f.a);
1005
+ }
1006
+
1007
+ // Legacy functions from the pre-C++11 days.
1008
+ template <typename T, int N>
1009
+ CERES_DEPRECATED_WITH_MSG(
1010
+ "ceres::IsFinite will be removed in a future Ceres Solver release. Please "
1011
+ "use ceres::isfinite.")
1012
+ inline bool IsFinite(const Jet<T, N>& f) {
1013
+ return isfinite(f);
1014
+ }
1015
+
1016
+ template <typename T, int N>
1017
+ CERES_DEPRECATED_WITH_MSG(
1018
+ "ceres::IsNaN will be removed in a future Ceres Solver release. Please use "
1019
+ "ceres::isnan.")
1020
+ inline bool IsNaN(const Jet<T, N>& f) {
1021
+ return isnan(f);
1022
+ }
1023
+
1024
+ template <typename T, int N>
1025
+ CERES_DEPRECATED_WITH_MSG(
1026
+ "ceres::IsNormal will be removed in a future Ceres Solver release. Please "
1027
+ "use ceres::isnormal.")
1028
+ inline bool IsNormal(const Jet<T, N>& f) {
1029
+ return isnormal(f);
1030
+ }
1031
+
1032
+ // The jet is infinite if any part of the jet is infinite.
1033
+ template <typename T, int N>
1034
+ CERES_DEPRECATED_WITH_MSG(
1035
+ "ceres::IsInfinite will be removed in a future Ceres Solver release. "
1036
+ "Please use ceres::isinf.")
1037
+ inline bool IsInfinite(const Jet<T, N>& f) {
1038
+ return isinf(f);
1039
+ }
1040
+
1041
+ #ifdef CERES_HAS_CPP20
1042
+ // Computes the linear interpolation a + t(b - a) between a and b at the value
1043
+ // t. For arguments outside of the range 0 <= t <= 1, the values are
1044
+ // extrapolated.
1045
+ //
1046
+ // Differentiating lerp(a, b, t) with respect to a, b, and t gives:
1047
+ //
1048
+ // d/da lerp(a, b, t) = 1 - t
1049
+ // d/db lerp(a, b, t) = t
1050
+ // d/dt lerp(a, b, t) = b - a
1051
+ //
1052
+ // with the dual representation given by
1053
+ //
1054
+ // lerp(a + da, b + db, t + dt)
1055
+ // ~= lerp(a, b, t) + (1 - t) da + t db + (b - a) dt .
1056
+ template <typename T, int N>
1057
+ inline Jet<T, N> lerp(const Jet<T, N>& a,
1058
+ const Jet<T, N>& b,
1059
+ const Jet<T, N>& t) {
1060
+ return Jet<T, N>{lerp(a.a, b.a, t.a),
1061
+ (T(1) - t.a) * a.v + t.a * b.v + (b.a - a.a) * t.v};
1062
+ }
1063
+
1064
+ // Computes the midpoint a + (b - a) / 2.
1065
+ //
1066
+ // Differentiating midpoint(a, b) with respect to a and b gives:
1067
+ //
1068
+ // d/da midpoint(a, b) = 1/2
1069
+ // d/db midpoint(a, b) = 1/2
1070
+ //
1071
+ // with the dual representation given by
1072
+ //
1073
+ // midpoint(a + da, b + db) ~= midpoint(a, b) + (da + db) / 2 .
1074
+ template <typename T, int N>
1075
+ inline Jet<T, N> midpoint(const Jet<T, N>& a, const Jet<T, N>& b) {
1076
+ Jet<T, N> result{midpoint(a.a, b.a)};
1077
+ // To avoid overflow in the differential, compute
1078
+ // (da + db) / 2 using midpoint.
1079
+ for (int i = 0; i < N; ++i) {
1080
+ result.v[i] = midpoint(a.v[i], b.v[i]);
1081
+ }
1082
+ return result;
1083
+ }
1084
+ #endif // defined(CERES_HAS_CPP20)
1085
+
1086
+ // atan2(b + db, a + da) ~= atan2(b, a) + (- b da + a db) / (a^2 + b^2)
1087
+ //
1088
+ // In words: the rate of change of theta is 1/r times the rate of
1089
+ // change of (x, y) in the positive angular direction.
1090
+ template <typename T, int N>
1091
+ inline Jet<T, N> atan2(const Jet<T, N>& g, const Jet<T, N>& f) {
1092
+ // Note order of arguments:
1093
+ //
1094
+ // f = a + da
1095
+ // g = b + db
1096
+
1097
+ T const tmp = T(1.0) / (f.a * f.a + g.a * g.a);
1098
+ return Jet<T, N>(atan2(g.a, f.a), tmp * (-g.a * f.v + f.a * g.v));
1099
+ }
1100
+
1101
+ // Computes the square x^2 of a real number x (not the Euclidean L^2 norm as
1102
+ // the name might suggest).
1103
+ //
1104
+ // NOTE: While std::norm is primarily intended for computing the squared
1105
+ // magnitude of a std::complex<> number, the current Jet implementation does not
1106
+ // support mixing a scalar T in its real part and std::complex<T> and in the
1107
+ // infinitesimal. Mixed Jet support is necessary for the type decay from
1108
+ // std::complex<T> to T (the squared magnitude of a complex number is always
1109
+ // real) performed by std::norm.
1110
+ //
1111
+ // norm(x + h) ~= norm(x) + 2x h
1112
+ template <typename T, int N>
1113
+ inline Jet<T, N> norm(const Jet<T, N>& f) {
1114
+ return Jet<T, N>(norm(f.a), T(2) * f.a * f.v);
1115
+ }
1116
+
1117
+ // pow -- base is a differentiable function, exponent is a constant.
1118
+ // (a+da)^p ~= a^p + p*a^(p-1) da
1119
+ template <typename T, int N>
1120
+ inline Jet<T, N> pow(const Jet<T, N>& f, double g) {
1121
+ T const tmp = g * pow(f.a, g - T(1.0));
1122
+ return Jet<T, N>(pow(f.a, g), tmp * f.v);
1123
+ }
1124
+
1125
+ // pow -- base is a constant, exponent is a differentiable function.
1126
+ // We have various special cases, see the comment for pow(Jet, Jet) for
1127
+ // analysis:
1128
+ //
1129
+ // 1. For f > 0 we have: (f)^(g + dg) ~= f^g + f^g log(f) dg
1130
+ //
1131
+ // 2. For f == 0 and g > 0 we have: (f)^(g + dg) ~= f^g
1132
+ //
1133
+ // 3. For f < 0 and integer g we have: (f)^(g + dg) ~= f^g but if dg
1134
+ // != 0, the derivatives are not defined and we return NaN.
1135
+
1136
+ template <typename T, int N>
1137
+ inline Jet<T, N> pow(T f, const Jet<T, N>& g) {
1138
+ Jet<T, N> result;
1139
+
1140
+ if (fpclassify(f) == FP_ZERO && g > 0) {
1141
+ // Handle case 2.
1142
+ result = Jet<T, N>(T(0.0));
1143
+ } else {
1144
+ if (f < 0 && g == floor(g.a)) { // Handle case 3.
1145
+ result = Jet<T, N>(pow(f, g.a));
1146
+ for (int i = 0; i < N; i++) {
1147
+ if (fpclassify(g.v[i]) != FP_ZERO) {
1148
+ // Return a NaN when g.v != 0.
1149
+ result.v[i] = std::numeric_limits<T>::quiet_NaN();
1150
+ }
1151
+ }
1152
+ } else {
1153
+ // Handle case 1.
1154
+ T const tmp = pow(f, g.a);
1155
+ result = Jet<T, N>(tmp, log(f) * tmp * g.v);
1156
+ }
1157
+ }
1158
+
1159
+ return result;
1160
+ }
1161
+
1162
+ // pow -- both base and exponent are differentiable functions. This has a
1163
+ // variety of special cases that require careful handling.
1164
+ //
1165
+ // 1. For f > 0:
1166
+ // (f + df)^(g + dg) ~= f^g + f^(g - 1) * (g * df + f * log(f) * dg)
1167
+ // The numerical evaluation of f * log(f) for f > 0 is well behaved, even for
1168
+ // extremely small values (e.g. 1e-99).
1169
+ //
1170
+ // 2. For f == 0 and g > 1: (f + df)^(g + dg) ~= 0
1171
+ // This cases is needed because log(0) can not be evaluated in the f > 0
1172
+ // expression. However the function f*log(f) is well behaved around f == 0
1173
+ // and its limit as f-->0 is zero.
1174
+ //
1175
+ // 3. For f == 0 and g == 1: (f + df)^(g + dg) ~= 0 + df
1176
+ //
1177
+ // 4. For f == 0 and 0 < g < 1: The value is finite but the derivatives are not.
1178
+ //
1179
+ // 5. For f == 0 and g < 0: The value and derivatives of f^g are not finite.
1180
+ //
1181
+ // 6. For f == 0 and g == 0: The C standard incorrectly defines 0^0 to be 1
1182
+ // "because there are applications that can exploit this definition". We
1183
+ // (arbitrarily) decree that derivatives here will be nonfinite, since that
1184
+ // is consistent with the behavior for f == 0, g < 0 and 0 < g < 1.
1185
+ // Practically any definition could have been justified because mathematical
1186
+ // consistency has been lost at this point.
1187
+ //
1188
+ // 7. For f < 0, g integer, dg == 0: (f + df)^(g + dg) ~= f^g + g * f^(g - 1) df
1189
+ // This is equivalent to the case where f is a differentiable function and g
1190
+ // is a constant (to first order).
1191
+ //
1192
+ // 8. For f < 0, g integer, dg != 0: The value is finite but the derivatives are
1193
+ // not, because any change in the value of g moves us away from the point
1194
+ // with a real-valued answer into the region with complex-valued answers.
1195
+ //
1196
+ // 9. For f < 0, g noninteger: The value and derivatives of f^g are not finite.
1197
+
1198
+ template <typename T, int N>
1199
+ inline Jet<T, N> pow(const Jet<T, N>& f, const Jet<T, N>& g) {
1200
+ Jet<T, N> result;
1201
+
1202
+ if (fpclassify(f) == FP_ZERO && g >= 1) {
1203
+ // Handle cases 2 and 3.
1204
+ if (g > 1) {
1205
+ result = Jet<T, N>(T(0.0));
1206
+ } else {
1207
+ result = f;
1208
+ }
1209
+
1210
+ } else {
1211
+ if (f < 0 && g == floor(g.a)) {
1212
+ // Handle cases 7 and 8.
1213
+ T const tmp = g.a * pow(f.a, g.a - T(1.0));
1214
+ result = Jet<T, N>(pow(f.a, g.a), tmp * f.v);
1215
+ for (int i = 0; i < N; i++) {
1216
+ if (fpclassify(g.v[i]) != FP_ZERO) {
1217
+ // Return a NaN when g.v != 0.
1218
+ result.v[i] = T(std::numeric_limits<double>::quiet_NaN());
1219
+ }
1220
+ }
1221
+ } else {
1222
+ // Handle the remaining cases. For cases 4,5,6,9 we allow the log()
1223
+ // function to generate -HUGE_VAL or NaN, since those cases result in a
1224
+ // nonfinite derivative.
1225
+ T const tmp1 = pow(f.a, g.a);
1226
+ T const tmp2 = g.a * pow(f.a, g.a - T(1.0));
1227
+ T const tmp3 = tmp1 * log(f.a);
1228
+ result = Jet<T, N>(tmp1, tmp2 * f.v + tmp3 * g.v);
1229
+ }
1230
+ }
1231
+
1232
+ return result;
1233
+ }
1234
+
1235
+ // Note: This has to be in the ceres namespace for argument dependent lookup to
1236
+ // function correctly. Otherwise statements like CHECK_LE(x, 2.0) fail with
1237
+ // strange compile errors.
1238
+ template <typename T, int N>
1239
+ inline std::ostream& operator<<(std::ostream& s, const Jet<T, N>& z) {
1240
+ s << "[" << z.a << " ; ";
1241
+ for (int i = 0; i < N; ++i) {
1242
+ s << z.v[i];
1243
+ if (i != N - 1) {
1244
+ s << ", ";
1245
+ }
1246
+ }
1247
+ s << "]";
1248
+ return s;
1249
+ }
1250
+ } // namespace ceres
1251
+
1252
+ namespace std {
1253
+ template <typename T, int N>
1254
+ struct numeric_limits<ceres::Jet<T, N>> {
1255
+ static constexpr bool is_specialized = true;
1256
+ static constexpr bool is_signed = std::numeric_limits<T>::is_signed;
1257
+ static constexpr bool is_integer = std::numeric_limits<T>::is_integer;
1258
+ static constexpr bool is_exact = std::numeric_limits<T>::is_exact;
1259
+ static constexpr bool has_infinity = std::numeric_limits<T>::has_infinity;
1260
+ static constexpr bool has_quiet_NaN = std::numeric_limits<T>::has_quiet_NaN;
1261
+ static constexpr bool has_signaling_NaN =
1262
+ std::numeric_limits<T>::has_signaling_NaN;
1263
+ static constexpr bool is_iec559 = std::numeric_limits<T>::is_iec559;
1264
+ static constexpr bool is_bounded = std::numeric_limits<T>::is_bounded;
1265
+ static constexpr bool is_modulo = std::numeric_limits<T>::is_modulo;
1266
+
1267
+ static constexpr std::float_denorm_style has_denorm =
1268
+ std::numeric_limits<T>::has_denorm;
1269
+ static constexpr std::float_round_style round_style =
1270
+ std::numeric_limits<T>::round_style;
1271
+
1272
+ static constexpr int digits = std::numeric_limits<T>::digits;
1273
+ static constexpr int digits10 = std::numeric_limits<T>::digits10;
1274
+ static constexpr int max_digits10 = std::numeric_limits<T>::max_digits10;
1275
+ static constexpr int radix = std::numeric_limits<T>::radix;
1276
+ static constexpr int min_exponent = std::numeric_limits<T>::min_exponent;
1277
+ static constexpr int min_exponent10 = std::numeric_limits<T>::max_exponent10;
1278
+ static constexpr int max_exponent = std::numeric_limits<T>::max_exponent;
1279
+ static constexpr int max_exponent10 = std::numeric_limits<T>::max_exponent10;
1280
+ static constexpr bool traps = std::numeric_limits<T>::traps;
1281
+ static constexpr bool tinyness_before =
1282
+ std::numeric_limits<T>::tinyness_before;
1283
+
1284
+ static constexpr ceres::Jet<T, N> min
1285
+ CERES_PREVENT_MACRO_SUBSTITUTION() noexcept {
1286
+ return ceres::Jet<T, N>((std::numeric_limits<T>::min)());
1287
+ }
1288
+ static constexpr ceres::Jet<T, N> lowest() noexcept {
1289
+ return ceres::Jet<T, N>(std::numeric_limits<T>::lowest());
1290
+ }
1291
+ static constexpr ceres::Jet<T, N> epsilon() noexcept {
1292
+ return ceres::Jet<T, N>(std::numeric_limits<T>::epsilon());
1293
+ }
1294
+ static constexpr ceres::Jet<T, N> round_error() noexcept {
1295
+ return ceres::Jet<T, N>(std::numeric_limits<T>::round_error());
1296
+ }
1297
+ static constexpr ceres::Jet<T, N> infinity() noexcept {
1298
+ return ceres::Jet<T, N>(std::numeric_limits<T>::infinity());
1299
+ }
1300
+ static constexpr ceres::Jet<T, N> quiet_NaN() noexcept {
1301
+ return ceres::Jet<T, N>(std::numeric_limits<T>::quiet_NaN());
1302
+ }
1303
+ static constexpr ceres::Jet<T, N> signaling_NaN() noexcept {
1304
+ return ceres::Jet<T, N>(std::numeric_limits<T>::signaling_NaN());
1305
+ }
1306
+ static constexpr ceres::Jet<T, N> denorm_min() noexcept {
1307
+ return ceres::Jet<T, N>(std::numeric_limits<T>::denorm_min());
1308
+ }
1309
+
1310
+ static constexpr ceres::Jet<T, N> max
1311
+ CERES_PREVENT_MACRO_SUBSTITUTION() noexcept {
1312
+ return ceres::Jet<T, N>((std::numeric_limits<T>::max)());
1313
+ }
1314
+ };
1315
+
1316
+ } // namespace std
1317
+
1318
+ namespace Eigen {
1319
+
1320
+ // Creating a specialization of NumTraits enables placing Jet objects inside
1321
+ // Eigen arrays, getting all the goodness of Eigen combined with autodiff.
1322
+ template <typename T, int N>
1323
+ struct NumTraits<ceres::Jet<T, N>> {
1324
+ using Real = ceres::Jet<T, N>;
1325
+ using NonInteger = ceres::Jet<T, N>;
1326
+ using Nested = ceres::Jet<T, N>;
1327
+ using Literal = ceres::Jet<T, N>;
1328
+
1329
+ static typename ceres::Jet<T, N> dummy_precision() {
1330
+ return ceres::Jet<T, N>(1e-12);
1331
+ }
1332
+
1333
+ static inline Real epsilon() {
1334
+ return Real(std::numeric_limits<T>::epsilon());
1335
+ }
1336
+
1337
+ static inline int digits10() { return NumTraits<T>::digits10(); }
1338
+
1339
+ enum {
1340
+ IsComplex = 0,
1341
+ IsInteger = 0,
1342
+ IsSigned,
1343
+ ReadCost = 1,
1344
+ AddCost = 1,
1345
+ // For Jet types, multiplication is more expensive than addition.
1346
+ MulCost = 3,
1347
+ HasFloatingPoint = 1,
1348
+ RequireInitialization = 1
1349
+ };
1350
+
1351
+ template <bool Vectorized>
1352
+ struct Div {
1353
+ enum {
1354
+ #if defined(EIGEN_VECTORIZE_AVX)
1355
+ AVX = true,
1356
+ #else
1357
+ AVX = false,
1358
+ #endif
1359
+
1360
+ // Assuming that for Jets, division is as expensive as
1361
+ // multiplication.
1362
+ Cost = 3
1363
+ };
1364
+ };
1365
+
1366
+ static inline Real highest() { return Real((std::numeric_limits<T>::max)()); }
1367
+ static inline Real lowest() { return Real(-(std::numeric_limits<T>::max)()); }
1368
+ };
1369
+
1370
+ // Specifying the return type of binary operations between Jets and scalar types
1371
+ // allows you to perform matrix/array operations with Eigen matrices and arrays
1372
+ // such as addition, subtraction, multiplication, and division where one Eigen
1373
+ // matrix/array is of type Jet and the other is a scalar type. This improves
1374
+ // performance by using the optimized scalar-to-Jet binary operations but
1375
+ // is only available on Eigen versions >= 3.3
1376
+ template <typename BinaryOp, typename T, int N>
1377
+ struct ScalarBinaryOpTraits<ceres::Jet<T, N>, T, BinaryOp> {
1378
+ using ReturnType = ceres::Jet<T, N>;
1379
+ };
1380
+ template <typename BinaryOp, typename T, int N>
1381
+ struct ScalarBinaryOpTraits<T, ceres::Jet<T, N>, BinaryOp> {
1382
+ using ReturnType = ceres::Jet<T, N>;
1383
+ };
1384
+
1385
+ } // namespace Eigen
1386
+
1387
+ #endif // CERES_PUBLIC_JET_H_
ceres-v2/include/jet_fwd.h ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sergiu.deitsch@gmail.com (Sergiu Deitsch)
30
+ //
31
+
32
+ #ifndef CERES_PUBLIC_JET_FWD_H_
33
+ #define CERES_PUBLIC_JET_FWD_H_
34
+
35
+ namespace ceres {
36
+
37
+ // Jet forward declaration necessary for the following partial specialization of
38
+ // std::common_type and type traits.
39
+ template <typename T, int N>
40
+ struct Jet;
41
+
42
+ } // namespace ceres
43
+
44
+ #endif // CERES_PUBLIC_JET_FWD_H_
ceres-v2/include/line_manifold.h ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: jodebo_beck@gmx.de (Johannes Beck)
30
+ //
31
+
32
+ #ifndef CERES_PUBLIC_LINE_MANIFOLD_H_
33
+ #define CERES_PUBLIC_LINE_MANIFOLD_H_
34
+
35
+ #include <Eigen/Core>
36
+ #include <algorithm>
37
+ #include <array>
38
+ #include <memory>
39
+ #include <vector>
40
+
41
+ #include "ceres/internal/disable_warnings.h"
42
+ #include "ceres/internal/export.h"
43
+ #include "ceres/internal/householder_vector.h"
44
+ #include "ceres/internal/sphere_manifold_functions.h"
45
+ #include "ceres/manifold.h"
46
+ #include "ceres/types.h"
47
+ #include "glog/logging.h"
48
+
49
+ namespace ceres {
50
+ // This provides a manifold for lines, where the line is
51
+ // over-parameterized by an origin point and a direction vector. So the
52
+ // parameter vector size needs to be two times the ambient space dimension,
53
+ // where the first half is interpreted as the origin point and the second half
54
+ // as the direction.
55
+ //
56
+ // The plus operator for the line direction is the same as for the
57
+ // SphereManifold. The update of the origin point is
58
+ // perpendicular to the line direction before the update.
59
+ //
60
+ // This manifold is a special case of the affine Grassmannian
61
+ // manifold (see https://en.wikipedia.org/wiki/Affine_Grassmannian_(manifold))
62
+ // for the case Graff_1(R^n).
63
+ //
64
+ // The class works with dynamic and static ambient space dimensions. If the
65
+ // ambient space dimensions is known at compile time use
66
+ //
67
+ // LineManifold<3> manifold;
68
+ //
69
+ // If the ambient space dimensions is not known at compile time the template
70
+ // parameter needs to be set to ceres::DYNAMIC and the actual dimension needs
71
+ // to be provided as a constructor argument:
72
+ //
73
+ // LineManifold<ceres::DYNAMIC> manifold(ambient_dim);
74
+ //
75
+ template <int AmbientSpaceDimension>
76
+ class LineManifold final : public Manifold {
77
+ public:
78
+ static_assert(AmbientSpaceDimension == DYNAMIC || AmbientSpaceDimension >= 2,
79
+ "The ambient space must be at least 2.");
80
+ static_assert(ceres::DYNAMIC == Eigen::Dynamic,
81
+ "ceres::DYNAMIC needs to be the same as Eigen::Dynamic.");
82
+
83
+ LineManifold();
84
+ explicit LineManifold(int size);
85
+
86
+ int AmbientSize() const override { return 2 * size_; }
87
+ int TangentSize() const override { return 2 * (size_ - 1); }
88
+ bool Plus(const double* x,
89
+ const double* delta,
90
+ double* x_plus_delta) const override;
91
+ bool PlusJacobian(const double* x, double* jacobian) const override;
92
+ bool Minus(const double* y,
93
+ const double* x,
94
+ double* y_minus_x) const override;
95
+ bool MinusJacobian(const double* x, double* jacobian) const override;
96
+
97
+ private:
98
+ static constexpr bool IsDynamic = (AmbientSpaceDimension == ceres::DYNAMIC);
99
+ static constexpr int TangentSpaceDimension =
100
+ IsDynamic ? ceres::DYNAMIC : AmbientSpaceDimension - 1;
101
+
102
+ static constexpr int DAmbientSpaceDimension =
103
+ IsDynamic ? ceres::DYNAMIC : 2 * AmbientSpaceDimension;
104
+ static constexpr int DTangentSpaceDimension =
105
+ IsDynamic ? ceres::DYNAMIC : 2 * TangentSpaceDimension;
106
+
107
+ using AmbientVector = Eigen::Matrix<double, AmbientSpaceDimension, 1>;
108
+ using TangentVector = Eigen::Matrix<double, TangentSpaceDimension, 1>;
109
+ using MatrixPlusJacobian = Eigen::Matrix<double,
110
+ DAmbientSpaceDimension,
111
+ DTangentSpaceDimension,
112
+ Eigen::RowMajor>;
113
+ using MatrixMinusJacobian = Eigen::Matrix<double,
114
+ DTangentSpaceDimension,
115
+ DAmbientSpaceDimension,
116
+ Eigen::RowMajor>;
117
+
118
+ const int size_{AmbientSpaceDimension};
119
+ };
120
+
121
+ template <int AmbientSpaceDimension>
122
+ LineManifold<AmbientSpaceDimension>::LineManifold()
123
+ : size_{AmbientSpaceDimension} {
124
+ static_assert(
125
+ AmbientSpaceDimension != Eigen::Dynamic,
126
+ "The size is set to dynamic. Please call the constructor with a size.");
127
+ }
128
+
129
+ template <int AmbientSpaceDimension>
130
+ LineManifold<AmbientSpaceDimension>::LineManifold(int size) : size_{size} {
131
+ if (AmbientSpaceDimension != Eigen::Dynamic) {
132
+ CHECK_EQ(AmbientSpaceDimension, size)
133
+ << "Specified size by template parameter differs from the supplied "
134
+ "one.";
135
+ } else {
136
+ CHECK_GT(size_, 1)
137
+ << "The size of the manifold needs to be greater than 1.";
138
+ }
139
+ }
140
+
141
+ template <int AmbientSpaceDimension>
142
+ bool LineManifold<AmbientSpaceDimension>::Plus(const double* x_ptr,
143
+ const double* delta_ptr,
144
+ double* x_plus_delta_ptr) const {
145
+ // We seek a box plus operator of the form
146
+ //
147
+ // [o*, d*] = Plus([o, d], [delta_o, delta_d])
148
+ //
149
+ // where o is the origin point, d is the direction vector, delta_o is
150
+ // the delta of the origin point and delta_d the delta of the direction and
151
+ // o* and d* is the updated origin point and direction.
152
+ //
153
+ // We separate the Plus operator into the origin point and directional part
154
+ // d* = Plus_d(d, delta_d)
155
+ // o* = Plus_o(o, d, delta_o)
156
+ //
157
+ // The direction update function Plus_d is the same as as the SphereManifold:
158
+ //
159
+ // d* = H_{v(d)} [0.5 sinc(0.5 |delta_d|) delta_d, cos(0.5 |delta_d|)]^T
160
+ //
161
+ // where H is the householder matrix
162
+ // H_{v} = I - (2 / |v|^2) v v^T
163
+ // and
164
+ // v(d) = d - sign(d_n) |d| e_n.
165
+ //
166
+ // The origin point update function Plus_o is defined as
167
+ //
168
+ // o* = o + H_{v(d)} [0.5 delta_o, 0]^T.
169
+
170
+ Eigen::Map<const AmbientVector> o(x_ptr, size_);
171
+ Eigen::Map<const AmbientVector> d(x_ptr + size_, size_);
172
+
173
+ Eigen::Map<const TangentVector> delta_o(delta_ptr, size_ - 1);
174
+ Eigen::Map<const TangentVector> delta_d(delta_ptr + size_ - 1, size_ - 1);
175
+ Eigen::Map<AmbientVector> o_plus_delta(x_plus_delta_ptr, size_);
176
+ Eigen::Map<AmbientVector> d_plus_delta(x_plus_delta_ptr + size_, size_);
177
+
178
+ const double norm_delta_d = delta_d.norm();
179
+
180
+ o_plus_delta = o;
181
+
182
+ // Shortcut for zero delta direction.
183
+ if (norm_delta_d == 0.0) {
184
+ d_plus_delta = d;
185
+
186
+ if (delta_o.isZero(0.0)) {
187
+ return true;
188
+ }
189
+ }
190
+
191
+ // Calculate the householder transformation which is needed for f_d and f_o.
192
+ AmbientVector v(size_);
193
+ double beta;
194
+
195
+ // NOTE: The explicit template arguments are needed here because
196
+ // ComputeHouseholderVector is templated and some versions of MSVC
197
+ // have trouble deducing the type of v automatically.
198
+ internal::ComputeHouseholderVector<Eigen::Map<const AmbientVector>,
199
+ double,
200
+ AmbientSpaceDimension>(d, &v, &beta);
201
+
202
+ if (norm_delta_d != 0.0) {
203
+ internal::ComputeSphereManifoldPlus(
204
+ v, beta, d, delta_d, norm_delta_d, &d_plus_delta);
205
+ }
206
+
207
+ // The null space is in the direction of the line, so the tangent space is
208
+ // perpendicular to the line direction. This is achieved by using the
209
+ // householder matrix of the direction and allow only movements
210
+ // perpendicular to e_n.
211
+ //
212
+ // The factor of 0.5 is used to be consistent with the line direction
213
+ // update.
214
+ AmbientVector y(size_);
215
+ y << 0.5 * delta_o, 0;
216
+ o_plus_delta += internal::ApplyHouseholderVector(y, v, beta);
217
+
218
+ return true;
219
+ }
220
+
221
+ template <int AmbientSpaceDimension>
222
+ bool LineManifold<AmbientSpaceDimension>::PlusJacobian(
223
+ const double* x_ptr, double* jacobian_ptr) const {
224
+ Eigen::Map<const AmbientVector> d(x_ptr + size_, size_);
225
+ Eigen::Map<MatrixPlusJacobian> jacobian(
226
+ jacobian_ptr, 2 * size_, 2 * (size_ - 1));
227
+
228
+ // Clear the Jacobian as only half of the matrix is not zero.
229
+ jacobian.setZero();
230
+
231
+ auto jacobian_d =
232
+ jacobian
233
+ .template topLeftCorner<AmbientSpaceDimension, TangentSpaceDimension>(
234
+ size_, size_ - 1);
235
+ auto jacobian_o = jacobian.template bottomRightCorner<AmbientSpaceDimension,
236
+ TangentSpaceDimension>(
237
+ size_, size_ - 1);
238
+ internal::ComputeSphereManifoldPlusJacobian(d, &jacobian_d);
239
+ jacobian_o = jacobian_d;
240
+ return true;
241
+ }
242
+
243
+ template <int AmbientSpaceDimension>
244
+ bool LineManifold<AmbientSpaceDimension>::Minus(const double* y_ptr,
245
+ const double* x_ptr,
246
+ double* y_minus_x) const {
247
+ Eigen::Map<const AmbientVector> y_o(y_ptr, size_);
248
+ Eigen::Map<const AmbientVector> y_d(y_ptr + size_, size_);
249
+ Eigen::Map<const AmbientVector> x_o(x_ptr, size_);
250
+ Eigen::Map<const AmbientVector> x_d(x_ptr + size_, size_);
251
+
252
+ Eigen::Map<TangentVector> y_minus_x_o(y_minus_x, size_ - 1);
253
+ Eigen::Map<TangentVector> y_minus_x_d(y_minus_x + size_ - 1, size_ - 1);
254
+
255
+ AmbientVector v(size_);
256
+ double beta;
257
+
258
+ // NOTE: The explicit template arguments are needed here because
259
+ // ComputeHouseholderVector is templated and some versions of MSVC
260
+ // have trouble deducing the type of v automatically.
261
+ internal::ComputeHouseholderVector<Eigen::Map<const AmbientVector>,
262
+ double,
263
+ AmbientSpaceDimension>(x_d, &v, &beta);
264
+
265
+ internal::ComputeSphereManifoldMinus(v, beta, x_d, y_d, &y_minus_x_d);
266
+
267
+ AmbientVector delta_o = y_o - x_o;
268
+ const AmbientVector h_delta_o =
269
+ 2.0 * internal::ApplyHouseholderVector(delta_o, v, beta);
270
+ y_minus_x_o = h_delta_o.template head<TangentSpaceDimension>(size_ - 1);
271
+
272
+ return true;
273
+ }
274
+
275
+ template <int AmbientSpaceDimension>
276
+ bool LineManifold<AmbientSpaceDimension>::MinusJacobian(
277
+ const double* x_ptr, double* jacobian_ptr) const {
278
+ Eigen::Map<const AmbientVector> d(x_ptr + size_, size_);
279
+ Eigen::Map<MatrixMinusJacobian> jacobian(
280
+ jacobian_ptr, 2 * (size_ - 1), 2 * size_);
281
+
282
+ // Clear the Jacobian as only half of the matrix is not zero.
283
+ jacobian.setZero();
284
+
285
+ auto jacobian_d =
286
+ jacobian
287
+ .template topLeftCorner<TangentSpaceDimension, AmbientSpaceDimension>(
288
+ size_ - 1, size_);
289
+ auto jacobian_o = jacobian.template bottomRightCorner<TangentSpaceDimension,
290
+ AmbientSpaceDimension>(
291
+ size_ - 1, size_);
292
+ internal::ComputeSphereManifoldMinusJacobian(d, &jacobian_d);
293
+ jacobian_o = jacobian_d;
294
+
295
+ return true;
296
+ }
297
+
298
+ } // namespace ceres
299
+
300
+ // clang-format off
301
+ #include "ceres/internal/reenable_warnings.h"
302
+ // clang-format on
303
+
304
+ #endif // CERES_PUBLIC_LINE_MANIFOLD_H_
ceres-v2/include/local_parameterization.h ADDED
@@ -0,0 +1,371 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: keir@google.com (Keir Mierle)
30
+ // sameeragarwal@google.com (Sameer Agarwal)
31
+
32
+ #ifndef CERES_PUBLIC_LOCAL_PARAMETERIZATION_H_
33
+ #define CERES_PUBLIC_LOCAL_PARAMETERIZATION_H_
34
+
35
+ #include <array>
36
+ #include <memory>
37
+ #include <vector>
38
+
39
+ #include "ceres/internal/disable_warnings.h"
40
+ #include "ceres/internal/export.h"
41
+ #include "ceres/internal/port.h"
42
+
43
+ namespace ceres {
44
+
45
+ // WARNING: LocalParameterizations are deprecated. They will be removed from
46
+ // Ceres Solver in version 2.2.0. Please use Manifolds instead.
47
+
48
+ // Purpose: Sometimes parameter blocks x can overparameterize a problem
49
+ //
50
+ // min f(x)
51
+ // x
52
+ //
53
+ // In that case it is desirable to choose a parameterization for the
54
+ // block itself to remove the null directions of the cost. More
55
+ // generally, if x lies on a manifold of a smaller dimension than the
56
+ // ambient space that it is embedded in, then it is numerically and
57
+ // computationally more effective to optimize it using a
58
+ // parameterization that lives in the tangent space of that manifold
59
+ // at each point.
60
+ //
61
+ // For example, a sphere in three dimensions is a 2 dimensional
62
+ // manifold, embedded in a three dimensional space. At each point on
63
+ // the sphere, the plane tangent to it defines a two dimensional
64
+ // tangent space. For a cost function defined on this sphere, given a
65
+ // point x, moving in the direction normal to the sphere at that point
66
+ // is not useful. Thus a better way to do a local optimization is to
67
+ // optimize over two dimensional vector delta in the tangent space at
68
+ // that point and then "move" to the point x + delta, where the move
69
+ // operation involves projecting back onto the sphere. Doing so
70
+ // removes a redundant dimension from the optimization, making it
71
+ // numerically more robust and efficient.
72
+ //
73
+ // More generally we can define a function
74
+ //
75
+ // x_plus_delta = Plus(x, delta),
76
+ //
77
+ // where x_plus_delta has the same size as x, and delta is of size
78
+ // less than or equal to x. The function Plus, generalizes the
79
+ // definition of vector addition. Thus it satisfies the identify
80
+ //
81
+ // Plus(x, 0) = x, for all x.
82
+ //
83
+ // A trivial version of Plus is when delta is of the same size as x
84
+ // and
85
+ //
86
+ // Plus(x, delta) = x + delta
87
+ //
88
+ // A more interesting case if x is two dimensional vector, and the
89
+ // user wishes to hold the first coordinate constant. Then, delta is a
90
+ // scalar and Plus is defined as
91
+ //
92
+ // Plus(x, delta) = x + [0] * delta
93
+ // [1]
94
+ //
95
+ // An example that occurs commonly in Structure from Motion problems
96
+ // is when camera rotations are parameterized using Quaternion. There,
97
+ // it is useful to only make updates orthogonal to that 4-vector
98
+ // defining the quaternion. One way to do this is to let delta be a 3
99
+ // dimensional vector and define Plus to be
100
+ //
101
+ // Plus(x, delta) = [cos(|delta|), sin(|delta|) delta / |delta|] * x
102
+ //
103
+ // The multiplication between the two 4-vectors on the RHS is the
104
+ // standard quaternion product.
105
+ //
106
+ // Given f and a point x, optimizing f can now be restated as
107
+ //
108
+ // min f(Plus(x, delta))
109
+ // delta
110
+ //
111
+ // Given a solution delta to this problem, the optimal value is then
112
+ // given by
113
+ //
114
+ // x* = Plus(x, delta)
115
+ //
116
+ // The class LocalParameterization defines the function Plus and its
117
+ // Jacobian which is needed to compute the Jacobian of f w.r.t delta.
118
+ class CERES_DEPRECATED_WITH_MSG(
119
+ "LocalParameterizations will be removed from the Ceres Solver API in "
120
+ "version 2.2.0. Use Manifolds instead.")
121
+ CERES_EXPORT LocalParameterization {
122
+ public:
123
+ virtual ~LocalParameterization();
124
+
125
+ // Generalization of the addition operation,
126
+ //
127
+ // x_plus_delta = Plus(x, delta)
128
+ //
129
+ // with the condition that Plus(x, 0) = x.
130
+ //
131
+ virtual bool Plus(const double* x,
132
+ const double* delta,
133
+ double* x_plus_delta) const = 0;
134
+
135
+ // The jacobian of Plus(x, delta) w.r.t delta at delta = 0.
136
+ //
137
+ // jacobian is a row-major GlobalSize() x LocalSize() matrix.
138
+ virtual bool ComputeJacobian(const double* x, double* jacobian) const = 0;
139
+
140
+ // local_matrix = global_matrix * jacobian
141
+ //
142
+ // global_matrix is a num_rows x GlobalSize row major matrix.
143
+ // local_matrix is a num_rows x LocalSize row major matrix.
144
+ // jacobian(x) is the matrix returned by ComputeJacobian at x.
145
+ //
146
+ // This is only used by GradientProblem. For most normal uses, it is
147
+ // okay to use the default implementation.
148
+ virtual bool MultiplyByJacobian(const double* x,
149
+ const int num_rows,
150
+ const double* global_matrix,
151
+ double* local_matrix) const;
152
+
153
+ // Size of x.
154
+ virtual int GlobalSize() const = 0;
155
+
156
+ // Size of delta.
157
+ virtual int LocalSize() const = 0;
158
+ };
159
+
160
+ // Some basic parameterizations
161
+
162
+ // Identity Parameterization: Plus(x, delta) = x + delta
163
+ class CERES_DEPRECATED_WITH_MSG("Use EuclideanManifold instead.")
164
+ CERES_EXPORT IdentityParameterization : public LocalParameterization {
165
+ public:
166
+ explicit IdentityParameterization(int size);
167
+ bool Plus(const double* x,
168
+ const double* delta,
169
+ double* x_plus_delta) const override;
170
+ bool ComputeJacobian(const double* x, double* jacobian) const override;
171
+ bool MultiplyByJacobian(const double* x,
172
+ const int num_cols,
173
+ const double* global_matrix,
174
+ double* local_matrix) const override;
175
+ int GlobalSize() const override { return size_; }
176
+ int LocalSize() const override { return size_; }
177
+
178
+ private:
179
+ const int size_;
180
+ };
181
+
182
+ // Hold a subset of the parameters inside a parameter block constant.
183
+ class CERES_DEPRECATED_WITH_MSG("Use SubsetManifold instead.")
184
+ CERES_EXPORT SubsetParameterization : public LocalParameterization {
185
+ public:
186
+ explicit SubsetParameterization(int size,
187
+ const std::vector<int>& constant_parameters);
188
+ bool Plus(const double* x,
189
+ const double* delta,
190
+ double* x_plus_delta) const override;
191
+ bool ComputeJacobian(const double* x, double* jacobian) const override;
192
+ bool MultiplyByJacobian(const double* x,
193
+ const int num_cols,
194
+ const double* global_matrix,
195
+ double* local_matrix) const override;
196
+ int GlobalSize() const override {
197
+ return static_cast<int>(constancy_mask_.size());
198
+ }
199
+ int LocalSize() const override { return local_size_; }
200
+
201
+ private:
202
+ const int local_size_;
203
+ std::vector<char> constancy_mask_;
204
+ };
205
+
206
+ // Plus(x, delta) = [cos(|delta|), sin(|delta|) delta / |delta|] * x
207
+ // with * being the quaternion multiplication operator. Here we assume
208
+ // that the first element of the quaternion vector is the real (cos
209
+ // theta) part.
210
+ class CERES_DEPRECATED_WITH_MSG("Use QuaternionManifold instead.")
211
+ CERES_EXPORT QuaternionParameterization : public LocalParameterization {
212
+ public:
213
+ bool Plus(const double* x,
214
+ const double* delta,
215
+ double* x_plus_delta) const override;
216
+ bool ComputeJacobian(const double* x, double* jacobian) const override;
217
+ int GlobalSize() const override { return 4; }
218
+ int LocalSize() const override { return 3; }
219
+ };
220
+
221
+ // Implements the quaternion local parameterization for Eigen's representation
222
+ // of the quaternion. Eigen uses a different internal memory layout for the
223
+ // elements of the quaternion than what is commonly used. Specifically, Eigen
224
+ // stores the elements in memory as [x, y, z, w] where the real part is last
225
+ // whereas it is typically stored first. Note, when creating an Eigen quaternion
226
+ // through the constructor the elements are accepted in w, x, y, z order. Since
227
+ // Ceres operates on parameter blocks which are raw double pointers this
228
+ // difference is important and requires a different parameterization.
229
+ //
230
+ // Plus(x, delta) = [sin(|delta|) delta / |delta|, cos(|delta|)] * x
231
+ // with * being the quaternion multiplication operator.
232
+ class CERES_DEPRECATED_WITH_MSG("Use EigenQuaternionManifold instead.")
233
+ CERES_EXPORT EigenQuaternionParameterization
234
+ : public ceres::LocalParameterization {
235
+ public:
236
+ bool Plus(const double* x,
237
+ const double* delta,
238
+ double* x_plus_delta) const override;
239
+ bool ComputeJacobian(const double* x, double* jacobian) const override;
240
+ int GlobalSize() const override { return 4; }
241
+ int LocalSize() const override { return 3; }
242
+ };
243
+
244
+ // This provides a parameterization for homogeneous vectors which are commonly
245
+ // used in Structure from Motion problems. One example where they are used is
246
+ // in representing points whose triangulation is ill-conditioned. Here it is
247
+ // advantageous to use an over-parameterization since homogeneous vectors can
248
+ // represent points at infinity.
249
+ //
250
+ // The plus operator is defined as
251
+ // Plus(x, delta) =
252
+ // [sin(0.5 * |delta|) * delta / |delta|, cos(0.5 * |delta|)] * x
253
+ //
254
+ // with * defined as an operator which applies the update orthogonal to x to
255
+ // remain on the sphere. We assume that the last element of x is the scalar
256
+ // component. The size of the homogeneous vector is required to be greater than
257
+ // 1.
258
+ class CERES_DEPRECATED_WITH_MSG("Use SphereManifold instead.") CERES_EXPORT
259
+ HomogeneousVectorParameterization : public LocalParameterization {
260
+ public:
261
+ explicit HomogeneousVectorParameterization(int size);
262
+ bool Plus(const double* x,
263
+ const double* delta,
264
+ double* x_plus_delta) const override;
265
+ bool ComputeJacobian(const double* x, double* jacobian) const override;
266
+ int GlobalSize() const override { return size_; }
267
+ int LocalSize() const override { return size_ - 1; }
268
+
269
+ private:
270
+ const int size_;
271
+ };
272
+
273
+ // This provides a parameterization for lines, where the line is
274
+ // over-parameterized by an origin point and a direction vector. So the
275
+ // parameter vector size needs to be two times the ambient space dimension,
276
+ // where the first half is interpreted as the origin point and the second half
277
+ // as the direction.
278
+ //
279
+ // The plus operator for the line direction is the same as for the
280
+ // HomogeneousVectorParameterization. The update of the origin point is
281
+ // perpendicular to the line direction before the update.
282
+ //
283
+ // This local parameterization is a special case of the affine Grassmannian
284
+ // manifold (see https://en.wikipedia.org/wiki/Affine_Grassmannian_(manifold))
285
+ // for the case Graff_1(R^n).
286
+ template <int AmbientSpaceDimension>
287
+ class CERES_DEPRECATED_WITH_MSG("Use LineManifold instead.")
288
+ LineParameterization : public LocalParameterization {
289
+ public:
290
+ static_assert(AmbientSpaceDimension >= 2,
291
+ "The ambient space must be at least 2");
292
+
293
+ bool Plus(const double* x,
294
+ const double* delta,
295
+ double* x_plus_delta) const override;
296
+ bool ComputeJacobian(const double* x, double* jacobian) const override;
297
+ int GlobalSize() const override { return 2 * AmbientSpaceDimension; }
298
+ int LocalSize() const override { return 2 * (AmbientSpaceDimension - 1); }
299
+ };
300
+
301
+ // Construct a local parameterization by taking the Cartesian product
302
+ // of a number of other local parameterizations. This is useful, when
303
+ // a parameter block is the cartesian product of two or more
304
+ // manifolds. For example the parameters of a camera consist of a
305
+ // rotation and a translation, i.e., SO(3) x R^3.
306
+ //
307
+ // Example usage:
308
+ //
309
+ // ProductParameterization product_param(new QuaterionionParameterization(),
310
+ // new IdentityParameterization(3));
311
+ //
312
+ // is the local parameterization for a rigid transformation, where the
313
+ // rotation is represented using a quaternion.
314
+ //
315
+ class CERES_DEPRECATED_WITH_MSG("Use ProductManifold instead.")
316
+ CERES_EXPORT ProductParameterization : public LocalParameterization {
317
+ public:
318
+ ProductParameterization(const ProductParameterization&) = delete;
319
+ ProductParameterization& operator=(const ProductParameterization&) = delete;
320
+ //
321
+ // NOTE: The constructor takes ownership of the input local
322
+ // parameterizations.
323
+ //
324
+ template <typename... LocalParams>
325
+ explicit ProductParameterization(LocalParams*... local_params)
326
+ : local_params_(sizeof...(LocalParams)) {
327
+ constexpr int kNumLocalParams = sizeof...(LocalParams);
328
+ static_assert(kNumLocalParams >= 2,
329
+ "At least two local parameterizations must be specified.");
330
+
331
+ using LocalParameterizationPtr = std::unique_ptr<LocalParameterization>;
332
+
333
+ // Wrap all raw pointers into std::unique_ptr for exception safety.
334
+ std::array<LocalParameterizationPtr, kNumLocalParams> local_params_array{
335
+ LocalParameterizationPtr(local_params)...};
336
+
337
+ // Initialize internal state.
338
+ for (int i = 0; i < kNumLocalParams; ++i) {
339
+ LocalParameterizationPtr& param = local_params_[i];
340
+ param = std::move(local_params_array[i]);
341
+
342
+ buffer_size_ =
343
+ std::max(buffer_size_, param->LocalSize() * param->GlobalSize());
344
+ global_size_ += param->GlobalSize();
345
+ local_size_ += param->LocalSize();
346
+ }
347
+ }
348
+
349
+ bool Plus(const double* x,
350
+ const double* delta,
351
+ double* x_plus_delta) const override;
352
+ bool ComputeJacobian(const double* x, double* jacobian) const override;
353
+ int GlobalSize() const override { return global_size_; }
354
+ int LocalSize() const override { return local_size_; }
355
+
356
+ private:
357
+ std::vector<std::unique_ptr<LocalParameterization>> local_params_;
358
+ int local_size_{0};
359
+ int global_size_{0};
360
+ int buffer_size_{0};
361
+ };
362
+
363
+ } // namespace ceres
364
+
365
+ // clang-format off
366
+ #include "ceres/internal/reenable_warnings.h"
367
+ // clang-format on
368
+
369
+ #include "ceres/internal/line_parameterization.h"
370
+
371
+ #endif // CERES_PUBLIC_LOCAL_PARAMETERIZATION_H_
ceres-v2/include/loss_function.h ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+ //
31
+ // The LossFunction interface is the way users describe how residuals
32
+ // are converted to cost terms for the overall problem cost function.
33
+ // For the exact manner in which loss functions are converted to the
34
+ // overall cost for a problem, see problem.h.
35
+ //
36
+ // For least squares problem where there are no outliers and standard
37
+ // squared loss is expected, it is not necessary to create a loss
38
+ // function; instead passing a nullptr to the problem when adding
39
+ // residuals implies a standard squared loss.
40
+ //
41
+ // For least squares problems where the minimization may encounter
42
+ // input terms that contain outliers, that is, completely bogus
43
+ // measurements, it is important to use a loss function that reduces
44
+ // their associated penalty.
45
+ //
46
+ // Consider a structure from motion problem. The unknowns are 3D
47
+ // points and camera parameters, and the measurements are image
48
+ // coordinates describing the expected reprojected position for a
49
+ // point in a camera. For example, we want to model the geometry of a
50
+ // street scene with fire hydrants and cars, observed by a moving
51
+ // camera with unknown parameters, and the only 3D points we care
52
+ // about are the pointy tippy-tops of the fire hydrants. Our magic
53
+ // image processing algorithm, which is responsible for producing the
54
+ // measurements that are input to Ceres, has found and matched all
55
+ // such tippy-tops in all image frames, except that in one of the
56
+ // frame it mistook a car's headlight for a hydrant. If we didn't do
57
+ // anything special (i.e. if we used a basic quadratic loss), the
58
+ // residual for the erroneous measurement will result in extreme error
59
+ // due to the quadratic nature of squared loss. This results in the
60
+ // entire solution getting pulled away from the optimum to reduce
61
+ // the large error that would otherwise be attributed to the wrong
62
+ // measurement.
63
+ //
64
+ // Using a robust loss function, the cost for large residuals is
65
+ // reduced. In the example above, this leads to outlier terms getting
66
+ // downweighted so they do not overly influence the final solution.
67
+ //
68
+ // What cost function is best?
69
+ //
70
+ // In general, there isn't a principled way to select a robust loss
71
+ // function. The authors suggest starting with a non-robust cost, then
72
+ // only experimenting with robust loss functions if standard squared
73
+ // loss doesn't work.
74
+
75
+ #ifndef CERES_PUBLIC_LOSS_FUNCTION_H_
76
+ #define CERES_PUBLIC_LOSS_FUNCTION_H_
77
+
78
+ #include <memory>
79
+
80
+ #include "ceres/internal/disable_warnings.h"
81
+ #include "ceres/internal/export.h"
82
+ #include "ceres/types.h"
83
+ #include "glog/logging.h"
84
+
85
+ namespace ceres {
86
+
87
+ class CERES_EXPORT LossFunction {
88
+ public:
89
+ virtual ~LossFunction();
90
+
91
+ // For a residual vector with squared 2-norm 'sq_norm', this method
92
+ // is required to fill in the value and derivatives of the loss
93
+ // function (rho in this example):
94
+ //
95
+ // out[0] = rho(sq_norm),
96
+ // out[1] = rho'(sq_norm),
97
+ // out[2] = rho''(sq_norm),
98
+ //
99
+ // Here the convention is that the contribution of a term to the
100
+ // cost function is given by 1/2 rho(s), where
101
+ //
102
+ // s = ||residuals||^2.
103
+ //
104
+ // Calling the method with a negative value of 's' is an error and
105
+ // the implementations are not required to handle that case.
106
+ //
107
+ // Most sane choices of rho() satisfy:
108
+ //
109
+ // rho(0) = 0,
110
+ // rho'(0) = 1,
111
+ // rho'(s) < 1 in outlier region,
112
+ // rho''(s) < 0 in outlier region,
113
+ //
114
+ // so that they mimic the least squares cost for small residuals.
115
+ virtual void Evaluate(double sq_norm, double out[3]) const = 0;
116
+ };
117
+
118
+ // Some common implementations follow below.
119
+ //
120
+ // Note: in the region of interest (i.e. s < 3) we have:
121
+ // TrivialLoss >= HuberLoss >= SoftLOneLoss >= CauchyLoss
122
+
123
+ // This corresponds to no robustification.
124
+ //
125
+ // rho(s) = s
126
+ //
127
+ // At s = 0: rho = [0, 1, 0].
128
+ //
129
+ // It is not normally necessary to use this, as passing nullptr for the
130
+ // loss function when building the problem accomplishes the same
131
+ // thing.
132
+ class CERES_EXPORT TrivialLoss final : public LossFunction {
133
+ public:
134
+ void Evaluate(double, double*) const override;
135
+ };
136
+
137
+ // Scaling
138
+ // -------
139
+ // Given one robustifier
140
+ // s -> rho(s)
141
+ // one can change the length scale at which robustification takes
142
+ // place, by adding a scale factor 'a' as follows:
143
+ //
144
+ // s -> a^2 rho(s / a^2).
145
+ //
146
+ // The first and second derivatives are:
147
+ //
148
+ // s -> rho'(s / a^2),
149
+ // s -> (1 / a^2) rho''(s / a^2),
150
+ //
151
+ // but the behaviour near s = 0 is the same as the original function,
152
+ // i.e.
153
+ //
154
+ // rho(s) = s + higher order terms,
155
+ // a^2 rho(s / a^2) = s + higher order terms.
156
+ //
157
+ // The scalar 'a' should be positive.
158
+ //
159
+ // The reason for the appearance of squaring is that 'a' is in the
160
+ // units of the residual vector norm whereas 's' is a squared
161
+ // norm. For applications it is more convenient to specify 'a' than
162
+ // its square. The commonly used robustifiers below are described in
163
+ // un-scaled format (a = 1) but their implementations work for any
164
+ // non-zero value of 'a'.
165
+
166
+ // Huber.
167
+ //
168
+ // rho(s) = s for s <= 1,
169
+ // rho(s) = 2 sqrt(s) - 1 for s >= 1.
170
+ //
171
+ // At s = 0: rho = [0, 1, 0].
172
+ //
173
+ // The scaling parameter 'a' corresponds to 'delta' on this page:
174
+ // http://en.wikipedia.org/wiki/Huber_Loss_Function
175
+ class CERES_EXPORT HuberLoss final : public LossFunction {
176
+ public:
177
+ explicit HuberLoss(double a) : a_(a), b_(a * a) {}
178
+ void Evaluate(double, double*) const override;
179
+
180
+ private:
181
+ const double a_;
182
+ // b = a^2.
183
+ const double b_;
184
+ };
185
+
186
+ // Soft L1, similar to Huber but smooth.
187
+ //
188
+ // rho(s) = 2 (sqrt(1 + s) - 1).
189
+ //
190
+ // At s = 0: rho = [0, 1, -1 / (2 * a^2)].
191
+ class CERES_EXPORT SoftLOneLoss final : public LossFunction {
192
+ public:
193
+ explicit SoftLOneLoss(double a) : b_(a * a), c_(1 / b_) {}
194
+ void Evaluate(double, double*) const override;
195
+
196
+ private:
197
+ // b = a^2.
198
+ const double b_;
199
+ // c = 1 / a^2.
200
+ const double c_;
201
+ };
202
+
203
+ // Inspired by the Cauchy distribution
204
+ //
205
+ // rho(s) = log(1 + s).
206
+ //
207
+ // At s = 0: rho = [0, 1, -1 / a^2].
208
+ class CERES_EXPORT CauchyLoss final : public LossFunction {
209
+ public:
210
+ explicit CauchyLoss(double a) : b_(a * a), c_(1 / b_) {}
211
+ void Evaluate(double, double*) const override;
212
+
213
+ private:
214
+ // b = a^2.
215
+ const double b_;
216
+ // c = 1 / a^2.
217
+ const double c_;
218
+ };
219
+
220
+ // Loss that is capped beyond a certain level using the arc-tangent function.
221
+ // The scaling parameter 'a' determines the level where falloff occurs.
222
+ // For costs much smaller than 'a', the loss function is linear and behaves like
223
+ // TrivialLoss, and for values much larger than 'a' the value asymptotically
224
+ // approaches the constant value of a * PI / 2.
225
+ //
226
+ // rho(s) = a atan(s / a).
227
+ //
228
+ // At s = 0: rho = [0, 1, 0].
229
+ class CERES_EXPORT ArctanLoss final : public LossFunction {
230
+ public:
231
+ explicit ArctanLoss(double a) : a_(a), b_(1 / (a * a)) {}
232
+ void Evaluate(double, double*) const override;
233
+
234
+ private:
235
+ const double a_;
236
+ // b = 1 / a^2.
237
+ const double b_;
238
+ };
239
+
240
+ // Loss function that maps to approximately zero cost in a range around the
241
+ // origin, and reverts to linear in error (quadratic in cost) beyond this range.
242
+ // The tolerance parameter 'a' sets the nominal point at which the
243
+ // transition occurs, and the transition size parameter 'b' sets the nominal
244
+ // distance over which most of the transition occurs. Both a and b must be
245
+ // greater than zero, and typically b will be set to a fraction of a.
246
+ // The slope rho'[s] varies smoothly from about 0 at s <= a - b to
247
+ // about 1 at s >= a + b.
248
+ //
249
+ // The term is computed as:
250
+ //
251
+ // rho(s) = b log(1 + exp((s - a) / b)) - c0.
252
+ //
253
+ // where c0 is chosen so that rho(0) == 0
254
+ //
255
+ // c0 = b log(1 + exp(-a / b)
256
+ //
257
+ // This has the following useful properties:
258
+ //
259
+ // rho(s) == 0 for s = 0
260
+ // rho'(s) ~= 0 for s << a - b
261
+ // rho'(s) ~= 1 for s >> a + b
262
+ // rho''(s) > 0 for all s
263
+ //
264
+ // In addition, all derivatives are continuous, and the curvature is
265
+ // concentrated in the range a - b to a + b.
266
+ //
267
+ // At s = 0: rho = [0, ~0, ~0].
268
+ class CERES_EXPORT TolerantLoss final : public LossFunction {
269
+ public:
270
+ explicit TolerantLoss(double a, double b);
271
+ void Evaluate(double, double*) const override;
272
+
273
+ private:
274
+ const double a_, b_, c_;
275
+ };
276
+
277
+ // This is the Tukey biweight loss function which aggressively
278
+ // attempts to suppress large errors.
279
+ //
280
+ // The term is computed as follows where the equations are scaled by a
281
+ // factor of 2 because the cost function is given by 1/2 rho(s):
282
+ //
283
+ // rho(s) = a^2 / 3 * (1 - (1 - s / a^2)^3 ) for s <= a^2,
284
+ // rho(s) = a^2 / 3 for s > a^2.
285
+ //
286
+ // At s = 0: rho = [0, 1, -2 / a^2]
287
+ class CERES_EXPORT TukeyLoss final : public ceres::LossFunction {
288
+ public:
289
+ explicit TukeyLoss(double a) : a_squared_(a * a) {}
290
+ void Evaluate(double, double*) const override;
291
+
292
+ private:
293
+ const double a_squared_;
294
+ };
295
+
296
+ // Composition of two loss functions. The error is the result of first
297
+ // evaluating g followed by f to yield the composition f(g(s)).
298
+ // The loss functions must not be nullptr.
299
+ class CERES_EXPORT ComposedLoss final : public LossFunction {
300
+ public:
301
+ explicit ComposedLoss(const LossFunction* f,
302
+ Ownership ownership_f,
303
+ const LossFunction* g,
304
+ Ownership ownership_g);
305
+ ~ComposedLoss() override;
306
+ void Evaluate(double, double*) const override;
307
+
308
+ private:
309
+ std::unique_ptr<const LossFunction> f_, g_;
310
+ const Ownership ownership_f_, ownership_g_;
311
+ };
312
+
313
+ // The discussion above has to do with length scaling: it affects the space
314
+ // in which s is measured. Sometimes you want to simply scale the output
315
+ // value of the robustifier. For example, you might want to weight
316
+ // different error terms differently (e.g., weight pixel reprojection
317
+ // errors differently from terrain errors).
318
+ //
319
+ // If rho is the wrapped robustifier, then this simply outputs
320
+ // s -> a * rho(s)
321
+ //
322
+ // The first and second derivatives are, not surprisingly
323
+ // s -> a * rho'(s)
324
+ // s -> a * rho''(s)
325
+ //
326
+ // Since we treat the a nullptr Loss function as the Identity loss
327
+ // function, rho = nullptr is a valid input and will result in the input
328
+ // being scaled by a. This provides a simple way of implementing a
329
+ // scaled ResidualBlock.
330
+ class CERES_EXPORT ScaledLoss final : public LossFunction {
331
+ public:
332
+ // Constructs a ScaledLoss wrapping another loss function. Takes
333
+ // ownership of the wrapped loss function or not depending on the
334
+ // ownership parameter.
335
+ ScaledLoss(const LossFunction* rho, double a, Ownership ownership)
336
+ : rho_(rho), a_(a), ownership_(ownership) {}
337
+ ScaledLoss(const ScaledLoss&) = delete;
338
+ void operator=(const ScaledLoss&) = delete;
339
+
340
+ ~ScaledLoss() override {
341
+ if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
342
+ rho_.release();
343
+ }
344
+ }
345
+ void Evaluate(double, double*) const override;
346
+
347
+ private:
348
+ std::unique_ptr<const LossFunction> rho_;
349
+ const double a_;
350
+ const Ownership ownership_;
351
+ };
352
+
353
+ // Sometimes after the optimization problem has been constructed, we
354
+ // wish to mutate the scale of the loss function. For example, when
355
+ // performing estimation from data which has substantial outliers,
356
+ // convergence can be improved by starting out with a large scale,
357
+ // optimizing the problem and then reducing the scale. This can have
358
+ // better convergence behaviour than just using a loss function with a
359
+ // small scale.
360
+ //
361
+ // This templated class allows the user to implement a loss function
362
+ // whose scale can be mutated after an optimization problem has been
363
+ // constructed.
364
+ //
365
+ // Since we treat the a nullptr Loss function as the Identity loss
366
+ // function, rho = nullptr is a valid input.
367
+ //
368
+ // Example usage
369
+ //
370
+ // Problem problem;
371
+ //
372
+ // // Add parameter blocks
373
+ //
374
+ // CostFunction* cost_function =
375
+ // new AutoDiffCostFunction < UW_Camera_Mapper, 2, 9, 3>(
376
+ // new UW_Camera_Mapper(feature_x, feature_y));
377
+ //
378
+ // LossFunctionWrapper* loss_function = new LossFunctionWrapper(
379
+ // new HuberLoss(1.0), TAKE_OWNERSHIP);
380
+ //
381
+ // problem.AddResidualBlock(cost_function, loss_function, parameters);
382
+ //
383
+ // Solver::Options options;
384
+ // Solger::Summary summary;
385
+ //
386
+ // Solve(options, &problem, &summary)
387
+ //
388
+ // loss_function->Reset(new HuberLoss(1.0), TAKE_OWNERSHIP);
389
+ //
390
+ // Solve(options, &problem, &summary)
391
+ //
392
+ class CERES_EXPORT LossFunctionWrapper final : public LossFunction {
393
+ public:
394
+ LossFunctionWrapper(LossFunction* rho, Ownership ownership)
395
+ : rho_(rho), ownership_(ownership) {}
396
+
397
+ LossFunctionWrapper(const LossFunctionWrapper&) = delete;
398
+ void operator=(const LossFunctionWrapper&) = delete;
399
+
400
+ ~LossFunctionWrapper() override {
401
+ if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
402
+ rho_.release();
403
+ }
404
+ }
405
+
406
+ void Evaluate(double sq_norm, double out[3]) const override {
407
+ if (rho_.get() == nullptr) {
408
+ out[0] = sq_norm;
409
+ out[1] = 1.0;
410
+ out[2] = 0.0;
411
+ } else {
412
+ rho_->Evaluate(sq_norm, out);
413
+ }
414
+ }
415
+
416
+ void Reset(LossFunction* rho, Ownership ownership) {
417
+ if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
418
+ rho_.release();
419
+ }
420
+ rho_.reset(rho);
421
+ ownership_ = ownership;
422
+ }
423
+
424
+ private:
425
+ std::unique_ptr<const LossFunction> rho_;
426
+ Ownership ownership_;
427
+ };
428
+
429
+ } // namespace ceres
430
+
431
+ #include "ceres/internal/reenable_warnings.h"
432
+
433
+ #endif // CERES_PUBLIC_LOSS_FUNCTION_H_
ceres-v2/include/manifold.h ADDED
@@ -0,0 +1,411 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #ifndef CERES_PUBLIC_MANIFOLD_H_
32
+ #define CERES_PUBLIC_MANIFOLD_H_
33
+
34
+ #include <Eigen/Core>
35
+ #include <algorithm>
36
+ #include <array>
37
+ #include <memory>
38
+ #include <utility>
39
+ #include <vector>
40
+
41
+ #include "ceres/internal/disable_warnings.h"
42
+ #include "ceres/internal/export.h"
43
+ #include "ceres/types.h"
44
+ #include "glog/logging.h"
45
+
46
+ namespace ceres {
47
+
48
+ // In sensor fusion problems, often we have to model quantities that live in
49
+ // spaces known as Manifolds, for example the rotation/orientation of a sensor
50
+ // that is represented by a quaternion.
51
+ //
52
+ // Manifolds are spaces which locally look like Euclidean spaces. More
53
+ // precisely, at each point on the manifold there is a linear space that is
54
+ // tangent to the manifold. It has dimension equal to the intrinsic dimension of
55
+ // the manifold itself, which is less than or equal to the ambient space in
56
+ // which the manifold is embedded.
57
+ //
58
+ // For example, the tangent space to a point on a sphere in three dimensions is
59
+ // the two dimensional plane that is tangent to the sphere at that point. There
60
+ // are two reasons tangent spaces are interesting:
61
+ //
62
+ // 1. They are Eucliean spaces so the usual vector space operations apply there,
63
+ // which makes numerical operations easy.
64
+ // 2. Movement in the tangent space translate into movements along the manifold.
65
+ // Movements perpendicular to the tangent space do not translate into
66
+ // movements on the manifold.
67
+ //
68
+ // Returning to our sphere example, moving in the 2 dimensional plane
69
+ // tangent to the sphere and projecting back onto the sphere will move you away
70
+ // from the point you started from but moving along the normal at the same point
71
+ // and the projecting back onto the sphere brings you back to the point.
72
+ //
73
+ // The Manifold interface defines two operations (and their derivatives)
74
+ // involving the tangent space, allowing filtering and optimization to be
75
+ // performed on said manifold:
76
+ //
77
+ // 1. x_plus_delta = Plus(x, delta)
78
+ // 2. delta = Minus(x_plus_delta, x)
79
+ //
80
+ // "Plus" computes the result of moving along delta in the tangent space at x,
81
+ // and then projecting back onto the manifold that x belongs to. In Differential
82
+ // Geometry this is known as a "Retraction". It is a generalization of vector
83
+ // addition in Euclidean spaces.
84
+ //
85
+ // Given two points on the manifold, "Minus" computes the change delta to x in
86
+ // the tangent space at x, that will take it to x_plus_delta.
87
+ //
88
+ // Let us now consider two examples.
89
+ //
90
+ // The Euclidean space R^n is the simplest example of a manifold. It has
91
+ // dimension n (and so does its tangent space) and Plus and Minus are the
92
+ // familiar vector sum and difference operations.
93
+ //
94
+ // Plus(x, delta) = x + delta = y,
95
+ // Minus(y, x) = y - x = delta.
96
+ //
97
+ // A more interesting case is SO(3), the special orthogonal group in three
98
+ // dimensions - the space of 3x3 rotation matrices. SO(3) is a three dimensional
99
+ // manifold embedded in R^9 or R^(3x3). So points on SO(3) are represented using
100
+ // 9 dimensional vectors or 3x3 matrices, and points in its tangent spaces are
101
+ // represented by 3 dimensional vectors.
102
+ //
103
+ // Defining Plus and Minus are defined in terms of the matrix Exp and Log
104
+ // operations as follows:
105
+ //
106
+ // Let Exp(p, q, r) = [cos(theta) + cp^2, -sr + cpq , sq + cpr ]
107
+ // [sr + cpq , cos(theta) + cq^2, -sp + cqr ]
108
+ // [-sq + cpr , sp + cqr , cos(theta) + cr^2]
109
+ //
110
+ // where: theta = sqrt(p^2 + q^2 + r^2)
111
+ // s = sinc(theta)
112
+ // c = (1 - cos(theta))/theta^2
113
+ //
114
+ // and Log(x) = 1/(2 sinc(theta))[x_32 - x_23, x_13 - x_31, x_21 - x_12]
115
+ //
116
+ // where: theta = acos((Trace(x) - 1)/2)
117
+ //
118
+ // Then,
119
+ //
120
+ // Plus(x, delta) = x Exp(delta)
121
+ // Minus(y, x) = Log(x^T y)
122
+ //
123
+ // For Plus and Minus to be mathematically consistent, the following identities
124
+ // must be satisfied at all points x on the manifold:
125
+ //
126
+ // 1. Plus(x, 0) = x.
127
+ // 2. For all y, Plus(x, Minus(y, x)) = y.
128
+ // 3. For all delta, Minus(Plus(x, delta), x) = delta.
129
+ // 4. For all delta_1, delta_2
130
+ // |Minus(Plus(x, delta_1), Plus(x, delta_2)) <= |delta_1 - delta_2|
131
+ //
132
+ // Briefly:
133
+ // (1) Ensures that the tangent space is "centered" at x, and the zero vector is
134
+ // the identity element.
135
+ // (2) Ensures that any y can be reached from x.
136
+ // (3) Ensures that Plus is an injective (one-to-one) map.
137
+ // (4) Allows us to define a metric on the manifold.
138
+ //
139
+ // Additionally we require that Plus and Minus be sufficiently smooth. In
140
+ // particular they need to be differentiable everywhere on the manifold.
141
+ //
142
+ // For more details, please see
143
+ //
144
+ // "Integrating Generic Sensor Fusion Algorithms with Sound State
145
+ // Representations through Encapsulation of Manifolds"
146
+ // By C. Hertzberg, R. Wagner, U. Frese and L. Schroder
147
+ // https://arxiv.org/pdf/1107.1119.pdf
148
+ class CERES_EXPORT Manifold {
149
+ public:
150
+ virtual ~Manifold();
151
+
152
+ // Dimension of the ambient space in which the manifold is embedded.
153
+ virtual int AmbientSize() const = 0;
154
+
155
+ // Dimension of the manifold/tangent space.
156
+ virtual int TangentSize() const = 0;
157
+
158
+ // x_plus_delta = Plus(x, delta),
159
+ //
160
+ // A generalization of vector addition in Euclidean space, Plus computes the
161
+ // result of moving along delta in the tangent space at x, and then projecting
162
+ // back onto the manifold that x belongs to.
163
+ //
164
+ // x and x_plus_delta are AmbientSize() vectors.
165
+ // delta is a TangentSize() vector.
166
+ //
167
+ // Return value indicates if the operation was successful or not.
168
+ virtual bool Plus(const double* x,
169
+ const double* delta,
170
+ double* x_plus_delta) const = 0;
171
+
172
+ // Compute the derivative of Plus(x, delta) w.r.t delta at delta = 0, i.e.
173
+ //
174
+ // (D_2 Plus)(x, 0)
175
+ //
176
+ // jacobian is a row-major AmbientSize() x TangentSize() matrix.
177
+ //
178
+ // Return value indicates whether the operation was successful or not.
179
+ virtual bool PlusJacobian(const double* x, double* jacobian) const = 0;
180
+
181
+ // tangent_matrix = ambient_matrix * (D_2 Plus)(x, 0)
182
+ //
183
+ // ambient_matrix is a row-major num_rows x AmbientSize() matrix.
184
+ // tangent_matrix is a row-major num_rows x TangentSize() matrix.
185
+ //
186
+ // Return value indicates whether the operation was successful or not.
187
+ //
188
+ // This function is only used by the GradientProblemSolver, where the
189
+ // dimension of the parameter block can be large and it may be more efficient
190
+ // to compute this product directly rather than first evaluating the Jacobian
191
+ // into a matrix and then doing a matrix vector product.
192
+ //
193
+ // Because this is not an often used function, we provide a default
194
+ // implementation for convenience. If performance becomes an issue then the
195
+ // user should consider implementing a specialization.
196
+ virtual bool RightMultiplyByPlusJacobian(const double* x,
197
+ const int num_rows,
198
+ const double* ambient_matrix,
199
+ double* tangent_matrix) const;
200
+
201
+ // y_minus_x = Minus(y, x)
202
+ //
203
+ // Given two points on the manifold, Minus computes the change to x in the
204
+ // tangent space at x, that will take it to y.
205
+ //
206
+ // x and y are AmbientSize() vectors.
207
+ // y_minus_x is a TangentSize() vector.
208
+ //
209
+ // Return value indicates if the operation was successful or not.
210
+ virtual bool Minus(const double* y,
211
+ const double* x,
212
+ double* y_minus_x) const = 0;
213
+
214
+ // Compute the derivative of Minus(y, x) w.r.t y at y = x, i.e
215
+ //
216
+ // (D_1 Minus) (x, x)
217
+ //
218
+ // Jacobian is a row-major TangentSize() x AmbientSize() matrix.
219
+ //
220
+ // Return value indicates whether the operation was successful or not.
221
+ virtual bool MinusJacobian(const double* x, double* jacobian) const = 0;
222
+ };
223
+
224
+ // The Euclidean manifold is another name for the ordinary vector space R^size,
225
+ // where the plus and minus operations are the usual vector addition and
226
+ // subtraction:
227
+ // Plus(x, delta) = x + delta
228
+ // Minus(y, x) = y - x.
229
+ //
230
+ // The class works with dynamic and static ambient space dimensions. If the
231
+ // ambient space dimensions is know at compile time use
232
+ //
233
+ // EuclideanManifold<3> manifold;
234
+ //
235
+ // If the ambient space dimensions is not known at compile time the template
236
+ // parameter needs to be set to ceres::DYNAMIC and the actual dimension needs
237
+ // to be provided as a constructor argument:
238
+ //
239
+ // EuclideanManifold<ceres::DYNAMIC> manifold(ambient_dim);
240
+ template <int Size>
241
+ class EuclideanManifold final : public Manifold {
242
+ public:
243
+ static_assert(Size == ceres::DYNAMIC || Size >= 0,
244
+ "The size of the manifold needs to be non-negative.");
245
+ static_assert(ceres::DYNAMIC == Eigen::Dynamic,
246
+ "ceres::DYNAMIC needs to be the same as Eigen::Dynamic.");
247
+
248
+ EuclideanManifold() : size_{Size} {
249
+ static_assert(
250
+ Size != ceres::DYNAMIC,
251
+ "The size is set to dynamic. Please call the constructor with a size.");
252
+ }
253
+
254
+ explicit EuclideanManifold(int size) : size_(size) {
255
+ if (Size != ceres::DYNAMIC) {
256
+ CHECK_EQ(Size, size)
257
+ << "Specified size by template parameter differs from the supplied "
258
+ "one.";
259
+ } else {
260
+ CHECK_GE(size_, 0)
261
+ << "The size of the manifold needs to be non-negative.";
262
+ }
263
+ }
264
+
265
+ int AmbientSize() const override { return size_; }
266
+ int TangentSize() const override { return size_; }
267
+
268
+ bool Plus(const double* x_ptr,
269
+ const double* delta_ptr,
270
+ double* x_plus_delta_ptr) const override {
271
+ Eigen::Map<const AmbientVector> x(x_ptr, size_);
272
+ Eigen::Map<const AmbientVector> delta(delta_ptr, size_);
273
+ Eigen::Map<AmbientVector> x_plus_delta(x_plus_delta_ptr, size_);
274
+ x_plus_delta = x + delta;
275
+ return true;
276
+ }
277
+
278
+ bool PlusJacobian(const double* x_ptr, double* jacobian_ptr) const override {
279
+ Eigen::Map<MatrixJacobian> jacobian(jacobian_ptr, size_, size_);
280
+ jacobian.setIdentity();
281
+ return true;
282
+ }
283
+
284
+ bool RightMultiplyByPlusJacobian(const double* x,
285
+ const int num_rows,
286
+ const double* ambient_matrix,
287
+ double* tangent_matrix) const override {
288
+ std::copy_n(ambient_matrix, num_rows * size_, tangent_matrix);
289
+ return true;
290
+ }
291
+
292
+ bool Minus(const double* y_ptr,
293
+ const double* x_ptr,
294
+ double* y_minus_x_ptr) const override {
295
+ Eigen::Map<const AmbientVector> x(x_ptr, size_);
296
+ Eigen::Map<const AmbientVector> y(y_ptr, size_);
297
+ Eigen::Map<AmbientVector> y_minus_x(y_minus_x_ptr, size_);
298
+ y_minus_x = y - x;
299
+ return true;
300
+ }
301
+
302
+ bool MinusJacobian(const double* x_ptr, double* jacobian_ptr) const override {
303
+ Eigen::Map<MatrixJacobian> jacobian(jacobian_ptr, size_, size_);
304
+ jacobian.setIdentity();
305
+ return true;
306
+ }
307
+
308
+ private:
309
+ static constexpr bool IsDynamic = (Size == ceres::DYNAMIC);
310
+ using AmbientVector = Eigen::Matrix<double, Size, 1>;
311
+ using MatrixJacobian = Eigen::Matrix<double, Size, Size, Eigen::RowMajor>;
312
+
313
+ int size_{};
314
+ };
315
+
316
+ // Hold a subset of the parameters inside a parameter block constant.
317
+ class CERES_EXPORT SubsetManifold final : public Manifold {
318
+ public:
319
+ SubsetManifold(int size, const std::vector<int>& constant_parameters);
320
+ int AmbientSize() const override;
321
+ int TangentSize() const override;
322
+
323
+ bool Plus(const double* x,
324
+ const double* delta,
325
+ double* x_plus_delta) const override;
326
+ bool PlusJacobian(const double* x, double* jacobian) const override;
327
+ bool RightMultiplyByPlusJacobian(const double* x,
328
+ const int num_rows,
329
+ const double* ambient_matrix,
330
+ double* tangent_matrix) const override;
331
+ bool Minus(const double* y,
332
+ const double* x,
333
+ double* y_minus_x) const override;
334
+ bool MinusJacobian(const double* x, double* jacobian) const override;
335
+
336
+ private:
337
+ const int tangent_size_ = 0;
338
+ std::vector<bool> constancy_mask_;
339
+ };
340
+
341
+ // Implements the manifold for a Hamilton quaternion as defined in
342
+ // https://en.wikipedia.org/wiki/Quaternion. Quaternions are represented as
343
+ // unit norm 4-vectors, i.e.
344
+ //
345
+ // q = [q0; q1; q2; q3], |q| = 1
346
+ //
347
+ // is the ambient space representation.
348
+ //
349
+ // q0 scalar part.
350
+ // q1 coefficient of i.
351
+ // q2 coefficient of j.
352
+ // q3 coefficient of k.
353
+ //
354
+ // where: i*i = j*j = k*k = -1 and i*j = k, j*k = i, k*i = j.
355
+ //
356
+ // The tangent space is R^3, which relates to the ambient space through the
357
+ // Plus and Minus operations defined as:
358
+ //
359
+ // Plus(x, delta) = [cos(|delta|); sin(|delta|) * delta / |delta|] * x
360
+ // Minus(y, x) = to_delta(y * x^{-1})
361
+ //
362
+ // where "*" is the quaternion product and because q is a unit quaternion
363
+ // (|q|=1), q^-1 = [q0; -q1; -q2; -q3]
364
+ //
365
+ // and to_delta( [q0; u_{3x1}] ) = u / |u| * atan2(|u|, q0)
366
+ class CERES_EXPORT QuaternionManifold final : public Manifold {
367
+ public:
368
+ int AmbientSize() const override { return 4; }
369
+ int TangentSize() const override { return 3; }
370
+
371
+ bool Plus(const double* x,
372
+ const double* delta,
373
+ double* x_plus_delta) const override;
374
+ bool PlusJacobian(const double* x, double* jacobian) const override;
375
+ bool Minus(const double* y,
376
+ const double* x,
377
+ double* y_minus_x) const override;
378
+ bool MinusJacobian(const double* x, double* jacobian) const override;
379
+ };
380
+
381
+ // Implements the quaternion manifold for Eigen's representation of the
382
+ // Hamilton quaternion. Geometrically it is exactly the same as the
383
+ // QuaternionManifold defined above. However, Eigen uses a different internal
384
+ // memory layout for the elements of the quaternion than what is commonly
385
+ // used. It stores the quaternion in memory as [q1, q2, q3, q0] or
386
+ // [x, y, z, w] where the real (scalar) part is last.
387
+ //
388
+ // Since Ceres operates on parameter blocks which are raw double pointers this
389
+ // difference is important and requires a different manifold.
390
+ class CERES_EXPORT EigenQuaternionManifold final : public Manifold {
391
+ public:
392
+ int AmbientSize() const override { return 4; }
393
+ int TangentSize() const override { return 3; }
394
+
395
+ bool Plus(const double* x,
396
+ const double* delta,
397
+ double* x_plus_delta) const override;
398
+ bool PlusJacobian(const double* x, double* jacobian) const override;
399
+ bool Minus(const double* y,
400
+ const double* x,
401
+ double* y_minus_x) const override;
402
+ bool MinusJacobian(const double* x, double* jacobian) const override;
403
+ };
404
+
405
+ } // namespace ceres
406
+
407
+ // clang-format off
408
+ #include "ceres/internal/reenable_warnings.h"
409
+ // clang-format on
410
+
411
+ #endif // CERES_PUBLIC_MANIFOLD_H_
ceres-v2/include/manifold_test_utils.h ADDED
@@ -0,0 +1,328 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2022 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+
31
+ #include <cmath>
32
+ #include <limits>
33
+ #include <memory>
34
+
35
+ #include "ceres/dynamic_numeric_diff_cost_function.h"
36
+ #include "ceres/internal/eigen.h"
37
+ #include "ceres/manifold.h"
38
+ #include "ceres/numeric_diff_options.h"
39
+ #include "ceres/types.h"
40
+ #include "gmock/gmock.h"
41
+ #include "gtest/gtest.h"
42
+
43
+ namespace ceres {
44
+
45
+ // Matchers and macros for help with testing Manifold objects.
46
+ //
47
+ // Testing a Manifold has two parts.
48
+ //
49
+ // 1. Checking that Manifold::Plus is correctly defined. This requires per
50
+ // manifold tests.
51
+ //
52
+ // 2. The other methods of the manifold have mathematical properties that make
53
+ // it compatible with Plus, as described in:
54
+ //
55
+ // "Integrating Generic Sensor Fusion Algorithms with Sound State
56
+ // Representations through Encapsulation of Manifolds"
57
+ // By C. Hertzberg, R. Wagner, U. Frese and L. Schroder
58
+ // https://arxiv.org/pdf/1107.1119.pdf
59
+ //
60
+ // These tests are implemented using generic matchers defined below which can
61
+ // all be called by the macro EXPECT_THAT_MANIFOLD_INVARIANTS_HOLD(manifold, x,
62
+ // delta, y, tolerance). See manifold_test.cc for example usage.
63
+
64
+ // Checks that the invariant Plus(x, 0) == x holds.
65
+ MATCHER_P2(XPlusZeroIsXAt, x, tolerance, "") {
66
+ const int ambient_size = arg.AmbientSize();
67
+ const int tangent_size = arg.TangentSize();
68
+
69
+ Vector actual = Vector::Zero(ambient_size);
70
+ Vector zero = Vector::Zero(tangent_size);
71
+ EXPECT_TRUE(arg.Plus(x.data(), zero.data(), actual.data()));
72
+ const double n = (actual - x).norm();
73
+ const double d = x.norm();
74
+ const double diffnorm = (d == 0.0) ? n : (n / d);
75
+ if (diffnorm > tolerance) {
76
+ *result_listener << "\nexpected (x): " << x.transpose()
77
+ << "\nactual: " << actual.transpose()
78
+ << "\ndiffnorm: " << diffnorm;
79
+ return false;
80
+ }
81
+ return true;
82
+ }
83
+
84
+ // Checks that the invariant Minus(x, x) == 0 holds.
85
+ MATCHER_P2(XMinusXIsZeroAt, x, tolerance, "") {
86
+ const int tangent_size = arg.TangentSize();
87
+ Vector actual = Vector::Zero(tangent_size);
88
+ EXPECT_TRUE(arg.Minus(x.data(), x.data(), actual.data()));
89
+ const double diffnorm = actual.norm();
90
+ if (diffnorm > tolerance) {
91
+ *result_listener << "\nx: " << x.transpose() //
92
+ << "\nexpected: 0 0 0"
93
+ << "\nactual: " << actual.transpose()
94
+ << "\ndiffnorm: " << diffnorm;
95
+ return false;
96
+ }
97
+ return true;
98
+ }
99
+
100
+ // Helper struct to curry Plus(x, .) so that it can be numerically
101
+ // differentiated.
102
+ struct PlusFunctor {
103
+ PlusFunctor(const Manifold& manifold, const double* x)
104
+ : manifold(manifold), x(x) {}
105
+ bool operator()(double const* const* parameters, double* x_plus_delta) const {
106
+ return manifold.Plus(x, parameters[0], x_plus_delta);
107
+ }
108
+
109
+ const Manifold& manifold;
110
+ const double* x;
111
+ };
112
+
113
+ // Checks that the output of PlusJacobian matches the one obtained by
114
+ // numerically evaluating D_2 Plus(x,0).
115
+ MATCHER_P2(HasCorrectPlusJacobianAt, x, tolerance, "") {
116
+ const int ambient_size = arg.AmbientSize();
117
+ const int tangent_size = arg.TangentSize();
118
+
119
+ NumericDiffOptions options;
120
+ options.ridders_relative_initial_step_size = 1e-4;
121
+
122
+ DynamicNumericDiffCostFunction<PlusFunctor, RIDDERS> cost_function(
123
+ new PlusFunctor(arg, x.data()), TAKE_OWNERSHIP, options);
124
+ cost_function.AddParameterBlock(tangent_size);
125
+ cost_function.SetNumResiduals(ambient_size);
126
+
127
+ Vector zero = Vector::Zero(tangent_size);
128
+ double* parameters[1] = {zero.data()};
129
+
130
+ Vector x_plus_zero = Vector::Zero(ambient_size);
131
+ Matrix expected = Matrix::Zero(ambient_size, tangent_size);
132
+ double* jacobians[1] = {expected.data()};
133
+
134
+ EXPECT_TRUE(
135
+ cost_function.Evaluate(parameters, x_plus_zero.data(), jacobians));
136
+
137
+ Matrix actual = Matrix::Random(ambient_size, tangent_size);
138
+ EXPECT_TRUE(arg.PlusJacobian(x.data(), actual.data()));
139
+
140
+ const double n = (actual - expected).norm();
141
+ const double d = expected.norm();
142
+ const double diffnorm = (d == 0.0) ? n : n / d;
143
+ if (diffnorm > tolerance) {
144
+ *result_listener << "\nx: " << x.transpose() << "\nexpected: \n"
145
+ << expected << "\nactual:\n"
146
+ << actual << "\ndiff:\n"
147
+ << expected - actual << "\ndiffnorm : " << diffnorm;
148
+ return false;
149
+ }
150
+ return true;
151
+ }
152
+
153
+ // Checks that the invariant Minus(Plus(x, delta), x) == delta holds.
154
+ MATCHER_P3(MinusPlusIsIdentityAt, x, delta, tolerance, "") {
155
+ const int ambient_size = arg.AmbientSize();
156
+ const int tangent_size = arg.TangentSize();
157
+ Vector x_plus_delta = Vector::Zero(ambient_size);
158
+ EXPECT_TRUE(arg.Plus(x.data(), delta.data(), x_plus_delta.data()));
159
+ Vector actual = Vector::Zero(tangent_size);
160
+ EXPECT_TRUE(arg.Minus(x_plus_delta.data(), x.data(), actual.data()));
161
+
162
+ const double n = (actual - delta).norm();
163
+ const double d = delta.norm();
164
+ const double diffnorm = (d == 0.0) ? n : (n / d);
165
+ if (diffnorm > tolerance) {
166
+ *result_listener << "\nx: " << x.transpose()
167
+ << "\nexpected: " << delta.transpose()
168
+ << "\nactual:" << actual.transpose()
169
+ << "\ndiff:" << (delta - actual).transpose()
170
+ << "\ndiffnorm: " << diffnorm;
171
+ return false;
172
+ }
173
+ return true;
174
+ }
175
+
176
+ // Checks that the invariant Plus(Minus(y, x), x) == y holds.
177
+ MATCHER_P3(PlusMinusIsIdentityAt, x, y, tolerance, "") {
178
+ const int ambient_size = arg.AmbientSize();
179
+ const int tangent_size = arg.TangentSize();
180
+
181
+ Vector y_minus_x = Vector::Zero(tangent_size);
182
+ EXPECT_TRUE(arg.Minus(y.data(), x.data(), y_minus_x.data()));
183
+
184
+ Vector actual = Vector::Zero(ambient_size);
185
+ EXPECT_TRUE(arg.Plus(x.data(), y_minus_x.data(), actual.data()));
186
+
187
+ const double n = (actual - y).norm();
188
+ const double d = y.norm();
189
+ const double diffnorm = (d == 0.0) ? n : (n / d);
190
+ if (diffnorm > tolerance) {
191
+ *result_listener << "\nx: " << x.transpose()
192
+ << "\nexpected: " << y.transpose()
193
+ << "\nactual:" << actual.transpose()
194
+ << "\ndiff:" << (y - actual).transpose()
195
+ << "\ndiffnorm: " << diffnorm;
196
+ return false;
197
+ }
198
+ return true;
199
+ }
200
+
201
+ // Helper struct to curry Minus(., x) so that it can be numerically
202
+ // differentiated.
203
+ struct MinusFunctor {
204
+ MinusFunctor(const Manifold& manifold, const double* x)
205
+ : manifold(manifold), x(x) {}
206
+ bool operator()(double const* const* parameters, double* y_minus_x) const {
207
+ return manifold.Minus(parameters[0], x, y_minus_x);
208
+ }
209
+
210
+ const Manifold& manifold;
211
+ const double* x;
212
+ };
213
+
214
+ // Checks that the output of MinusJacobian matches the one obtained by
215
+ // numerically evaluating D_1 Minus(x,x).
216
+ MATCHER_P2(HasCorrectMinusJacobianAt, x, tolerance, "") {
217
+ const int ambient_size = arg.AmbientSize();
218
+ const int tangent_size = arg.TangentSize();
219
+
220
+ Vector y = x;
221
+ Vector y_minus_x = Vector::Zero(tangent_size);
222
+
223
+ NumericDiffOptions options;
224
+ options.ridders_relative_initial_step_size = 1e-4;
225
+ DynamicNumericDiffCostFunction<MinusFunctor, RIDDERS> cost_function(
226
+ new MinusFunctor(arg, x.data()), TAKE_OWNERSHIP, options);
227
+ cost_function.AddParameterBlock(ambient_size);
228
+ cost_function.SetNumResiduals(tangent_size);
229
+
230
+ double* parameters[1] = {y.data()};
231
+
232
+ Matrix expected = Matrix::Zero(tangent_size, ambient_size);
233
+ double* jacobians[1] = {expected.data()};
234
+
235
+ EXPECT_TRUE(cost_function.Evaluate(parameters, y_minus_x.data(), jacobians));
236
+
237
+ Matrix actual = Matrix::Random(tangent_size, ambient_size);
238
+ EXPECT_TRUE(arg.MinusJacobian(x.data(), actual.data()));
239
+
240
+ const double n = (actual - expected).norm();
241
+ const double d = expected.norm();
242
+ const double diffnorm = (d == 0.0) ? n : (n / d);
243
+ if (diffnorm > tolerance) {
244
+ *result_listener << "\nx: " << x.transpose() << "\nexpected: \n"
245
+ << expected << "\nactual:\n"
246
+ << actual << "\ndiff:\n"
247
+ << expected - actual << "\ndiffnorm: " << diffnorm;
248
+ return false;
249
+ }
250
+ return true;
251
+ }
252
+
253
+ // Checks that D_delta Minus(Plus(x, delta), x) at delta = 0 is an identity
254
+ // matrix.
255
+ MATCHER_P2(MinusPlusJacobianIsIdentityAt, x, tolerance, "") {
256
+ const int ambient_size = arg.AmbientSize();
257
+ const int tangent_size = arg.TangentSize();
258
+
259
+ Matrix plus_jacobian(ambient_size, tangent_size);
260
+ EXPECT_TRUE(arg.PlusJacobian(x.data(), plus_jacobian.data()));
261
+ Matrix minus_jacobian(tangent_size, ambient_size);
262
+ EXPECT_TRUE(arg.MinusJacobian(x.data(), minus_jacobian.data()));
263
+
264
+ const Matrix actual = minus_jacobian * plus_jacobian;
265
+ const Matrix expected = Matrix::Identity(tangent_size, tangent_size);
266
+
267
+ const double n = (actual - expected).norm();
268
+ const double d = expected.norm();
269
+ const double diffnorm = n / d;
270
+ if (diffnorm > tolerance) {
271
+ *result_listener << "\nx: " << x.transpose() << "\nexpected: \n"
272
+ << expected << "\nactual:\n"
273
+ << actual << "\ndiff:\n"
274
+ << expected - actual << "\ndiffnorm: " << diffnorm;
275
+
276
+ return false;
277
+ }
278
+ return true;
279
+ }
280
+
281
+ // Verify that the output of RightMultiplyByPlusJacobian is ambient_matrix *
282
+ // plus_jacobian.
283
+ MATCHER_P2(HasCorrectRightMultiplyByPlusJacobianAt, x, tolerance, "") {
284
+ const int ambient_size = arg.AmbientSize();
285
+ const int tangent_size = arg.TangentSize();
286
+
287
+ constexpr int kMinNumRows = 0;
288
+ constexpr int kMaxNumRows = 3;
289
+ for (int num_rows = kMinNumRows; num_rows <= kMaxNumRows; ++num_rows) {
290
+ Matrix plus_jacobian = Matrix::Random(ambient_size, tangent_size);
291
+ EXPECT_TRUE(arg.PlusJacobian(x.data(), plus_jacobian.data()));
292
+
293
+ Matrix ambient_matrix = Matrix::Random(num_rows, ambient_size);
294
+ Matrix expected = ambient_matrix * plus_jacobian;
295
+
296
+ Matrix actual = Matrix::Random(num_rows, tangent_size);
297
+ EXPECT_TRUE(arg.RightMultiplyByPlusJacobian(
298
+ x.data(), num_rows, ambient_matrix.data(), actual.data()));
299
+ const double n = (actual - expected).norm();
300
+ const double d = expected.norm();
301
+ const double diffnorm = (d == 0.0) ? n : (n / d);
302
+ if (diffnorm > tolerance) {
303
+ *result_listener << "\nx: " << x.transpose() << "\nambient_matrix : \n"
304
+ << ambient_matrix << "\nplus_jacobian : \n"
305
+ << plus_jacobian << "\nexpected: \n"
306
+ << expected << "\nactual:\n"
307
+ << actual << "\ndiff:\n"
308
+ << expected - actual << "\ndiffnorm : " << diffnorm;
309
+ return false;
310
+ }
311
+ }
312
+ return true;
313
+ }
314
+
315
+ #define EXPECT_THAT_MANIFOLD_INVARIANTS_HOLD(manifold, x, delta, y, tolerance) \
316
+ Vector zero_tangent = Vector::Zero(manifold.TangentSize()); \
317
+ EXPECT_THAT(manifold, XPlusZeroIsXAt(x, tolerance)); \
318
+ EXPECT_THAT(manifold, XMinusXIsZeroAt(x, tolerance)); \
319
+ EXPECT_THAT(manifold, MinusPlusIsIdentityAt(x, delta, tolerance)); \
320
+ EXPECT_THAT(manifold, MinusPlusIsIdentityAt(x, zero_tangent, tolerance)); \
321
+ EXPECT_THAT(manifold, PlusMinusIsIdentityAt(x, x, tolerance)); \
322
+ EXPECT_THAT(manifold, PlusMinusIsIdentityAt(x, y, tolerance)); \
323
+ EXPECT_THAT(manifold, HasCorrectPlusJacobianAt(x, tolerance)); \
324
+ EXPECT_THAT(manifold, HasCorrectMinusJacobianAt(x, tolerance)); \
325
+ EXPECT_THAT(manifold, MinusPlusJacobianIsIdentityAt(x, tolerance)); \
326
+ EXPECT_THAT(manifold, HasCorrectRightMultiplyByPlusJacobianAt(x, tolerance));
327
+
328
+ } // namespace ceres
ceres-v2/include/normal_prior.h ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Ceres Solver - A fast non-linear least squares minimizer
2
+ // Copyright 2019 Google Inc. All rights reserved.
3
+ // http://ceres-solver.org/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ //
8
+ // * Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ // * Redistributions in binary form must reproduce the above copyright notice,
11
+ // this list of conditions and the following disclaimer in the documentation
12
+ // and/or other materials provided with the distribution.
13
+ // * Neither the name of Google Inc. nor the names of its contributors may be
14
+ // used to endorse or promote products derived from this software without
15
+ // specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ // POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Author: sameeragarwal@google.com (Sameer Agarwal)
30
+ //
31
+ // Cost term that implements a prior on a parameter block using a
32
+ // normal distribution.
33
+
34
+ #ifndef CERES_PUBLIC_NORMAL_PRIOR_H_
35
+ #define CERES_PUBLIC_NORMAL_PRIOR_H_
36
+
37
+ #include "ceres/cost_function.h"
38
+ #include "ceres/internal/disable_warnings.h"
39
+ #include "ceres/internal/eigen.h"
40
+
41
+ namespace ceres {
42
+
43
+ // Implements a cost function of the form
44
+ //
45
+ // cost(x) = ||A(x - b)||^2
46
+ //
47
+ // where, the matrix A and the vector b are fixed and x is the
48
+ // variable. In case the user is interested in implementing a cost
49
+ // function of the form
50
+ //
51
+ // cost(x) = (x - mu)^T S^{-1} (x - mu)
52
+ //
53
+ // where, mu is a vector and S is a covariance matrix, then, A =
54
+ // S^{-1/2}, i.e the matrix A is the square root of the inverse of the
55
+ // covariance, also known as the stiffness matrix. There are however
56
+ // no restrictions on the shape of A. It is free to be rectangular,
57
+ // which would be the case if the covariance matrix S is rank
58
+ // deficient.
59
+
60
+ class CERES_EXPORT NormalPrior final : public CostFunction {
61
+ public:
62
+ // Check that the number of rows in the vector b are the same as the
63
+ // number of columns in the matrix A, crash otherwise.
64
+ NormalPrior(const Matrix& A, const Vector& b);
65
+ bool Evaluate(double const* const* parameters,
66
+ double* residuals,
67
+ double** jacobians) const override;
68
+
69
+ private:
70
+ Matrix A_;
71
+ Vector b_;
72
+ };
73
+
74
+ } // namespace ceres
75
+
76
+ #include "ceres/internal/reenable_warnings.h"
77
+
78
+ #endif // CERES_PUBLIC_NORMAL_PRIOR_H_