Imported Upstream version ceres 1.13.0
[platform/upstream/ceres-solver.git] / include / ceres / cost_function_to_functor.h
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 // 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 //      virtual bool Evaluate(double const* const* parameters,
42 //                            double* residuals,
43 //                            double** jacobians) const;
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 // either via analytic or numerical differentiation can compute its
50 // jacobians.
51 //
52 // Now we would like to compose the action of this CostFunction with
53 // the action of camera extrinsics, i.e., rotation and
54 // translation. Say we have a templated function
55 //
56 //   template<typename T>
57 //   void RotateAndTranslatePoint(const T* rotation,
58 //                                const T* translation,
59 //                                const T* point,
60 //                                T* result);
61 //
62 // Then we can now do the following,
63 //
64 // struct CameraProjection {
65 //   CameraProjection(const double* observation)
66 //       : intrinsic_projection_(new IntrinsicProjection(observation)) {
67 //   }
68 //   template <typename T>
69 //   bool operator()(const T* rotation,
70 //                   const T* translation,
71 //                   const T* intrinsics,
72 //                   const T* point,
73 //                   T* residual) const {
74 //     T transformed_point[3];
75 //     RotateAndTranslatePoint(rotation, translation, point, transformed_point);
76 //
77 //     // Note that we call intrinsic_projection_, just like it was
78 //     // any other templated functor.
79 //
80 //     return intrinsic_projection_(intrinsics, transformed_point, residual);
81 //   }
82 //
83 //  private:
84 //   CostFunctionToFunctor<2,5,3> intrinsic_projection_;
85 // };
86
87 #ifndef CERES_PUBLIC_COST_FUNCTION_TO_FUNCTOR_H_
88 #define CERES_PUBLIC_COST_FUNCTION_TO_FUNCTOR_H_
89
90 #include <numeric>
91 #include <vector>
92
93 #include "ceres/cost_function.h"
94 #include "ceres/dynamic_cost_function_to_functor.h"
95 #include "ceres/internal/fixed_array.h"
96 #include "ceres/internal/port.h"
97 #include "ceres/internal/scoped_ptr.h"
98
99 namespace ceres {
100
101 template <int kNumResiduals,
102           int N0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0,
103           int N5 = 0, int N6 = 0, int N7 = 0, int N8 = 0, int N9 = 0>
104 class CostFunctionToFunctor {
105  public:
106   // Takes ownership of cost_function.
107   explicit CostFunctionToFunctor(CostFunction* cost_function)
108       : cost_functor_(cost_function) {
109     CHECK_NOTNULL(cost_function);
110     CHECK(kNumResiduals > 0 || kNumResiduals == DYNAMIC);
111
112     // This block breaks the 80 column rule to keep it somewhat readable.
113     CHECK((!N1 && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
114           ((N1 > 0) && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
115           ((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||                                    // NOLINT
116           ((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||                               // NOLINT
117           ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5 && !N6 && !N7 && !N8 && !N9) ||                          // NOLINT
118           ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && !N6 && !N7 && !N8 && !N9) ||                     // NOLINT
119           ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && !N7 && !N8 && !N9) ||                // NOLINT
120           ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && !N8 && !N9) ||           // NOLINT
121           ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && !N9) ||      // NOLINT
122           ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && (N9 > 0)))   // NOLINT
123         << "Zero block cannot precede a non-zero block. Block sizes are "
124         << "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", "
125         << N3 << ", " << N4 << ", " << N5 << ", " << N6 << ", " << N7 << ", "
126         << N8 << ", " << N9;
127
128     const std::vector<int32>& parameter_block_sizes =
129         cost_function->parameter_block_sizes();
130     const int num_parameter_blocks =
131         (N0 > 0) + (N1 > 0) + (N2 > 0) + (N3 > 0) + (N4 > 0) +
132         (N5 > 0) + (N6 > 0) + (N7 > 0) + (N8 > 0) + (N9 > 0);
133     CHECK_EQ(static_cast<int>(parameter_block_sizes.size()),
134              num_parameter_blocks);
135
136     CHECK_EQ(N0, parameter_block_sizes[0]);
137     if (parameter_block_sizes.size() > 1) CHECK_EQ(N1, parameter_block_sizes[1]);  // NOLINT
138     if (parameter_block_sizes.size() > 2) CHECK_EQ(N2, parameter_block_sizes[2]);  // NOLINT
139     if (parameter_block_sizes.size() > 3) CHECK_EQ(N3, parameter_block_sizes[3]);  // NOLINT
140     if (parameter_block_sizes.size() > 4) CHECK_EQ(N4, parameter_block_sizes[4]);  // NOLINT
141     if (parameter_block_sizes.size() > 5) CHECK_EQ(N5, parameter_block_sizes[5]);  // NOLINT
142     if (parameter_block_sizes.size() > 6) CHECK_EQ(N6, parameter_block_sizes[6]);  // NOLINT
143     if (parameter_block_sizes.size() > 7) CHECK_EQ(N7, parameter_block_sizes[7]);  // NOLINT
144     if (parameter_block_sizes.size() > 8) CHECK_EQ(N8, parameter_block_sizes[8]);  // NOLINT
145     if (parameter_block_sizes.size() > 9) CHECK_EQ(N9, parameter_block_sizes[9]);  // NOLINT
146
147     CHECK_EQ(accumulate(parameter_block_sizes.begin(),
148                         parameter_block_sizes.end(), 0),
149              N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9);
150   }
151
152   bool operator()(const double* x0, double* residuals) const {
153     CHECK_NE(N0, 0);
154     CHECK_EQ(N1, 0);
155     CHECK_EQ(N2, 0);
156     CHECK_EQ(N3, 0);
157     CHECK_EQ(N4, 0);
158     CHECK_EQ(N5, 0);
159     CHECK_EQ(N6, 0);
160     CHECK_EQ(N7, 0);
161     CHECK_EQ(N8, 0);
162     CHECK_EQ(N9, 0);
163
164     return cost_functor_(&x0, residuals);
165   }
166
167   bool operator()(const double* x0,
168                   const double* x1,
169                   double* residuals) const {
170     CHECK_NE(N0, 0);
171     CHECK_NE(N1, 0);
172     CHECK_EQ(N2, 0);
173     CHECK_EQ(N3, 0);
174     CHECK_EQ(N4, 0);
175     CHECK_EQ(N5, 0);
176     CHECK_EQ(N6, 0);
177     CHECK_EQ(N7, 0);
178     CHECK_EQ(N8, 0);
179     CHECK_EQ(N9, 0);
180     internal::FixedArray<const double*> parameter_blocks(2);
181     parameter_blocks[0] = x0;
182     parameter_blocks[1] = x1;
183     return cost_functor_(parameter_blocks.get(), residuals);
184   }
185
186   bool operator()(const double* x0,
187                   const double* x1,
188                   const double* x2,
189                   double* residuals) const {
190     CHECK_NE(N0, 0);
191     CHECK_NE(N1, 0);
192     CHECK_NE(N2, 0);
193     CHECK_EQ(N3, 0);
194     CHECK_EQ(N4, 0);
195     CHECK_EQ(N5, 0);
196     CHECK_EQ(N6, 0);
197     CHECK_EQ(N7, 0);
198     CHECK_EQ(N8, 0);
199     CHECK_EQ(N9, 0);
200     internal::FixedArray<const double*> parameter_blocks(3);
201     parameter_blocks[0] = x0;
202     parameter_blocks[1] = x1;
203     parameter_blocks[2] = x2;
204     return cost_functor_(parameter_blocks.get(), residuals);
205   }
206
207   bool operator()(const double* x0,
208                   const double* x1,
209                   const double* x2,
210                   const double* x3,
211                   double* residuals) const {
212     CHECK_NE(N0, 0);
213     CHECK_NE(N1, 0);
214     CHECK_NE(N2, 0);
215     CHECK_NE(N3, 0);
216     CHECK_EQ(N4, 0);
217     CHECK_EQ(N5, 0);
218     CHECK_EQ(N6, 0);
219     CHECK_EQ(N7, 0);
220     CHECK_EQ(N8, 0);
221     CHECK_EQ(N9, 0);
222     internal::FixedArray<const double*> parameter_blocks(4);
223     parameter_blocks[0] = x0;
224     parameter_blocks[1] = x1;
225     parameter_blocks[2] = x2;
226     parameter_blocks[3] = x3;
227     return cost_functor_(parameter_blocks.get(), residuals);
228   }
229
230   bool operator()(const double* x0,
231                   const double* x1,
232                   const double* x2,
233                   const double* x3,
234                   const double* x4,
235                   double* residuals) const {
236     CHECK_NE(N0, 0);
237     CHECK_NE(N1, 0);
238     CHECK_NE(N2, 0);
239     CHECK_NE(N3, 0);
240     CHECK_NE(N4, 0);
241     CHECK_EQ(N5, 0);
242     CHECK_EQ(N6, 0);
243     CHECK_EQ(N7, 0);
244     CHECK_EQ(N8, 0);
245     CHECK_EQ(N9, 0);
246     internal::FixedArray<const double*> parameter_blocks(5);
247     parameter_blocks[0] = x0;
248     parameter_blocks[1] = x1;
249     parameter_blocks[2] = x2;
250     parameter_blocks[3] = x3;
251     parameter_blocks[4] = x4;
252     return cost_functor_(parameter_blocks.get(), residuals);
253   }
254
255   bool operator()(const double* x0,
256                   const double* x1,
257                   const double* x2,
258                   const double* x3,
259                   const double* x4,
260                   const double* x5,
261                   double* residuals) const {
262     CHECK_NE(N0, 0);
263     CHECK_NE(N1, 0);
264     CHECK_NE(N2, 0);
265     CHECK_NE(N3, 0);
266     CHECK_NE(N4, 0);
267     CHECK_NE(N5, 0);
268     CHECK_EQ(N6, 0);
269     CHECK_EQ(N7, 0);
270     CHECK_EQ(N8, 0);
271     CHECK_EQ(N9, 0);
272     internal::FixedArray<const double*> parameter_blocks(6);
273     parameter_blocks[0] = x0;
274     parameter_blocks[1] = x1;
275     parameter_blocks[2] = x2;
276     parameter_blocks[3] = x3;
277     parameter_blocks[4] = x4;
278     parameter_blocks[5] = x5;
279     return cost_functor_(parameter_blocks.get(), residuals);
280   }
281
282   bool operator()(const double* x0,
283                   const double* x1,
284                   const double* x2,
285                   const double* x3,
286                   const double* x4,
287                   const double* x5,
288                   const double* x6,
289                   double* residuals) const {
290     CHECK_NE(N0, 0);
291     CHECK_NE(N1, 0);
292     CHECK_NE(N2, 0);
293     CHECK_NE(N3, 0);
294     CHECK_NE(N4, 0);
295     CHECK_NE(N5, 0);
296     CHECK_NE(N6, 0);
297     CHECK_EQ(N7, 0);
298     CHECK_EQ(N8, 0);
299     CHECK_EQ(N9, 0);
300     internal::FixedArray<const double*> parameter_blocks(7);
301     parameter_blocks[0] = x0;
302     parameter_blocks[1] = x1;
303     parameter_blocks[2] = x2;
304     parameter_blocks[3] = x3;
305     parameter_blocks[4] = x4;
306     parameter_blocks[5] = x5;
307     parameter_blocks[6] = x6;
308     return cost_functor_(parameter_blocks.get(), residuals);
309   }
310
311   bool operator()(const double* x0,
312                   const double* x1,
313                   const double* x2,
314                   const double* x3,
315                   const double* x4,
316                   const double* x5,
317                   const double* x6,
318                   const double* x7,
319                   double* residuals) const {
320     CHECK_NE(N0, 0);
321     CHECK_NE(N1, 0);
322     CHECK_NE(N2, 0);
323     CHECK_NE(N3, 0);
324     CHECK_NE(N4, 0);
325     CHECK_NE(N5, 0);
326     CHECK_NE(N6, 0);
327     CHECK_NE(N7, 0);
328     CHECK_EQ(N8, 0);
329     CHECK_EQ(N9, 0);
330     internal::FixedArray<const double*> parameter_blocks(8);
331     parameter_blocks[0] = x0;
332     parameter_blocks[1] = x1;
333     parameter_blocks[2] = x2;
334     parameter_blocks[3] = x3;
335     parameter_blocks[4] = x4;
336     parameter_blocks[5] = x5;
337     parameter_blocks[6] = x6;
338     parameter_blocks[7] = x7;
339     return cost_functor_(parameter_blocks.get(), residuals);
340   }
341
342   bool operator()(const double* x0,
343                   const double* x1,
344                   const double* x2,
345                   const double* x3,
346                   const double* x4,
347                   const double* x5,
348                   const double* x6,
349                   const double* x7,
350                   const double* x8,
351                   double* residuals) const {
352     CHECK_NE(N0, 0);
353     CHECK_NE(N1, 0);
354     CHECK_NE(N2, 0);
355     CHECK_NE(N3, 0);
356     CHECK_NE(N4, 0);
357     CHECK_NE(N5, 0);
358     CHECK_NE(N6, 0);
359     CHECK_NE(N7, 0);
360     CHECK_NE(N8, 0);
361     CHECK_EQ(N9, 0);
362     internal::FixedArray<const double*> parameter_blocks(9);
363     parameter_blocks[0] = x0;
364     parameter_blocks[1] = x1;
365     parameter_blocks[2] = x2;
366     parameter_blocks[3] = x3;
367     parameter_blocks[4] = x4;
368     parameter_blocks[5] = x5;
369     parameter_blocks[6] = x6;
370     parameter_blocks[7] = x7;
371     parameter_blocks[8] = x8;
372     return cost_functor_(parameter_blocks.get(), residuals);
373   }
374
375   bool operator()(const double* x0,
376                   const double* x1,
377                   const double* x2,
378                   const double* x3,
379                   const double* x4,
380                   const double* x5,
381                   const double* x6,
382                   const double* x7,
383                   const double* x8,
384                   const double* x9,
385                   double* residuals) const {
386     CHECK_NE(N0, 0);
387     CHECK_NE(N1, 0);
388     CHECK_NE(N2, 0);
389     CHECK_NE(N3, 0);
390     CHECK_NE(N4, 0);
391     CHECK_NE(N5, 0);
392     CHECK_NE(N6, 0);
393     CHECK_NE(N7, 0);
394     CHECK_NE(N8, 0);
395     CHECK_NE(N9, 0);
396     internal::FixedArray<const double*> parameter_blocks(10);
397     parameter_blocks[0] = x0;
398     parameter_blocks[1] = x1;
399     parameter_blocks[2] = x2;
400     parameter_blocks[3] = x3;
401     parameter_blocks[4] = x4;
402     parameter_blocks[5] = x5;
403     parameter_blocks[6] = x6;
404     parameter_blocks[7] = x7;
405     parameter_blocks[8] = x8;
406     parameter_blocks[9] = x9;
407     return cost_functor_(parameter_blocks.get(), residuals);
408   }
409
410   template <typename JetT>
411   bool operator()(const JetT* x0, JetT* residuals) const {
412     CHECK_NE(N0, 0);
413     CHECK_EQ(N1, 0);
414     CHECK_EQ(N2, 0);
415     CHECK_EQ(N3, 0);
416     CHECK_EQ(N4, 0);
417     CHECK_EQ(N5, 0);
418     CHECK_EQ(N6, 0);
419     CHECK_EQ(N7, 0);
420     CHECK_EQ(N8, 0);
421     CHECK_EQ(N9, 0);
422     return cost_functor_(&x0, residuals);
423   }
424
425   template <typename JetT>
426   bool operator()(const JetT* x0,
427                   const JetT* x1,
428                   JetT* residuals) const {
429     CHECK_NE(N0, 0);
430     CHECK_NE(N1, 0);
431     CHECK_EQ(N2, 0);
432     CHECK_EQ(N3, 0);
433     CHECK_EQ(N4, 0);
434     CHECK_EQ(N5, 0);
435     CHECK_EQ(N6, 0);
436     CHECK_EQ(N7, 0);
437     CHECK_EQ(N8, 0);
438     CHECK_EQ(N9, 0);
439     internal::FixedArray<const JetT*> jets(2);
440     jets[0] = x0;
441     jets[1] = x1;
442     return cost_functor_(jets.get(), residuals);
443   }
444
445   template <typename JetT>
446   bool operator()(const JetT* x0,
447                   const JetT* x1,
448                   const JetT* x2,
449                   JetT* residuals) const {
450     CHECK_NE(N0, 0);
451     CHECK_NE(N1, 0);
452     CHECK_NE(N2, 0);
453     CHECK_EQ(N3, 0);
454     CHECK_EQ(N4, 0);
455     CHECK_EQ(N5, 0);
456     CHECK_EQ(N6, 0);
457     CHECK_EQ(N7, 0);
458     CHECK_EQ(N8, 0);
459     CHECK_EQ(N9, 0);
460     internal::FixedArray<const JetT*> jets(3);
461     jets[0] = x0;
462     jets[1] = x1;
463     jets[2] = x2;
464     return cost_functor_(jets.get(), residuals);
465   }
466
467   template <typename JetT>
468   bool operator()(const JetT* x0,
469                   const JetT* x1,
470                   const JetT* x2,
471                   const JetT* x3,
472                   JetT* residuals) const {
473     CHECK_NE(N0, 0);
474     CHECK_NE(N1, 0);
475     CHECK_NE(N2, 0);
476     CHECK_NE(N3, 0);
477     CHECK_EQ(N4, 0);
478     CHECK_EQ(N5, 0);
479     CHECK_EQ(N6, 0);
480     CHECK_EQ(N7, 0);
481     CHECK_EQ(N8, 0);
482     CHECK_EQ(N9, 0);
483     internal::FixedArray<const JetT*> jets(4);
484     jets[0] = x0;
485     jets[1] = x1;
486     jets[2] = x2;
487     jets[3] = x3;
488     return cost_functor_(jets.get(), residuals);
489   }
490
491   template <typename JetT>
492   bool operator()(const JetT* x0,
493                   const JetT* x1,
494                   const JetT* x2,
495                   const JetT* x3,
496                   const JetT* x4,
497                   JetT* residuals) const {
498     CHECK_NE(N0, 0);
499     CHECK_NE(N1, 0);
500     CHECK_NE(N2, 0);
501     CHECK_NE(N3, 0);
502     CHECK_NE(N4, 0);
503     CHECK_EQ(N5, 0);
504     CHECK_EQ(N6, 0);
505     CHECK_EQ(N7, 0);
506     CHECK_EQ(N8, 0);
507     CHECK_EQ(N9, 0);
508     internal::FixedArray<const JetT*> jets(5);
509     jets[0] = x0;
510     jets[1] = x1;
511     jets[2] = x2;
512     jets[3] = x3;
513     jets[4] = x4;
514     return cost_functor_(jets.get(), residuals);
515   }
516
517   template <typename JetT>
518   bool operator()(const JetT* x0,
519                   const JetT* x1,
520                   const JetT* x2,
521                   const JetT* x3,
522                   const JetT* x4,
523                   const JetT* x5,
524                   JetT* residuals) const {
525     CHECK_NE(N0, 0);
526     CHECK_NE(N1, 0);
527     CHECK_NE(N2, 0);
528     CHECK_NE(N3, 0);
529     CHECK_NE(N4, 0);
530     CHECK_NE(N5, 0);
531     CHECK_EQ(N6, 0);
532     CHECK_EQ(N7, 0);
533     CHECK_EQ(N8, 0);
534     CHECK_EQ(N9, 0);
535     internal::FixedArray<const JetT*> jets(6);
536     jets[0] = x0;
537     jets[1] = x1;
538     jets[2] = x2;
539     jets[3] = x3;
540     jets[4] = x4;
541     jets[5] = x5;
542     return cost_functor_(jets.get(), residuals);
543   }
544
545   template <typename JetT>
546   bool operator()(const JetT* x0,
547                   const JetT* x1,
548                   const JetT* x2,
549                   const JetT* x3,
550                   const JetT* x4,
551                   const JetT* x5,
552                   const JetT* x6,
553                   JetT* residuals) const {
554     CHECK_NE(N0, 0);
555     CHECK_NE(N1, 0);
556     CHECK_NE(N2, 0);
557     CHECK_NE(N3, 0);
558     CHECK_NE(N4, 0);
559     CHECK_NE(N5, 0);
560     CHECK_NE(N6, 0);
561     CHECK_EQ(N7, 0);
562     CHECK_EQ(N8, 0);
563     CHECK_EQ(N9, 0);
564     internal::FixedArray<const JetT*> jets(7);
565     jets[0] = x0;
566     jets[1] = x1;
567     jets[2] = x2;
568     jets[3] = x3;
569     jets[4] = x4;
570     jets[5] = x5;
571     jets[6] = x6;
572     return cost_functor_(jets.get(), residuals);
573   }
574
575   template <typename JetT>
576   bool operator()(const JetT* x0,
577                   const JetT* x1,
578                   const JetT* x2,
579                   const JetT* x3,
580                   const JetT* x4,
581                   const JetT* x5,
582                   const JetT* x6,
583                   const JetT* x7,
584                   JetT* residuals) const {
585     CHECK_NE(N0, 0);
586     CHECK_NE(N1, 0);
587     CHECK_NE(N2, 0);
588     CHECK_NE(N3, 0);
589     CHECK_NE(N4, 0);
590     CHECK_NE(N5, 0);
591     CHECK_NE(N6, 0);
592     CHECK_NE(N7, 0);
593     CHECK_EQ(N8, 0);
594     CHECK_EQ(N9, 0);
595     internal::FixedArray<const JetT*> jets(8);
596     jets[0] = x0;
597     jets[1] = x1;
598     jets[2] = x2;
599     jets[3] = x3;
600     jets[4] = x4;
601     jets[5] = x5;
602     jets[6] = x6;
603     jets[7] = x7;
604     return cost_functor_(jets.get(), residuals);
605   }
606
607   template <typename JetT>
608   bool operator()(const JetT* x0,
609                   const JetT* x1,
610                   const JetT* x2,
611                   const JetT* x3,
612                   const JetT* x4,
613                   const JetT* x5,
614                   const JetT* x6,
615                   const JetT* x7,
616                   const JetT* x8,
617                   JetT* residuals) const {
618     CHECK_NE(N0, 0);
619     CHECK_NE(N1, 0);
620     CHECK_NE(N2, 0);
621     CHECK_NE(N3, 0);
622     CHECK_NE(N4, 0);
623     CHECK_NE(N5, 0);
624     CHECK_NE(N6, 0);
625     CHECK_NE(N7, 0);
626     CHECK_NE(N8, 0);
627     CHECK_EQ(N9, 0);
628     internal::FixedArray<const JetT*> jets(9);
629     jets[0] = x0;
630     jets[1] = x1;
631     jets[2] = x2;
632     jets[3] = x3;
633     jets[4] = x4;
634     jets[5] = x5;
635     jets[6] = x6;
636     jets[7] = x7;
637     jets[8] = x8;
638     return cost_functor_(jets.get(), residuals);
639   }
640
641   template <typename JetT>
642   bool operator()(const JetT* x0,
643                   const JetT* x1,
644                   const JetT* x2,
645                   const JetT* x3,
646                   const JetT* x4,
647                   const JetT* x5,
648                   const JetT* x6,
649                   const JetT* x7,
650                   const JetT* x8,
651                   const JetT* x9,
652                   JetT* residuals) const {
653     CHECK_NE(N0, 0);
654     CHECK_NE(N1, 0);
655     CHECK_NE(N2, 0);
656     CHECK_NE(N3, 0);
657     CHECK_NE(N4, 0);
658     CHECK_NE(N5, 0);
659     CHECK_NE(N6, 0);
660     CHECK_NE(N7, 0);
661     CHECK_NE(N8, 0);
662     CHECK_NE(N9, 0);
663     internal::FixedArray<const JetT*> jets(10);
664     jets[0] = x0;
665     jets[1] = x1;
666     jets[2] = x2;
667     jets[3] = x3;
668     jets[4] = x4;
669     jets[5] = x5;
670     jets[6] = x6;
671     jets[7] = x7;
672     jets[8] = x8;
673     jets[9] = x9;
674     return cost_functor_(jets.get(), residuals);
675   }
676
677  private:
678   DynamicCostFunctionToFunctor cost_functor_;
679 };
680
681 }  // namespace ceres
682
683 #endif  // CERES_PUBLIC_COST_FUNCTION_TO_FUNCTOR_H_