Drake
autodiffxd_test.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <gtest/gtest.h>
4 
6 
7 namespace drake {
8 namespace test {
9 
10 class AutoDiffXdTest : public ::testing::Test {
11  protected:
12  void SetUp() override {
13  // We only set the derivatives of y and leave x's uninitialized.
14  y_xd_.derivatives() = Eigen::VectorXd::Ones(3);
15  y_3d_.derivatives() = Eigen::Vector3d::Ones();
16  }
17 
18  // Evaluates a given function f with values of AutoDiffXd and values with
19  // AutoDiffd<3>. It checks if the values and the derivatives of those
20  // evaluation results are matched.
21  template <typename F>
22  ::testing::AssertionResult Check(const F& f) {
23  const AutoDiffXd e1{f(x_xd_, y_xd_)};
24  const AutoDiffd<3> e2{f(x_3d_, y_3d_)};
25 
26  if (std::isnan(e1.value()) && std::isnan(e2.value())) {
27  // Both values are NaN.
28  return ::testing::AssertionSuccess();
29  }
30  if (e1.value() != e2.value()) {
31  return ::testing::AssertionFailure()
32  << "Values do not match: " << e1.value() << " and " << e2.value();
33  }
34  if (e1.derivatives().array().isNaN().all() &&
35  e2.derivatives().array().isNaN().all()) {
36  // Both derivatives are NaN.
37  return ::testing::AssertionSuccess();
38  }
39  if (e1.derivatives() != e2.derivatives()) {
40  return ::testing::AssertionFailure() << "Derivatives do not match:\n"
41  << e1.derivatives() << "\n----\n"
42  << e2.derivatives() << "\n";
43  }
44  return ::testing::AssertionSuccess();
45  }
46 
47  // AutoDiffXd constants -- x and y.
48  const AutoDiffXd x_xd_{0.4};
50  // AutoDiffd<3> constants -- x and y.
51  const AutoDiffd<3> x_3d_{x_xd_.value()};
53 };
54 
55 // We need to specify the return type of the polymorphic lambda function that is
56 // passed to AutoDiffXdTest::Check() method.
57 #define CHECK_EXPR(expr) \
58  EXPECT_TRUE( \
59  Check([](const auto& x, const auto& y) -> \
60  typename Eigen::internal::remove_reference<decltype(x)>::type { \
61  return expr; \
62  })) \
63  << #expr // Print statement to locate it if it fails
64 
65 #define CHECK_BINARY_OP(bop, x, y, c) \
66  CHECK_EXPR((x bop x)bop(y bop y)); \
67  CHECK_EXPR((x bop y)bop(x bop y)); \
68  CHECK_EXPR((x bop y)bop c); \
69  CHECK_EXPR((x bop y)bop c); \
70  CHECK_EXPR((x bop c)bop y); \
71  CHECK_EXPR((c bop x)bop y); \
72  CHECK_EXPR(x bop(y bop c)); \
73  CHECK_EXPR(x bop(c bop y)); \
74  CHECK_EXPR(c bop(x bop y));
75 
76 #define CHECK_UNARY_FUNCTION(f, x, y, c) \
77  CHECK_EXPR(f(x + x) + (y + y)); \
78  CHECK_EXPR(f(x + y) + (x + y)); \
79  CHECK_EXPR(f(x - x) + (y - y)); \
80  CHECK_EXPR(f(x - y) + (x - y)); \
81  CHECK_EXPR(f(x* x) + (y * y)); \
82  CHECK_EXPR(f(x* y) + (x * y)); \
83  CHECK_EXPR(f(x / x) + (y / y)); \
84  CHECK_EXPR(f(x / y) + (x / y)); \
85  CHECK_EXPR(f(x + c) + y); \
86  CHECK_EXPR(f(x - c) + y); \
87  CHECK_EXPR(f(x* c) + y); \
88  CHECK_EXPR(f(x / c) + y); \
89  CHECK_EXPR(f(c + x) + y); \
90  CHECK_EXPR(f(c - x) + y); \
91  CHECK_EXPR(f(c* x) + y); \
92  CHECK_EXPR(f(c / x) + y); \
93  CHECK_EXPR(f(-x) + y);
94 
95 #define CHECK_BINARY_FUNCTION_ADS_ADS(f, x, y, c) \
96  CHECK_EXPR(f(x + x, y + y) + x); \
97  CHECK_EXPR(f(x + x, y + y) + y); \
98  CHECK_EXPR(f(x + y, y + y) + x); \
99  CHECK_EXPR(f(x + y, y + y) + y); \
100  CHECK_EXPR(f(x - x, y - y) - x); \
101  CHECK_EXPR(f(x - x, y - y) - y); \
102  CHECK_EXPR(f(x - y, y - y) - x); \
103  CHECK_EXPR(f(x - y, y - y) - y); \
104  CHECK_EXPR(f(x* x, y* y) * x); \
105  CHECK_EXPR(f(x* x, y* y) * y); \
106  CHECK_EXPR(f(x* y, y* y) * x); \
107  CHECK_EXPR(f(x* y, y* y) * y); \
108  CHECK_EXPR(f(x / x, y / y) / x); \
109  CHECK_EXPR(f(x / x, y / y) / y); \
110  CHECK_EXPR(f(x / y, y / y) / x); \
111  CHECK_EXPR(f(x / y, y / y) / y); \
112  CHECK_EXPR(f(x + c, y + c) + x); \
113  CHECK_EXPR(f(c + x, c + x) + x); \
114  CHECK_EXPR(f(x* c, y* c) + x); \
115  CHECK_EXPR(f(c* x, c* x) + x); \
116  CHECK_EXPR(f(-x, -y) + y)
117 
118 #define CHECK_BINARY_FUNCTION_ADS_SCALAR(f, x, y, c) \
119  CHECK_EXPR(f(x, c) + y); \
120  CHECK_EXPR(f(x + x, c) + y); \
121  CHECK_EXPR(f(x + y, c) + y); \
122  CHECK_EXPR(f(x - x, c) - y); \
123  CHECK_EXPR(f(x - x, c) - y); \
124  CHECK_EXPR(f(x* x, c) * y); \
125  CHECK_EXPR(f(x* x, c) * y); \
126  CHECK_EXPR(f(x / x, c) / y); \
127  CHECK_EXPR(f(x / x, c) / y); \
128  CHECK_EXPR(f(x + c, c) + y); \
129  CHECK_EXPR(f(c + x, c) + y); \
130  CHECK_EXPR(f(x* c, c) + y); \
131  CHECK_EXPR(f(c* x, c) + y); \
132  CHECK_EXPR(f(-x, c) + y);
133 
134 } // namespace test
135 } // namespace drake
std::vector< snopt::doublereal > F
Definition: snopt_solver.cc:59
bool isnan(const Eigen::AutoDiffScalar< DerType > &x)
Overloads isnan to mimic std::isnan from <cmath>.
Definition: autodiff_overloads.h:52
Eigen::AutoDiffScalar< Eigen::VectorXd > AutoDiffXd
An autodiff variable with a dynamic number of partials.
Definition: eigen_autodiff_types.h:25
Eigen::AutoDiffScalar< Eigen::Matrix< double, num_vars, 1 > > AutoDiffd
An autodiff variable with num_vars partials.
Definition: eigen_autodiff_types.h:31
void SetUp() override
Definition: autodiffxd_test.h:12
Definition: automotive_demo.cc:88
::testing::AssertionResult Check(const F &f)
Definition: autodiffxd_test.h:22
AutoDiffd< 3 > y_3d_
Definition: autodiffxd_test.h:52
AutoDiffXd y_xd_
Definition: autodiffxd_test.h:49
const AutoDiffd< 3 > x_3d_
Definition: autodiffxd_test.h:51
Definition: autodiffxd_test.h:10
const AutoDiffXd x_xd_
Definition: autodiffxd_test.h:48