blob: 2a551d394b3e9228b792e8d63bdf081262d64c87 [file] [log] [blame]
Sameer Agarwal509f68c2013-02-20 01:39:03 -08001// Ceres Solver - A fast non-linear least squares minimizer
Keir Mierle7492b0d2015-03-17 22:30:16 -07002// Copyright 2015 Google Inc. All rights reserved.
3// http://ceres-solver.org/
Sameer Agarwal509f68c2013-02-20 01:39:03 -08004//
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_NUMERIC_DIFF_TEST_UTILS_H_
32#define CERES_INTERNAL_NUMERIC_DIFF_TEST_UTILS_H_
33
Sameer Agarwal2f0d7242013-01-18 13:11:32 -080034#include "ceres/cost_function.h"
35#include "ceres/sized_cost_function.h"
36#include "ceres/types.h"
37
38namespace ceres {
39namespace internal {
40
Tal Ben-Nun4f049db2015-05-13 15:43:51 +030041// Noise factor for randomized cost function.
42static const double kNoiseFactor = 0.01;
43
44// Default random seed for randomized cost function.
45static const unsigned int kRandomSeed = 1234;
46
Sameer Agarwal2f0d7242013-01-18 13:11:32 -080047// y1 = x1'x2 -> dy1/dx1 = x2, dy1/dx2 = x1
48// y2 = (x1'x2)^2 -> dy2/dx1 = 2 * x2 * (x1'x2), dy2/dx2 = 2 * x1 * (x1'x2)
49// y3 = x2'x2 -> dy3/dx1 = 0, dy3/dx2 = 2 * x2
50class EasyFunctor {
51 public:
52 bool operator()(const double* x1, const double* x2, double* residuals) const;
53 void ExpectCostFunctionEvaluationIsNearlyCorrect(
54 const CostFunction& cost_function,
Tal Ben-Nun4f049db2015-05-13 15:43:51 +030055 NumericDiffMethodType method) const;
Sameer Agarwal2f0d7242013-01-18 13:11:32 -080056};
57
58class EasyCostFunction : public SizedCostFunction<3, 5, 5> {
59 public:
60 virtual bool Evaluate(double const* const* parameters,
61 double* residuals,
62 double** /* not used */) const {
63 return functor_(parameters[0], parameters[1], residuals);
64 }
65
66 private:
67 EasyFunctor functor_;
68};
69
70// y1 = sin(x1'x2)
71// y2 = exp(-x1'x2 / 10)
72//
73// dy1/dx1 = x2 * cos(x1'x2), dy1/dx2 = x1 * cos(x1'x2)
74// dy2/dx1 = -x2 * exp(-x1'x2 / 10) / 10, dy2/dx2 = -x2 * exp(-x1'x2 / 10) / 10
75class TranscendentalFunctor {
76 public:
77 bool operator()(const double* x1, const double* x2, double* residuals) const;
78 void ExpectCostFunctionEvaluationIsNearlyCorrect(
79 const CostFunction& cost_function,
Tal Ben-Nun4f049db2015-05-13 15:43:51 +030080 NumericDiffMethodType method) const;
Sameer Agarwal2f0d7242013-01-18 13:11:32 -080081};
82
83class TranscendentalCostFunction : public SizedCostFunction<2, 5, 5> {
84 public:
85 virtual bool Evaluate(double const* const* parameters,
86 double* residuals,
87 double** /* not used */) const {
88 return functor_(parameters[0], parameters[1], residuals);
89 }
90 private:
91 TranscendentalFunctor functor_;
92};
93
Tal Ben-Nun4f049db2015-05-13 15:43:51 +030094// y = exp(x), dy/dx = exp(x)
95class ExponentialFunctor {
96 public:
97 bool operator()(const double* x1, double* residuals) const;
98 void ExpectCostFunctionEvaluationIsNearlyCorrect(
99 const CostFunction& cost_function) const;
100};
101
102class ExponentialCostFunction : public SizedCostFunction<1, 1> {
103 public:
104 virtual bool Evaluate(double const* const* parameters,
105 double* residuals,
106 double** /* not used */) const {
107 return functor_(parameters[0], residuals);
108 }
109
110 private:
111 ExponentialFunctor functor_;
112};
113
114// Test adaptive numeric differentiation by synthetically adding random noise
115// to a functor.
116// y = x^2 + [random noise], dy/dx ~ 2x
117class RandomizedFunctor {
118 public:
119 RandomizedFunctor(double noise_factor, unsigned int random_seed)
120 : noise_factor_(noise_factor), random_seed_(random_seed) {
121 }
122
123 bool operator()(const double* x1, double* residuals) const;
124 void ExpectCostFunctionEvaluationIsNearlyCorrect(
125 const CostFunction& cost_function) const;
126
127 private:
128 double noise_factor_;
129 unsigned int random_seed_;
130};
131
132class RandomizedCostFunction : public SizedCostFunction<1, 1> {
133 public:
134 RandomizedCostFunction(double noise_factor, unsigned int random_seed)
135 : functor_(noise_factor, random_seed) {
136 }
137
138 virtual bool Evaluate(double const* const* parameters,
139 double* residuals,
140 double** /* not used */) const {
141 return functor_(parameters[0], residuals);
142 }
143
144 private:
145 RandomizedFunctor functor_;
146};
147
148
Sameer Agarwal2f0d7242013-01-18 13:11:32 -0800149} // namespace internal
150} // namespace ceres
Sameer Agarwal509f68c2013-02-20 01:39:03 -0800151
152#endif // CERES_INTERNAL_NUMERIC_DIFF_TEST_UTILS_H_