$darkmode
Eigen-unsupported  5.0.1-dev
AutoDiffScalar.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_AUTODIFF_SCALAR_H
11 #define EIGEN_AUTODIFF_SCALAR_H
12 
13 // IWYU pragma: private
14 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 
20 template <typename DerivativeType, bool Enable>
21 struct auto_diff_special_op;
22 
23 template <typename DerivativeType, typename OtherDerivativeType, typename EnableIf = void>
24 struct maybe_coherent_pad_helper {
25  static constexpr int SizeAtCompileTime =
26  max_size_prefer_dynamic(DerivativeType::SizeAtCompileTime, OtherDerivativeType::SizeAtCompileTime);
27  using type = CoherentPadOp<DerivativeType, SizeAtCompileTime>;
28  static type pad(const DerivativeType& x, const OtherDerivativeType& y) {
29  // CoherentPadOp uses variable_if_dynamic<SizeAtCompileTime>. In this case, `SizeAtCompileTime` might
30  // by Dynamic, so we need to take the runtime maximum of x, y.
31  return CoherentPadOp<DerivativeType, SizeAtCompileTime>(x, numext::maxi(x.size(), y.size()));
32  }
33 };
34 
35 // Both are fixed-sized and equal, don't need to pad.
36 // Both are fixed-size and this is larger than other, don't need to pad.
37 template <typename DerivativeType, typename OtherDerivativeType>
38 struct maybe_coherent_pad_helper<
39  DerivativeType, OtherDerivativeType,
40  std::enable_if_t<enum_ge_not_dynamic(DerivativeType::SizeAtCompileTime, OtherDerivativeType::SizeAtCompileTime)>> {
41  using type = const DerivativeType&;
42  static const DerivativeType& pad(const DerivativeType& x, const OtherDerivativeType& /*y*/) { return x; }
43 };
44 
45 template <typename DerivativeType, typename OtherDerivativeType>
46 typename maybe_coherent_pad_helper<DerivativeType, OtherDerivativeType>::type MaybeCoherentPad(
47  const DerivativeType& x, const OtherDerivativeType& y) {
48  return maybe_coherent_pad_helper<DerivativeType, OtherDerivativeType>::pad(x, y);
49 }
50 
51 template <typename Op, typename LhsDerivativeType, typename RhsDerivativeType>
52 auto MakeCoherentCwiseBinaryOp(const LhsDerivativeType& x, const RhsDerivativeType& y, Op op = Op()) {
53  const auto& lhs = MaybeCoherentPad(x, y);
54  const auto& rhs = MaybeCoherentPad(y, x);
55  return CwiseBinaryOp<Op, remove_all_t<decltype(lhs)>, remove_all_t<decltype(rhs)>>(lhs, rhs, op);
56 }
57 
58 } // namespace internal
59 
60 template <typename DerivativeType>
62 
63 template <typename NewDerType>
64 inline AutoDiffScalar<NewDerType> MakeAutoDiffScalar(const typename NewDerType::Scalar& value, const NewDerType& der) {
65  return AutoDiffScalar<NewDerType>(value, der);
66 }
67 
94 template <typename DerivativeType>
95 class AutoDiffScalar
96  : public internal::auto_diff_special_op<
97  DerivativeType, !internal::is_same<typename internal::traits<internal::remove_all_t<DerivativeType>>::Scalar,
98  typename NumTraits<typename internal::traits<
99  internal::remove_all_t<DerivativeType>>::Scalar>::Real>::value> {
100  public:
101  typedef internal::auto_diff_special_op<
102  DerivativeType,
103  !internal::is_same<
104  typename internal::traits<internal::remove_all_t<DerivativeType>>::Scalar,
106  Base;
107  typedef internal::remove_all_t<DerivativeType> DerType;
108  typedef typename internal::traits<DerType>::Scalar Scalar;
109  typedef typename NumTraits<Scalar>::Real Real;
110 
111  using Base::operator+;
112  using Base::operator*;
113 
116 
119  AutoDiffScalar(const Scalar& value, int nbDer, int derNumber) : m_value(value), m_derivatives(DerType::Zero(nbDer)) {
120  m_derivatives.coeffRef(derNumber) = Scalar(1);
121  }
122 
125  /*explicit*/ AutoDiffScalar(const Real& value) : m_value(value) {
126  if (m_derivatives.size() > 0) m_derivatives.setZero();
127  }
128 
130  AutoDiffScalar(const Scalar& value, const DerType& der) : m_value(value), m_derivatives(der) {}
131 
132  template <typename OtherDerType>
134  const AutoDiffScalar<OtherDerType>& other
135 #ifndef EIGEN_PARSED_BY_DOXYGEN
136  ,
137  std::enable_if_t<
138  internal::is_same<Scalar, typename internal::traits<internal::remove_all_t<OtherDerType>>::Scalar>::value &&
139  internal::is_convertible<OtherDerType, DerType>::value,
140  void*> = 0
141 #endif
142  )
143  : m_value(other.value()), m_derivatives(other.derivatives()) {
144  }
145 
146  friend std::ostream& operator<<(std::ostream& s, const AutoDiffScalar& a) { return s << a.value(); }
147 
148  AutoDiffScalar(const AutoDiffScalar& other) : m_value(other.value()), m_derivatives(other.derivatives()) {}
149 
150  template <typename OtherDerType>
151  inline AutoDiffScalar& operator=(const AutoDiffScalar<OtherDerType>& other) {
152  m_value = other.value();
153  m_derivatives = other.derivatives();
154  return *this;
155  }
156 
157  inline AutoDiffScalar& operator=(const AutoDiffScalar& other) {
158  m_value = other.value();
159  m_derivatives = other.derivatives();
160  return *this;
161  }
162 
163  inline AutoDiffScalar& operator=(const Scalar& other) {
164  m_value = other;
165  if (m_derivatives.size() > 0) m_derivatives.setZero();
166  return *this;
167  }
168 
169  // inline operator const Scalar& () const { return m_value; }
170  // inline operator Scalar& () { return m_value; }
171 
172  inline const Scalar& value() const { return m_value; }
173  inline Scalar& value() { return m_value; }
174 
175  inline const DerType& derivatives() const { return m_derivatives; }
176  inline DerType& derivatives() { return m_derivatives; }
177 
178  inline bool operator<(const Scalar& other) const { return m_value < other; }
179  inline bool operator<=(const Scalar& other) const { return m_value <= other; }
180  inline bool operator>(const Scalar& other) const { return m_value > other; }
181  inline bool operator>=(const Scalar& other) const { return m_value >= other; }
182  inline bool operator==(const Scalar& other) const { return m_value == other; }
183  inline bool operator!=(const Scalar& other) const { return m_value != other; }
184 
185  friend inline bool operator<(const Scalar& a, const AutoDiffScalar& b) { return a < b.value(); }
186  friend inline bool operator<=(const Scalar& a, const AutoDiffScalar& b) { return a <= b.value(); }
187  friend inline bool operator>(const Scalar& a, const AutoDiffScalar& b) { return a > b.value(); }
188  friend inline bool operator>=(const Scalar& a, const AutoDiffScalar& b) { return a >= b.value(); }
189  friend inline bool operator==(const Scalar& a, const AutoDiffScalar& b) { return a == b.value(); }
190  friend inline bool operator!=(const Scalar& a, const AutoDiffScalar& b) { return a != b.value(); }
191 
192  template <typename OtherDerType>
193  inline bool operator<(const AutoDiffScalar<OtherDerType>& b) const {
194  return m_value < b.value();
195  }
196  template <typename OtherDerType>
197  inline bool operator<=(const AutoDiffScalar<OtherDerType>& b) const {
198  return m_value <= b.value();
199  }
200  template <typename OtherDerType>
201  inline bool operator>(const AutoDiffScalar<OtherDerType>& b) const {
202  return m_value > b.value();
203  }
204  template <typename OtherDerType>
205  inline bool operator>=(const AutoDiffScalar<OtherDerType>& b) const {
206  return m_value >= b.value();
207  }
208  template <typename OtherDerType>
209  inline bool operator==(const AutoDiffScalar<OtherDerType>& b) const {
210  return m_value == b.value();
211  }
212  template <typename OtherDerType>
213  inline bool operator!=(const AutoDiffScalar<OtherDerType>& b) const {
214  return m_value != b.value();
215  }
216 
217  inline AutoDiffScalar<DerType&> operator+(const Scalar& other) const {
218  return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
219  }
220 
221  friend inline AutoDiffScalar<DerType&> operator+(const Scalar& a, const AutoDiffScalar& b) {
222  return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
223  }
224 
225  // inline const AutoDiffScalar<DerType&> operator+(const Real& other) const
226  // {
227  // return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
228  // }
229 
230  // friend inline const AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar& b)
231  // {
232  // return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
233  // }
234 
235  inline AutoDiffScalar& operator+=(const Scalar& other) {
236  value() += other;
237  return *this;
238  }
239 
240  template <typename OtherDerType>
241  inline auto operator+(const AutoDiffScalar<OtherDerType>& other) const {
242  return MakeAutoDiffScalar(
243  m_value + other.value(),
244  internal::MakeCoherentCwiseBinaryOp<internal::scalar_sum_op<Scalar>>(m_derivatives, other.derivatives()));
245  }
246 
247  template <typename OtherDerType>
248  inline AutoDiffScalar& operator+=(const AutoDiffScalar<OtherDerType>& other) {
249  (*this) = (*this) + other;
250  return *this;
251  }
252 
253  inline AutoDiffScalar<DerType&> operator-(const Scalar& b) const {
254  return AutoDiffScalar<DerType&>(m_value - b, m_derivatives);
255  }
256 
257  friend inline AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType>> operator-(
258  const Scalar& a, const AutoDiffScalar& b) {
259  return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType>>(a - b.value(),
260  -b.derivatives());
261  }
262 
263  inline AutoDiffScalar& operator-=(const Scalar& other) {
264  value() -= other;
265  return *this;
266  }
267 
268  template <typename OtherDerType>
269  inline auto operator-(const AutoDiffScalar<OtherDerType>& other) const {
270  return MakeAutoDiffScalar(m_value - other.value(),
271  internal::MakeCoherentCwiseBinaryOp<internal::scalar_difference_op<Scalar>>(
272  m_derivatives, other.derivatives()));
273  }
274 
275  template <typename OtherDerType>
276  inline AutoDiffScalar& operator-=(const AutoDiffScalar<OtherDerType>& other) {
277  *this = *this - other;
278  return *this;
279  }
280 
281  inline AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType>> operator-() const {
282  return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType>>(-m_value, -m_derivatives);
283  }
284 
285  inline auto operator*(const Scalar& other) const {
286  return MakeAutoDiffScalar(m_value * other, m_derivatives * other);
287  }
288 
289  friend inline auto operator*(const Scalar& other, const AutoDiffScalar& a) {
290  return MakeAutoDiffScalar(a.value() * other, a.derivatives() * other);
291  }
292 
293  // inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
294  // operator*(const Real& other) const
295  // {
296  // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
297  // m_value * other,
298  // (m_derivatives * other));
299  // }
300  //
301  // friend inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
302  // operator*(const Real& other, const AutoDiffScalar& a)
303  // {
304  // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
305  // a.value() * other,
306  // a.derivatives() * other);
307  // }
308 
309  inline auto operator/(const Scalar& other) const {
310  return MakeAutoDiffScalar(m_value / other, (m_derivatives * (Scalar(1) / other)));
311  }
312 
313  friend inline auto operator/(const Scalar& other, const AutoDiffScalar& a) {
314  return MakeAutoDiffScalar(other / a.value(), a.derivatives() * (Scalar(-other) / (a.value() * a.value())));
315  }
316 
317  // inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
318  // operator/(const Real& other) const
319  // {
320  // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
321  // m_value / other,
322  // (m_derivatives * (Real(1)/other)));
323  // }
324  //
325  // friend inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
326  // operator/(const Real& other, const AutoDiffScalar& a)
327  // {
328  // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
329  // other / a.value(),
330  // a.derivatives() * (-Real(1)/other));
331  // }
332 
333  template <typename OtherDerType>
334  inline auto operator/(const AutoDiffScalar<OtherDerType>& other) const {
335  return MakeAutoDiffScalar(m_value / other.value(),
336  internal::MakeCoherentCwiseBinaryOp<internal::scalar_difference_op<Scalar>>(
337  m_derivatives * other.value(), (other.derivatives() * m_value)) *
338  (Scalar(1) / (other.value() * other.value())));
339  }
340 
341  template <typename OtherDerType>
342  inline auto operator*(const AutoDiffScalar<OtherDerType>& other) const {
343  return MakeAutoDiffScalar(m_value * other.value(),
344  internal::MakeCoherentCwiseBinaryOp<internal::scalar_sum_op<Scalar>>(
345  m_derivatives * other.value(), other.derivatives() * m_value));
346  }
347 
348  inline AutoDiffScalar& operator*=(const Scalar& other) {
349  *this = *this * other;
350  return *this;
351  }
352 
353  template <typename OtherDerType>
354  inline AutoDiffScalar& operator*=(const AutoDiffScalar<OtherDerType>& other) {
355  *this = *this * other;
356  return *this;
357  }
358 
359  inline AutoDiffScalar& operator/=(const Scalar& other) {
360  *this = *this / other;
361  return *this;
362  }
363 
364  template <typename OtherDerType>
365  inline AutoDiffScalar& operator/=(const AutoDiffScalar<OtherDerType>& other) {
366  *this = *this / other;
367  return *this;
368  }
369 
370  protected:
371  Scalar m_value;
372  DerType m_derivatives;
373 };
374 
375 namespace internal {
376 
377 template <typename DerivativeType>
378 struct auto_diff_special_op<DerivativeType, true>
379 // : auto_diff_scalar_op<DerivativeType, typename NumTraits<Scalar>::Real,
380 // is_same<Scalar,typename NumTraits<Scalar>::Real>::value>
381 {
382  typedef remove_all_t<DerivativeType> DerType;
383  typedef typename traits<DerType>::Scalar Scalar;
384  typedef typename NumTraits<Scalar>::Real Real;
385 
386  // typedef auto_diff_scalar_op<DerivativeType, typename NumTraits<Scalar>::Real,
387  // is_same<Scalar,typename NumTraits<Scalar>::Real>::value> Base;
388 
389  // using Base::operator+;
390  // using Base::operator+=;
391  // using Base::operator-;
392  // using Base::operator-=;
393  // using Base::operator*;
394  // using Base::operator*=;
395 
396  const AutoDiffScalar<DerivativeType>& derived() const {
397  return *static_cast<const AutoDiffScalar<DerivativeType>*>(this);
398  }
399  AutoDiffScalar<DerivativeType>& derived() { return *static_cast<AutoDiffScalar<DerivativeType>*>(this); }
400 
401  inline AutoDiffScalar<DerType&> operator+(const Real& other) const {
402  return AutoDiffScalar<DerType&>(derived().value() + other, derived().derivatives());
403  }
404 
405  friend inline AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar<DerivativeType>& b) {
406  return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
407  }
408 
409  inline AutoDiffScalar<DerivativeType>& operator+=(const Real& other) {
410  derived().value() += other;
411  return derived();
412  }
413 
414  inline AutoDiffScalar<typename CwiseUnaryOp<bind2nd_op<scalar_product_op<Scalar, Real>>, DerType>::Type> operator*(
415  const Real& other) const {
416  return AutoDiffScalar<typename CwiseUnaryOp<bind2nd_op<scalar_product_op<Scalar, Real>>, DerType>::Type>(
417  derived().value() * other, derived().derivatives() * other);
418  }
419 
420  friend inline AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real, Scalar>>, DerType>::Type>
421  operator*(const Real& other, const AutoDiffScalar<DerivativeType>& a) {
422  return AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real, Scalar>>, DerType>::Type>(
423  a.value() * other, a.derivatives() * other);
424  }
425 
426  inline AutoDiffScalar<DerivativeType>& operator*=(const Scalar& other) {
427  *this = *this * other;
428  return derived();
429  }
430 };
431 
432 template <typename DerivativeType>
433 struct auto_diff_special_op<DerivativeType, false> {
434  void operator*() const;
435  void operator-() const;
436  void operator+() const;
437 };
438 
439 } // end namespace internal
440 
441 template <typename DerType, typename BinOp>
442 struct ScalarBinaryOpTraits<AutoDiffScalar<DerType>, typename DerType::Scalar, BinOp> {
443  typedef AutoDiffScalar<DerType> ReturnType;
444 };
445 
446 template <typename DerType, typename BinOp>
447 struct ScalarBinaryOpTraits<typename DerType::Scalar, AutoDiffScalar<DerType>, BinOp> {
448  typedef AutoDiffScalar<DerType> ReturnType;
449 };
450 
451 // The following is an attempt to let Eigen's known about expression template, but that's more tricky!
452 
453 // template<typename DerType, typename BinOp>
454 // struct ScalarBinaryOpTraits<AutoDiffScalar<DerType>,AutoDiffScalar<DerType>, BinOp>
455 // {
456 // enum { Defined = 1 };
457 // typedef AutoDiffScalar<typename DerType::PlainObject> ReturnType;
458 // };
459 //
460 // template<typename DerType1,typename DerType2, typename BinOp>
461 // struct ScalarBinaryOpTraits<AutoDiffScalar<DerType1>,AutoDiffScalar<DerType2>, BinOp>
462 // {
463 // enum { Defined = 1 };//internal::is_same<typename DerType1::Scalar,typename DerType2::Scalar>::value };
464 // typedef AutoDiffScalar<typename DerType1::PlainObject> ReturnType;
465 // };
466 
467 #define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC, CODE) \
468  template <typename DerType> \
469  inline auto FUNC(const Eigen::AutoDiffScalar<DerType>& x) { \
470  using namespace Eigen; \
471  typedef typename Eigen::internal::traits<Eigen::internal::remove_all_t<DerType>>::Scalar Scalar; \
472  EIGEN_UNUSED_VARIABLE(sizeof(Scalar)); \
473  CODE; \
474  }
475 
476 template <typename DerType>
477 struct CleanedUpDerType {
478  typedef AutoDiffScalar<typename Eigen::internal::remove_all_t<DerType>::PlainObject> type;
479 };
480 
481 template <typename DerType>
482 inline const AutoDiffScalar<DerType>& conj(const AutoDiffScalar<DerType>& x) {
483  return x;
484 }
485 template <typename DerType>
486 inline const AutoDiffScalar<DerType>& real(const AutoDiffScalar<DerType>& x) {
487  return x;
488 }
489 template <typename DerType>
490 inline typename DerType::Scalar imag(const AutoDiffScalar<DerType>&) {
491  return 0.;
492 }
493 template <typename DerType, typename T>
494 inline typename CleanedUpDerType<DerType>::type(min)(const AutoDiffScalar<DerType>& x, const T& y) {
495  typedef typename CleanedUpDerType<DerType>::type ADS;
496  return (x <= y ? ADS(x) : ADS(y));
497 }
498 template <typename DerType, typename T>
499 inline typename CleanedUpDerType<DerType>::type(max)(const AutoDiffScalar<DerType>& x, const T& y) {
500  typedef typename CleanedUpDerType<DerType>::type ADS;
501  return (x >= y ? ADS(x) : ADS(y));
502 }
503 template <typename DerType, typename T>
504 inline typename CleanedUpDerType<DerType>::type(min)(const T& x, const AutoDiffScalar<DerType>& y) {
505  typedef typename CleanedUpDerType<DerType>::type ADS;
506  return (x < y ? ADS(x) : ADS(y));
507 }
508 template <typename DerType, typename T>
509 inline typename CleanedUpDerType<DerType>::type(max)(const T& x, const AutoDiffScalar<DerType>& y) {
510  typedef typename CleanedUpDerType<DerType>::type ADS;
511  return (x > y ? ADS(x) : ADS(y));
512 }
513 template <typename DerType>
514 inline
515  typename CleanedUpDerType<DerType>::type(min)(const AutoDiffScalar<DerType>& x, const AutoDiffScalar<DerType>& y) {
516  return (x.value() < y.value() ? x : y);
517 }
518 template <typename DerType>
519 inline
520  typename CleanedUpDerType<DerType>::type(max)(const AutoDiffScalar<DerType>& x, const AutoDiffScalar<DerType>& y) {
521  return (x.value() >= y.value() ? x : y);
522 }
523 
524 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs, using std::abs;
525  return Eigen::MakeAutoDiffScalar(abs(x.value()),
526  x.derivatives() * (x.value() < 0 ? -1 : 1));)
527 
528 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs2, using numext::abs2;
529  return Eigen::MakeAutoDiffScalar(abs2(x.value()),
530  x.derivatives() * (Scalar(2) * x.value()));)
531 
532 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sqrt, using std::sqrt; Scalar sqrtx = sqrt(x.value());
533  return Eigen::MakeAutoDiffScalar(sqrtx, x.derivatives() * (Scalar(0.5) / sqrtx));)
534 
535 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cos, using std::cos; using std::sin;
536  return Eigen::MakeAutoDiffScalar(cos(x.value()),
537  x.derivatives() * (-sin(x.value())));)
538 
539 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sin, using std::sin; using std::cos;
540  return Eigen::MakeAutoDiffScalar(sin(x.value()), x.derivatives() * cos(x.value()));)
541 
542 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(exp, using std::exp; Scalar expx = exp(x.value());
543  return Eigen::MakeAutoDiffScalar(expx, x.derivatives() * expx);)
544 
545 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log, using std::log;
546  return Eigen::MakeAutoDiffScalar(log(x.value()),
547  x.derivatives() * (Scalar(1) / x.value()));)
548 
549 template <typename DerType>
550 inline auto pow(const Eigen::AutoDiffScalar<DerType>& x,
551  const typename internal::traits<internal::remove_all_t<DerType>>::Scalar& y) {
552  using namespace Eigen;
553  using std::pow;
554  return Eigen::MakeAutoDiffScalar(pow(x.value(), y), x.derivatives() * (y * pow(x.value(), y - 1)));
555 }
556 
557 template <typename DerTypeA, typename DerTypeB>
560  using std::atan2;
561  typedef typename internal::traits<internal::remove_all_t<DerTypeA>>::Scalar Scalar;
563  PlainADS ret;
564  ret.value() = atan2(a.value(), b.value());
565 
566  Scalar squared_hypot = a.value() * a.value() + b.value() * b.value();
567 
568  // if (squared_hypot==0) the derivation is undefined and the following results in a NaN:
569  ret.derivatives() = (a.derivatives() * b.value() - a.value() * b.derivatives()) / squared_hypot;
570 
571  return ret;
572 }
573 
574 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tan, using std::tan; using std::cos; return Eigen::MakeAutoDiffScalar(
575  tan(x.value()), x.derivatives() * (Scalar(1) / numext::abs2(cos(x.value()))));)
576 
577 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(asin, using std::sqrt; using std::asin; return Eigen::MakeAutoDiffScalar(
578  asin(x.value()),
579  x.derivatives() * (Scalar(1) / sqrt(1 - numext::abs2(x.value()))));)
580 
581 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(acos, using std::sqrt; using std::acos; return Eigen::MakeAutoDiffScalar(
582  acos(x.value()),
583  x.derivatives() * (Scalar(-1) / sqrt(1 - numext::abs2(x.value()))));)
584 
585 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
586  tanh, using std::cosh; using std::tanh;
587  return Eigen::MakeAutoDiffScalar(tanh(x.value()), x.derivatives() * (Scalar(1) / numext::abs2(cosh(x.value()))));)
588 
589 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sinh, using std::sinh; using std::cosh;
590  return Eigen::MakeAutoDiffScalar(sinh(x.value()),
591  x.derivatives() * cosh(x.value()));)
592 
593 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cosh, using std::sinh; using std::cosh;
594  return Eigen::MakeAutoDiffScalar(cosh(x.value()),
595  x.derivatives() * sinh(x.value()));)
596 
597 #undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY
598 
599 template <typename DerType>
601  : NumTraits<typename NumTraits<typename internal::remove_all_t<DerType>::Scalar>::Real> {
602  typedef internal::remove_all_t<DerType> DerTypeCleaned;
604  DerTypeCleaned::RowsAtCompileTime, DerTypeCleaned::ColsAtCompileTime, 0,
605  DerTypeCleaned::MaxRowsAtCompileTime, DerTypeCleaned::MaxColsAtCompileTime>>
606  Real;
607  typedef AutoDiffScalar<DerType> NonInteger;
608  typedef AutoDiffScalar<DerType> Nested;
610  enum { RequireInitialization = 1 };
611 };
612 
613 namespace internal {
614 template <typename DerivativeType>
615 struct is_identically_zero_impl<AutoDiffScalar<DerivativeType>> {
616  static inline bool run(const AutoDiffScalar<DerivativeType>& s) {
617  const DerivativeType& derivatives = s.derivatives();
618  for (int i = 0; i < derivatives.size(); ++i) {
619  if (!numext::is_exactly_zero(derivatives[i])) {
620  return false;
621  }
622  }
623  return numext::is_exactly_zero(s.value());
624  }
625 };
626 } // namespace internal
627 } // namespace Eigen
628 
629 namespace std {
630 
631 template <typename T>
632 class numeric_limits<Eigen::AutoDiffScalar<T>> : public numeric_limits<typename T::Scalar> {};
633 
634 template <typename T>
635 class numeric_limits<Eigen::AutoDiffScalar<T&>> : public numeric_limits<typename T::Scalar> {};
636 
637 } // namespace std
638 
639 #endif // EIGEN_AUTODIFF_SCALAR_H
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_tanh_op< typename Derived::Scalar >, const Derived > tanh(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sinh_op< typename Derived::Scalar >, const Derived > sinh(const Eigen::ArrayBase< Derived > &x)
A scalar type replacement with automatic differentiation capability.
Definition: AutoDiffScalar.h:61
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)
Namespace containing all symbols from the Eigen library.
Definition: AutoDiffScalar.h:629
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_asin_op< typename Derived::Scalar >, const Derived > asin(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs2_op< typename Derived::Scalar >, const Derived > abs2(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_acos_op< typename Derived::Scalar >, const Derived > acos(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_cos_op< typename Derived::Scalar >, const Derived > cos(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_imag_op< typename Derived::Scalar >, const Derived > imag(const Eigen::ArrayBase< Derived > &x)
AutoDiffScalar(const Scalar &value, int nbDer, int derNumber)
Definition: AutoDiffScalar.h:119
AutoDiffScalar(const Real &value)
Definition: AutoDiffScalar.h:125
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_real_op< typename Derived::Scalar >, const Derived > real(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_cosh_op< typename Derived::Scalar >, const Derived > cosh(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log_op< typename Derived::Scalar >, const Derived > log(const Eigen::ArrayBase< Derived > &x)
AutoDiffScalar()
Definition: AutoDiffScalar.h:115
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_tan_op< typename Derived::Scalar >, const Derived > tan(const Eigen::ArrayBase< Derived > &x)
AutoDiffScalar(const Scalar &value, const DerType &der)
Definition: AutoDiffScalar.h:130
const int Dynamic
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sin_op< typename Derived::Scalar >, const Derived > sin(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_exp_op< typename Derived::Scalar >, const Derived > exp(const Eigen::ArrayBase< Derived > &x)
const Product< SparseDerived, PermDerived, AliasFreeProduct > operator*(const SparseMatrixBase< SparseDerived > &matrix, const PermutationBase< PermDerived > &perm)