Drake
autodiff_overloads.h
Go to the documentation of this file.
1 
20 #pragma once
21 
22 #include <cmath>
23 #include <limits>
24 
26 #include "drake/common/cond.h"
29 
30 namespace Eigen {
31 
33 template <typename DerType>
34 double round(const Eigen::AutoDiffScalar<DerType>& x) {
35  using std::round;
36  return round(x.value());
37 }
38 
40 template <typename DerType>
41 bool isinf(const Eigen::AutoDiffScalar<DerType>& x) {
42  using std::isinf;
43  return isinf(x.value());
44 }
45 
47 template <typename DerType>
48 bool isnan(const Eigen::AutoDiffScalar<DerType>& x) {
49  using std::isnan;
50  return isnan(x.value());
51 }
52 
54 template <typename DerType>
55 double floor(const Eigen::AutoDiffScalar<DerType>& x) {
56  using std::floor;
57  return floor(x.value());
58 }
59 
61 template <typename DerType>
62 double ceil(const Eigen::AutoDiffScalar<DerType>& x) {
63  using std::ceil;
64  return ceil(x.value());
65 }
66 
68 template <typename DerType, typename T>
69 Eigen::AutoDiffScalar<DerType> copysign(const Eigen::AutoDiffScalar<DerType>& x,
70  const T& y) {
71  using std::isnan;
72  if (isnan(x)) return (y >= 0) ? NAN : -NAN;
73  if ((x < 0 && y >= 0) || (x >= 0 && y < 0))
74  return -x;
75  else
76  return x;
77 }
78 
80 template <typename DerType>
81 double copysign(double x, const Eigen::AutoDiffScalar<DerType>& y) {
82  using std::isnan;
83  if (isnan(x)) return (y >= 0) ? NAN : -NAN;
84  if ((x < 0 && y >= 0) || (x >= 0 && y < 0))
85  return -x;
86  else
87  return x;
88 }
89 
92 template <typename DerTypeA, typename DerTypeB>
93 Eigen::AutoDiffScalar<
94  typename internal::remove_all<DerTypeA>::type::PlainObject>
95 pow(const Eigen::AutoDiffScalar<DerTypeA>& base,
96  const Eigen::AutoDiffScalar<DerTypeB>& exponent) {
97  // The two AutoDiffScalars being exponentiated must have the same matrix
98  // type. This includes, but is not limited to, the same scalar type and
99  // the same dimension.
100  static_assert(
101  std::is_same<
102  typename internal::remove_all<DerTypeA>::type::PlainObject,
103  typename internal::remove_all<DerTypeB>::type::PlainObject>::value,
104  "The derivative types must match.");
105 
106  internal::make_coherent(base.derivatives(), exponent.derivatives());
107 
108  const auto& x = base.value();
109  const auto& xgrad = base.derivatives();
110  const auto& y = exponent.value();
111  const auto& ygrad = exponent.derivatives();
112 
113  using std::pow;
114  using std::log;
115  const auto x_to_the_y = pow(x, y);
116  return Eigen::MakeAutoDiffScalar(
117  // The value is x ^ y.
118  x_to_the_y,
119  // The multivariable chain rule states:
120  // df/dv_i = (∂f/∂x * dx/dv_i) + (∂f/∂y * dy/dv_i)
121  // ∂f/∂x is y*x^(y-1)
122  y * pow(x, y - 1) * xgrad +
123  // ∂f/∂y is (x^y)*ln(x)
124  x_to_the_y * log(x) * ygrad);
125 }
126 
127 } // namespace Eigen
128 
129 namespace drake {
130 
133 template <typename DerType>
134 double ExtractDoubleOrThrow(const Eigen::AutoDiffScalar<DerType>& scalar) {
135  return static_cast<double>(scalar.value());
136 }
137 
139 template <typename DerType>
140 struct dummy_value<Eigen::AutoDiffScalar<DerType>> {
141  static constexpr Eigen::AutoDiffScalar<DerType> get() {
142  constexpr double kNaN = std::numeric_limits<double>::quiet_NaN();
143  DerType derivatives;
144  derivatives.fill(kNaN);
145  return Eigen::AutoDiffScalar<DerType>(kNaN, derivatives);
146  }
147 };
148 
154 template <typename DerType1, typename DerType2>
155 inline Eigen::AutoDiffScalar<
156  typename Eigen::internal::remove_all<DerType1>::type::PlainObject>
157 if_then_else(bool f_cond, const Eigen::AutoDiffScalar<DerType1>& x,
158  const Eigen::AutoDiffScalar<DerType2>& y) {
159  typedef Eigen::AutoDiffScalar<
160  typename Eigen::internal::remove_all<DerType1>::type::PlainObject>
161  ADS1;
162  typedef Eigen::AutoDiffScalar<
163  typename Eigen::internal::remove_all<DerType2>::type::PlainObject>
164  ADS2;
165  static_assert(std::is_same<ADS1, ADS2>::value,
166  "The derivative types must match.");
167  return f_cond ? ADS1(x) : ADS2(y);
168 }
169 
171 template <typename DerType, typename... Rest>
172 Eigen::AutoDiffScalar<
173  typename Eigen::internal::remove_all<DerType>::type::PlainObject>
174 cond(bool f_cond, const Eigen::AutoDiffScalar<DerType>& e_then, Rest... rest) {
175  return if_then_else(f_cond, e_then, cond(rest...));
176 }
177 
178 } // namespace drake
bool isnan(const Eigen::AutoDiffScalar< DerType > &x)
Overloads isnan to mimic std::isnan from <cmath>.
Definition: autodiff_overloads.h:48
double ceil(const Eigen::AutoDiffScalar< DerType > &x)
Overloads ceil to mimic std::ceil from <cmath>.
Definition: autodiff_overloads.h:62
std::vector< Number > x
Definition: ipopt_solver.cc:153
Definition: automotive_demo.cc:88
Eigen::AutoDiffScalar< typename Eigen::internal::remove_all< DerType1 >::type::PlainObject > if_then_else(bool f_cond, const Eigen::AutoDiffScalar< DerType1 > &x, const Eigen::AutoDiffScalar< DerType2 > &y)
Provides if-then-else expression for Eigen::AutoDiffScalar type.
Definition: autodiff_overloads.h:157
double round(const Eigen::AutoDiffScalar< DerType > &x)
Overloads round to mimic std::round from <cmath>.
Definition: autodiff_overloads.h:34
Definition: autodiff_overloads.h:30
double floor(const Eigen::AutoDiffScalar< DerType > &x)
Overloads floor to mimic std::floor from <cmath>.
Definition: autodiff_overloads.h:55
double y
Definition: vtk_util_test.cc:26
int value
Definition: copyable_unique_ptr_test.cc:61
Provides Drake&#39;s assertion implementation.
double ExtractDoubleOrThrow(const Eigen::AutoDiffScalar< DerType > &scalar)
Returns the autodiff scalar&#39;s value() as a double.
Definition: autodiff_overloads.h:134
Eigen::AutoDiffScalar< typename Eigen::internal::remove_all< DerType >::type::PlainObject > cond(bool f_cond, const Eigen::AutoDiffScalar< DerType > &e_then, Rest...rest)
Provides special case of cond expression for Eigen::AutoDiffScalar type.
Definition: autodiff_overloads.h:174
Eigen::AutoDiffScalar< DerType > copysign(const Eigen::AutoDiffScalar< DerType > &x, const T &y)
Overloads copysign from <cmath>.
Definition: autodiff_overloads.h:69
Provides a "dummy" value for a ScalarType – a value that is unlikely to be mistaken for a purposeful...
Definition: dummy_value.h:17
bool isinf(const Eigen::AutoDiffScalar< DerType > &x)
Overloads isinf to mimic std::isinf from <cmath>.
Definition: autodiff_overloads.h:41
Polynomial< CoefficientType > pow(const Polynomial< CoefficientType > &base, typename Polynomial< CoefficientType >::PowerType exponent)
Provides power function for Polynomial.
Definition: polynomial.h:450
Eigen::AutoDiffScalar< typename internal::remove_all< DerTypeA >::type::PlainObject > pow(const Eigen::AutoDiffScalar< DerTypeA > &base, const Eigen::AutoDiffScalar< DerTypeB > &exponent)
Overloads pow for an AutoDiffScalar base and exponent, implementing the chain rule.
Definition: autodiff_overloads.h:95
Expression log(const Expression &e)
Definition: symbolic_expression.cc:527