blob: 2a8cd390d0efb48a78375c01f3d2de4e68414416 [file] [log] [blame]
Austin Schuh70cc9552019-01-21 19:46:48 -08001
2// Ceres Solver - A fast non-linear least squares minimizer
3// Copyright 2017 Google Inc. All rights reserved.
4// http://ceres-solver.org/
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are met:
8//
9// * Redistributions of source code must retain the above copyright notice,
10// this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above copyright notice,
12// this list of conditions and the following disclaimer in the documentation
13// and/or other materials provided with the distribution.
14// * Neither the name of Google Inc. nor the names of its contributors may be
15// used to endorse or promote products derived from this software without
16// specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28// POSSIBILITY OF SUCH DAMAGE.
29//
30// Author: mierle@gmail.com (Keir Mierle)
31
32#include "ceres/tiny_solver.h"
33#include "ceres/tiny_solver_test_util.h"
34
35#include <algorithm>
36#include <cmath>
37
38#include "gtest/gtest.h"
39
40namespace ceres {
41
42typedef Eigen::Matrix<double, 2, 1> Vec2;
43typedef Eigen::Matrix<double, 3, 1> Vec3;
44typedef Eigen::VectorXd VecX;
45
46class ExampleStatic {
47 public:
48 typedef double Scalar;
49 enum {
50 // Can also be Eigen::Dynamic.
51 NUM_RESIDUALS = 2,
52 NUM_PARAMETERS = 3,
53 };
54 bool operator()(const double* parameters,
55 double* residuals,
56 double* jacobian) const {
57 return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
58 }
59};
60
61class ExampleParametersDynamic {
62 public:
63 typedef double Scalar;
64 enum {
65 NUM_RESIDUALS = 2,
66 NUM_PARAMETERS = Eigen::Dynamic,
67 };
68
69 int NumParameters() const {
70 return 3;
71 }
72
73 bool operator()(const double* parameters,
74 double* residuals,
75 double* jacobian) const {
76 return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
77 }
78};
79
80class ExampleResidualsDynamic {
81 public:
82 typedef double Scalar;
83 enum {
84 NUM_RESIDUALS = Eigen::Dynamic,
85 NUM_PARAMETERS = 3,
86 };
87
88 int NumResiduals() const {
89 return 2;
90 }
91
92 bool operator()(const double* parameters,
93 double* residuals,
94 double* jacobian) const {
95 return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
96 }
97};
98
99class ExampleAllDynamic {
100 public:
101 typedef double Scalar;
102 enum {
103 NUM_RESIDUALS = Eigen::Dynamic,
104 NUM_PARAMETERS = Eigen::Dynamic,
105 };
106
107 int NumResiduals() const {
108 return 2;
109 }
110
111 int NumParameters() const {
112 return 3;
113 }
114
115 bool operator()(const double* parameters,
116 double* residuals,
117 double* jacobian) const {
118 return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
119 }
120};
121
122template<typename Function, typename Vector>
123void TestHelper(const Function& f, const Vector& x0) {
124 Vector x = x0;
125 Vec2 residuals;
126 f(x.data(), residuals.data(), NULL);
127 EXPECT_GT(residuals.squaredNorm() / 2.0, 1e-10);
128
129 TinySolver<Function> solver;
130 solver.Solve(f, &x);
131 EXPECT_NEAR(0.0, solver.summary.final_cost, 1e-10);
132}
133
134// A test case for when the cost function is statically sized.
135TEST(TinySolver, SimpleExample) {
136 Vec3 x0(0.76026643, -30.01799744, 0.55192142);
137 ExampleStatic f;
138
139 TestHelper(f, x0);
140}
141
142// A test case for when the number of parameters is dynamically sized.
143TEST(TinySolver, ParametersDynamic) {
144 VecX x0(3);
145 x0 << 0.76026643, -30.01799744, 0.55192142;
146
147 ExampleParametersDynamic f;
148
149 TestHelper(f, x0);
150}
151
152// A test case for when the number of residuals is dynamically sized.
153TEST(TinySolver, ResidualsDynamic) {
154 Vec3 x0(0.76026643, -30.01799744, 0.55192142);
155
156 ExampleResidualsDynamic f;
157
158 TestHelper(f, x0);
159}
160
161// A test case for when the number of parameters and residuals is
162// dynamically sized.
163TEST(TinySolver, ParametersAndResidualsDynamic) {
164 VecX x0(3);
165 x0 << 0.76026643, -30.01799744, 0.55192142;
166
167 ExampleAllDynamic f;
168
169 TestHelper(f, x0);
170}
171
172} // namespace ceres