blob: 593c3718bf51b43bce7f4ece71d788e2cc9dffde [file] [log] [blame]
Sameer Agarwal2f0d7242013-01-18 13:11:32 -08001// Ceres Solver - A fast non-linear least squares minimizer
2// Copyright 2013 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: sameeragarwal@google.com (Sameer Agarwal)
30//
31// A wrapper class that takes a variadic functor evaluating a
32// function, numerically differentiates it and makes it available as a
33// templated functor so that it can be easily used as part of Ceres'
34// automatic differentiation framework.
35//
36// For example:
37//
38// For example, let us assume that
39//
40// struct IntrinsicProjection
41// IntrinsicProjection(const double* observations);
42// bool operator()(const double* calibration,
43// const double* point,
44// double* residuals);
45// };
46//
47// is a functor that implements the projection of a point in its local
48// coordinate system onto its image plane and subtracts it from the
49// observed point projection.
50//
51// Now we would like to compose the action of this functor with the
52// action of camera extrinsics, i.e., rotation and translation, which
53// is given by the following 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// To compose the extrinsics and intrinsics, we can construct a
62// CameraProjection functor as follows.
63//
64// struct CameraProjection {
65// typedef NumericDiffFunctor<IntrinsicProjection, CENTRAL, 2, 5, 3>
66// IntrinsicProjectionFunctor;
67//
68// CameraProjection(double* observation) {
69// intrinsic_projection_.reset(
70// new IntrinsicProjectionFunctor(observation)) {
71// }
72//
73// template <typename T>
74// bool operator(const T* rotation,
75// const T* translation,
76// const T* intrinsics,
77// const T* point,
78// T* residuals) const {
79// T transformed_point[3];
80// RotateAndTranslatePoint(rotation, translation, point, transformed_point);
81// return (*intrinsic_projection_)(intrinsics, transformed_point, residual);
82// }
83//
84// private:
85// scoped_ptr<IntrinsicProjectionFunctor> intrinsic_projection_;
86// };
87//
88// Here, we made the choice of using CENTRAL differences to compute
89// the jacobian of IntrinsicProjection.
90//
91// Now, we are ready to construct an automatically differentiated cost
92// function as
93//
94// CostFunction* cost_function =
95// new AutoDiffCostFunction<CameraProjection, 2, 3, 3, 5>(
96// new CameraProjection(observations));
97//
98// cost_function now seamlessly integrates automatic differentiation
99// of RotateAndTranslatePoint with a numerically differentiated
100// version of IntrinsicProjection.
101
Sameer Agarwal509f68c2013-02-20 01:39:03 -0800102#ifndef CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_
103#define CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_
104
Sameer Agarwal2f0d7242013-01-18 13:11:32 -0800105#include "ceres/numeric_diff_cost_function.h"
106#include "ceres/types.h"
107#include "ceres/cost_function_to_functor.h"
108
109namespace ceres {
110
111template<typename Functor,
112 NumericDiffMethod kMethod = CENTRAL,
113 int kNumResiduals = 0,
114 int N0 = 0, int N1 = 0 , int N2 = 0, int N3 = 0, int N4 = 0,
115 int N5 = 0, int N6 = 0 , int N7 = 0, int N8 = 0, int N9 = 0>
116class NumericDiffFunctor {
117 public:
118 // relative_step_size controls the step size used by the numeric
119 // differentiation process.
Sameer Agarwal509f68c2013-02-20 01:39:03 -0800120 explicit NumericDiffFunctor(double relative_step_size = 1e-6)
121 : functor_(
122 new NumericDiffCostFunction<Functor,
123 kMethod,
124 kNumResiduals,
125 N0, N1, N2, N3, N4,
126 N5, N6, N7, N8, N9>(new Functor,
127 relative_step_size)) {
Sameer Agarwal2f0d7242013-01-18 13:11:32 -0800128 }
129
130 NumericDiffFunctor(Functor* functor, double relative_step_size = 1e-6)
131 : functor_(new NumericDiffCostFunction<Functor,
132 kMethod,
133 kNumResiduals,
134 N0, N1, N2, N3, N4,
135 N5, N6, N7, N8, N9>(
136 functor, relative_step_size)) {
137 }
138
139 bool operator()(const double* x0, double* residuals) const {
Sameer Agarwal977be7c2013-01-26 16:01:54 -0800140 return functor_(x0, residuals);
Sameer Agarwal2f0d7242013-01-18 13:11:32 -0800141 }
142
143 bool operator()(const double* x0,
144 const double* x1,
145 double* residuals) const {
146 return functor_(x0, x1, residuals);
147 }
148
149 bool operator()(const double* x0,
150 const double* x1,
151 const double* x2,
152 double* residuals) const {
153 return functor_(x0, x1, x2, residuals);
154 }
155
156 bool operator()(const double* x0,
157 const double* x1,
158 const double* x2,
159 const double* x3,
160 double* residuals) const {
161 return functor_(x0, x1, x2, x3, residuals);
162 }
163
164 bool operator()(const double* x0,
165 const double* x1,
166 const double* x2,
167 const double* x3,
168 const double* x4,
169 double* residuals) const {
170 return functor_(x0, x1, x2, x3, x4, residuals);
171 }
172
173 bool operator()(const double* x0,
174 const double* x1,
175 const double* x2,
176 const double* x3,
177 const double* x4,
178 const double* x5,
179 double* residuals) const {
180 return functor_(x0, x1, x2, x3, x4, x5, residuals);
181 }
182
183 bool operator()(const double* x0,
184 const double* x1,
185 const double* x2,
186 const double* x3,
187 const double* x4,
188 const double* x5,
189 const double* x6,
190 double* residuals) const {
191 return functor_(x0, x1, x2, x3, x4, x5, x6, residuals);
192 }
193
194 bool operator()(const double* x0,
195 const double* x1,
196 const double* x2,
197 const double* x3,
198 const double* x4,
199 const double* x5,
200 const double* x6,
201 const double* x7,
202 double* residuals) const {
203 return functor_(x0, x1, x2, x3, x4, x5, x6, x7, residuals);
204 }
205
206 bool operator()(const double* x0,
207 const double* x1,
208 const double* x2,
209 const double* x3,
210 const double* x4,
211 const double* x5,
212 const double* x6,
213 const double* x7,
214 const double* x8,
215 double* residuals) const {
216 return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, residuals);
217 }
218
219 bool operator()(const double* x0,
220 const double* x1,
221 const double* x2,
222 const double* x3,
223 const double* x4,
224 const double* x5,
225 const double* x6,
226 const double* x7,
227 const double* x8,
228 const double* x9,
229 double* residuals) const {
230 return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, residuals);
231 }
232
233 template <typename T>
234 bool operator()(const T* x0, T* residuals) const {
Sameer Agarwal977be7c2013-01-26 16:01:54 -0800235 return functor_(x0, residuals);
Sameer Agarwal2f0d7242013-01-18 13:11:32 -0800236 }
237
238 template <typename T>
239 bool operator()(const T* x0,
240 const T* x1,
241 T* residuals) const {
242 return functor_(x0, x1, residuals);
243 }
244
245 template <typename T>
246 bool operator()(const T* x0,
247 const T* x1,
248 const T* x2,
249 T* residuals) const {
250 return functor_(x0, x1, x2, residuals);
251 }
252
253 template <typename T>
254 bool operator()(const T* x0,
255 const T* x1,
256 const T* x2,
257 const T* x3,
258 T* residuals) const {
259 return functor_(x0, x1, x2, x3, residuals);
260 }
261
262 template <typename T>
263 bool operator()(const T* x0,
264 const T* x1,
265 const T* x2,
266 const T* x3,
267 const T* x4,
268 T* residuals) const {
269 return functor_(x0, x1, x2, x3, x4, residuals);
270 }
271
272 template <typename T>
273 bool operator()(const T* x0,
274 const T* x1,
275 const T* x2,
276 const T* x3,
277 const T* x4,
278 const T* x5,
279 T* residuals) const {
280 return functor_(x0, x1, x2, x3, x4, x5, residuals);
281 }
282
283 template <typename T>
284 bool operator()(const T* x0,
285 const T* x1,
286 const T* x2,
287 const T* x3,
288 const T* x4,
289 const T* x5,
290 const T* x6,
291 T* residuals) const {
292 return functor_(x0, x1, x2, x3, x4, x5, x6, residuals);
293 }
294
295 template <typename T>
296 bool operator()(const T* x0,
297 const T* x1,
298 const T* x2,
299 const T* x3,
300 const T* x4,
301 const T* x5,
302 const T* x6,
303 const T* x7,
304 T* residuals) const {
305 return functor_(x0, x1, x2, x3, x4, x5, x6, x7, residuals);
306 }
307
308 template <typename T>
309 bool operator()(const T* x0,
310 const T* x1,
311 const T* x2,
312 const T* x3,
313 const T* x4,
314 const T* x5,
315 const T* x6,
316 const T* x7,
317 const T* x8,
318 T* residuals) const {
319 return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, residuals);
320 }
321
322 template <typename T>
323 bool operator()(const T* x0,
324 const T* x1,
325 const T* x2,
326 const T* x3,
327 const T* x4,
328 const T* x5,
329 const T* x6,
330 const T* x7,
331 const T* x8,
332 const T* x9,
333 T* residuals) const {
334 return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, residuals);
335 }
336
337
338 private:
339 CostFunctionToFunctor<kNumResiduals,
340 N0, N1, N2, N3, N4,
341 N5, N6, N7, N8, N9> functor_;
Sameer Agarwal2f0d7242013-01-18 13:11:32 -0800342};
343
344} // namespace ceres
Sameer Agarwal509f68c2013-02-20 01:39:03 -0800345
346#endif // CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_