blob: 2e70694ee454111c8a3e8ca5d3e20f86fef7f216 [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"
Austin Schuh70cc9552019-01-21 19:46:48 -080033
34#include <algorithm>
35#include <cmath>
36
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080037#include "ceres/tiny_solver_test_util.h"
Austin Schuh70cc9552019-01-21 19:46:48 -080038#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
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080069 int NumParameters() const { return 3; }
Austin Schuh70cc9552019-01-21 19:46:48 -080070
71 bool operator()(const double* parameters,
72 double* residuals,
73 double* jacobian) const {
74 return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
75 }
76};
77
78class ExampleResidualsDynamic {
79 public:
80 typedef double Scalar;
81 enum {
82 NUM_RESIDUALS = Eigen::Dynamic,
83 NUM_PARAMETERS = 3,
84 };
85
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080086 int NumResiduals() const { return 2; }
Austin Schuh70cc9552019-01-21 19:46:48 -080087
88 bool operator()(const double* parameters,
89 double* residuals,
90 double* jacobian) const {
91 return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
92 }
93};
94
95class ExampleAllDynamic {
96 public:
97 typedef double Scalar;
98 enum {
99 NUM_RESIDUALS = Eigen::Dynamic,
100 NUM_PARAMETERS = Eigen::Dynamic,
101 };
102
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800103 int NumResiduals() const { return 2; }
Austin Schuh70cc9552019-01-21 19:46:48 -0800104
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800105 int NumParameters() const { return 3; }
Austin Schuh70cc9552019-01-21 19:46:48 -0800106
107 bool operator()(const double* parameters,
108 double* residuals,
109 double* jacobian) const {
110 return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
111 }
112};
113
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800114template <typename Function, typename Vector>
Austin Schuh70cc9552019-01-21 19:46:48 -0800115void TestHelper(const Function& f, const Vector& x0) {
116 Vector x = x0;
117 Vec2 residuals;
118 f(x.data(), residuals.data(), NULL);
119 EXPECT_GT(residuals.squaredNorm() / 2.0, 1e-10);
120
121 TinySolver<Function> solver;
122 solver.Solve(f, &x);
123 EXPECT_NEAR(0.0, solver.summary.final_cost, 1e-10);
124}
125
126// A test case for when the cost function is statically sized.
127TEST(TinySolver, SimpleExample) {
128 Vec3 x0(0.76026643, -30.01799744, 0.55192142);
129 ExampleStatic f;
130
131 TestHelper(f, x0);
132}
133
134// A test case for when the number of parameters is dynamically sized.
135TEST(TinySolver, ParametersDynamic) {
136 VecX x0(3);
137 x0 << 0.76026643, -30.01799744, 0.55192142;
138
139 ExampleParametersDynamic f;
140
141 TestHelper(f, x0);
142}
143
144// A test case for when the number of residuals is dynamically sized.
145TEST(TinySolver, ResidualsDynamic) {
146 Vec3 x0(0.76026643, -30.01799744, 0.55192142);
147
148 ExampleResidualsDynamic f;
149
150 TestHelper(f, x0);
151}
152
153// A test case for when the number of parameters and residuals is
154// dynamically sized.
155TEST(TinySolver, ParametersAndResidualsDynamic) {
156 VecX x0(3);
157 x0 << 0.76026643, -30.01799744, 0.55192142;
158
159 ExampleAllDynamic f;
160
161 TestHelper(f, x0);
162}
163
164} // namespace ceres