1
// Ceres Solver - A fast non-linear least squares minimizer
2
// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
3
// http://code.google.com/p/ceres-solver/
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions are met:
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.
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.
29
// Author: keir@google.com (Keir Mierle)
31
#include "ceres/jet.h"
36
#include <glog/logging.h>
37
#include "gtest/gtest.h"
38
#include "ceres/stringprintf.h"
39
#include "ceres/test_util.h"
46
typedef Jet<double, 2> J;
48
// Convenient shorthand for making a jet.
49
J MakeJet(double a, double v0, double v1) {
57
// On a 32-bit optimized build, the mismatch is about 1.4e-14.
58
double const kTolerance = 1e-13;
60
void ExpectJetsClose(const J &x, const J &y) {
61
ExpectClose(x.a, y.a, kTolerance);
62
ExpectClose(x.v[0], y.v[0], kTolerance);
63
ExpectClose(x.v[1], y.v[1], kTolerance);
67
// Pick arbitrary values for x and y.
68
J x = MakeJet(2.3, -2.7, 1e-3);
69
J y = MakeJet(1.7, 0.5, 1e+2);
74
{ // Check that log(exp(x)) == x.
79
ExpectJetsClose(w, x);
82
{ // Check that (x * y) / x == y.
87
ExpectJetsClose(w, y);
90
{ // Check that sqrt(x * x) == x.
95
ExpectJetsClose(w, x);
98
{ // Check that sqrt(y) * sqrt(y) == y.
103
ExpectJetsClose(w, y);
106
{ // Check that cos(2*x) = cos(x)^2 - sin(x)^2
107
J z = cos(J(2.0) * x);
108
J w = cos(x)*cos(x) - sin(x)*sin(x);
111
ExpectJetsClose(w, z);
114
{ // Check that sin(2*x) = 2*cos(x)*sin(x)
115
J z = sin(J(2.0) * x);
116
J w = J(2.0)*cos(x)*sin(x);
119
ExpectJetsClose(w, z);
122
{ // Check that cos(x)*cos(x) + sin(x)*sin(x) = 1
123
J z = cos(x) * cos(x);
124
J w = sin(x) * sin(x);
127
ExpectJetsClose(z + w, J(1.0));
130
{ // Check that atan2(r*sin(t), r*cos(t)) = t.
131
J t = MakeJet(0.7, -0.3, +1.5);
132
J r = MakeJet(2.3, 0.13, -2.4);
136
J u = atan2(r * sin(t), r * cos(t));
139
ExpectJetsClose(u, t);
142
{ // Check that pow(x, 1) == x.
148
ExpectJetsClose(x, u);
151
{ // Check that pow(x, 1) == x.
152
J y = MakeJet(1, 0.0, 0.0);
159
ExpectJetsClose(x, u);
162
{ // Check that pow(e, log(x)) == x.
168
J u = pow(M_E, logx);
171
ExpectJetsClose(x, u);
174
{ // Check that pow(e, log(x)) == x.
176
J e = MakeJet(M_E, 0., 0.);
178
VL << "log(x) = " << logx;
183
ExpectJetsClose(x, u);
186
{ // Check that pow(e, log(x)) == x.
188
J e = MakeJet(M_E, 0., 0.);
190
VL << "logx = " << logx;
195
ExpectJetsClose(x, u);
198
{ // Check that pow(x,y) = exp(y*log(x)).
200
J e = MakeJet(M_E, 0., 0.);
202
VL << "logx = " << logx;
204
J u = pow(e, y*logx);
209
ExpectJetsClose(v, u);
212
{ // Check that 1 + x == x + 1.
216
ExpectJetsClose(a, b);
219
{ // Check that 1 - x == -(x - 1).
223
ExpectJetsClose(a, b);
226
{ // Check that x/s == x*s.
230
ExpectJetsClose(5.0 * a, b / 5.0);
233
{ // Check that x / y == 1 / (y / x).
239
ExpectJetsClose(a, b);
242
{ // Check that abs(-x * x) == sqrt(x * x).
243
ExpectJetsClose(abs(-x), sqrt(x * x));
246
{ // Check that cos(acos(x)) == x.
247
J a = MakeJet(0.1, -2.7, 1e-3);
248
ExpectJetsClose(cos(acos(a)), a);
249
ExpectJetsClose(acos(cos(a)), a);
251
J b = MakeJet(0.6, 0.5, 1e+2);
252
ExpectJetsClose(cos(acos(b)), b);
253
ExpectJetsClose(acos(cos(b)), b);
256
{ // Check that sin(asin(x)) == x.
257
J a = MakeJet(0.1, -2.7, 1e-3);
258
ExpectJetsClose(sin(asin(a)), a);
259
ExpectJetsClose(asin(sin(a)), a);
261
J b = MakeJet(0.4, 0.5, 1e+2);
262
ExpectJetsClose(sin(asin(b)), b);
263
ExpectJetsClose(asin(sin(b)), b);
267
TEST(Jet, JetsInEigenMatrices) {
268
J x = MakeJet(2.3, -2.7, 1e-3);
269
J y = MakeJet(1.7, 0.5, 1e+2);
270
J z = MakeJet(5.3, -4.7, 1e-3);
271
J w = MakeJet(9.7, 1.5, 10.1);
273
Eigen::Matrix<J, 2, 2> M;
274
Eigen::Matrix<J, 2, 1> v, r1, r2;
279
// Check that M * v == (v^T * M^T)^T
281
r2 = (v.transpose() * M.transpose()).transpose();
283
ExpectJetsClose(r1(0), r2(0));
284
ExpectJetsClose(r1(1), r2(1));
287
TEST(JetTraitsTest, ClassificationMixed) {
288
Jet<double, 3> a(5.5, 0);
289
a.v[0] = std::numeric_limits<double>::quiet_NaN();
290
a.v[1] = std::numeric_limits<double>::infinity();
291
a.v[2] = -std::numeric_limits<double>::infinity();
292
EXPECT_FALSE(isfinite(a));
293
EXPECT_FALSE(isnormal(a));
294
EXPECT_TRUE(isinf(a));
295
EXPECT_TRUE(isnan(a));
298
TEST(JetTraitsTest, ClassificationNaN) {
299
Jet<double, 3> a(5.5, 0);
300
a.v[0] = std::numeric_limits<double>::quiet_NaN();
303
EXPECT_FALSE(isfinite(a));
304
EXPECT_FALSE(isnormal(a));
305
EXPECT_FALSE(isinf(a));
306
EXPECT_TRUE(isnan(a));
309
TEST(JetTraitsTest, ClassificationInf) {
310
Jet<double, 3> a(5.5, 0);
311
a.v[0] = std::numeric_limits<double>::infinity();
314
EXPECT_FALSE(isfinite(a));
315
EXPECT_FALSE(isnormal(a));
316
EXPECT_TRUE(isinf(a));
317
EXPECT_FALSE(isnan(a));
320
TEST(JetTraitsTest, ClassificationFinite) {
321
Jet<double, 3> a(5.5, 0);
325
EXPECT_TRUE(isfinite(a));
326
EXPECT_TRUE(isnormal(a));
327
EXPECT_FALSE(isinf(a));
328
EXPECT_FALSE(isnan(a));
331
} // namespace internal