autodiff_scalar.h
Go to the documentation of this file.
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 // Added support for SparseVector DerType
11 // Modification on lines 23, 552-585, 739-755, 806-819
12 
13 #ifndef EIGEN_AUTODIFF_SCALAR_H_
14 #define EIGEN_AUTODIFF_SCALAR_H_
15 
16 enum
17 {
19 };
20 
21 EIGEN_STATIC_ASSERT(EIGEN_VERSION_AT_LEAST(3, 3, 0), AUTODIFF_IS_SUPPORTED_ONLY_WITH_EIGEN_3_3_0_OR_ABOVE)
22 
23 #include <Eigen/SparseCore>
24 
25 namespace Eigen
26 {
27 namespace internal
28 {
29 template <typename A, typename B>
31 {
32  static void run(A&, B&) {}
33 };
34 
35 // resize a to match b is a.size()==0, and conversely.
36 template <typename A, typename B>
37 void make_coherent(const A& a, const B& b)
38 {
39  make_coherent_impl<A, B>::run(a.const_cast_derived(), b.const_cast_derived());
40 }
41 
42 template <typename _DerType, bool Enable>
44 
45 } // end namespace internal
46 
47 template <typename _DerType>
49 
50 template <typename NewDerType>
51 inline AutoDiffScalar<NewDerType> MakeAutoDiffScalar(const typename NewDerType::Scalar& value, const NewDerType& der)
52 {
53  return AutoDiffScalar<NewDerType>(value, der);
54 }
55 
56 // \class AutoDiffScalar
57 // \brief A scalar type replacement with automatic differentation capability
58 //
59 // \param _DerType the vector type used to store/represent the derivatives. The base scalar type
60 // as well as the number of derivatives to compute are determined from this type.
61 // Typical choices include, e.g., \c Vector4f for 4 derivatives, or \c VectorXf
62 // if the number of derivatives is not known at compile time, and/or, the number
63 // of derivatives is large.
64 // Note that _DerType can also be a reference (e.g., \c VectorXf&) to wrap a
65 // existing vector into an AutoDiffScalar.
66 // Finally, _DerType can also be any Eigen compatible expression.
67 //
68 // This class represents a scalar value while tracking its respective derivatives using Eigen's expression
69 // template mechanism.
70 //
71 // It supports the following list of global math function:
72 // - std::abs, std::sqrt, std::pow, std::exp, std::log, std::sin, std::cos,
73 // - internal::abs, internal::sqrt, numext::pow, internal::exp, internal::log, internal::sin, internal::cos,
74 // - internal::conj, internal::real, internal::imag, numext::abs2.
75 //
76 // AutoDiffScalar can be used as the scalar type of an Eigen::Matrix object. However,
77 // in that case, the expression template mechanism only occurs at the top Matrix level,
78 // while derivatives are computed right away.
79 
80 template <typename _DerType>
81 class AutoDiffScalar
82  : public internal::auto_diff_special_op<_DerType, !internal::is_same<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar,
83  typename NumTraits<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar>::Real>::value>
84 {
85 public:
87  typename NumTraits<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar>::Real>::value>
89  typedef typename internal::remove_all<_DerType>::type DerType;
90  typedef typename internal::traits<DerType>::Scalar Scalar;
91  typedef typename NumTraits<Scalar>::Real Real;
92 
93  using Base::operator+;
94  using Base::operator*;
95 
100  AutoDiffScalar(const Scalar& value, int nbDer, int derNumber)
101  : m_value(value), m_derivatives(DerType::Zero(nbDer))
102  {
103  m_derivatives.coeffRef(derNumber) = Scalar(1);
104  }
105 
108  /*explicit*/ AutoDiffScalar(const Real& value)
109  : m_value(value)
110  {
111  if (m_derivatives.size() > 0)
112  m_derivatives.setZero();
113  }
114 
116  AutoDiffScalar(const Scalar& value, const DerType& der)
117  : m_value(value), m_derivatives(der)
118  {
119  }
120 
121  template <typename OtherDerType>
123 #ifndef EIGEN_PARSED_BY_DOXYGEN
124  ,
125  typename internal::enable_if<
126  internal::is_same<Scalar, typename internal::traits<typename internal::remove_all<OtherDerType>::type>::Scalar>::value && internal::is_convertible<OtherDerType, DerType>::value, void*>::type = 0
127 #endif
128  )
129  : m_value(other.value()), m_derivatives(other.derivatives())
130  {
131  }
132 
133  friend std::ostream& operator<<(std::ostream& s, const AutoDiffScalar& a)
134  {
135  return s << a.value();
136  }
137 
139  : m_value(other.value()), m_derivatives(other.derivatives())
140  {
141  }
142 
143  template <typename OtherDerType>
145  {
146  m_value = other.value();
147  m_derivatives = other.derivatives();
148  return *this;
149  }
150 
152  {
153  m_value = other.value();
154  m_derivatives = other.derivatives();
155  return *this;
156  }
157 
158  inline AutoDiffScalar& operator=(const Scalar& other)
159  {
160  m_value = other;
161  if (m_derivatives.size() > 0)
162  m_derivatives.setZero();
163  return *this;
164  }
165 
166  // inline operator const Scalar& () const { return m_value; }
167  // inline operator Scalar& () { return m_value; }
168 
169  inline const Scalar& value() const { return m_value; }
170  inline Scalar& value() { return m_value; }
171  inline const DerType& derivatives() const { return m_derivatives; }
172  inline DerType& derivatives() { return m_derivatives; }
173  inline bool operator<(const Scalar& other) const { return m_value < other; }
174  inline bool operator<=(const Scalar& other) const { return m_value <= other; }
175  inline bool operator>(const Scalar& other) const { return m_value > other; }
176  inline bool operator>=(const Scalar& other) const { return m_value >= other; }
177  inline bool operator==(const Scalar& other) const { return m_value == other; }
178  inline bool operator!=(const Scalar& other) const { return m_value != other; }
179  friend inline bool operator<(const Scalar& a, const AutoDiffScalar& b) { return a < b.value(); }
180  friend inline bool operator<=(const Scalar& a, const AutoDiffScalar& b) { return a <= b.value(); }
181  friend inline bool operator>(const Scalar& a, const AutoDiffScalar& b) { return a > b.value(); }
182  friend inline bool operator>=(const Scalar& a, const AutoDiffScalar& b) { return a >= b.value(); }
183  friend inline bool operator==(const Scalar& a, const AutoDiffScalar& b) { return a == b.value(); }
184  friend inline bool operator!=(const Scalar& a, const AutoDiffScalar& b) { return a != b.value(); }
185  template <typename OtherDerType>
186  inline bool operator<(const AutoDiffScalar<OtherDerType>& b) const
187  {
188  return m_value < b.value();
189  }
190  template <typename OtherDerType>
191  inline bool operator<=(const AutoDiffScalar<OtherDerType>& b) const
192  {
193  return m_value <= b.value();
194  }
195  template <typename OtherDerType>
196  inline bool operator>(const AutoDiffScalar<OtherDerType>& b) const
197  {
198  return m_value > b.value();
199  }
200  template <typename OtherDerType>
201  inline bool operator>=(const AutoDiffScalar<OtherDerType>& b) const
202  {
203  return m_value >= b.value();
204  }
205  template <typename OtherDerType>
206  inline bool operator==(const AutoDiffScalar<OtherDerType>& b) const
207  {
208  return m_value == b.value();
209  }
210  template <typename OtherDerType>
211  inline bool operator!=(const AutoDiffScalar<OtherDerType>& b) const
212  {
213  return m_value != b.value();
214  }
215 
216  inline const AutoDiffScalar<DerType&> operator+(const Scalar& other) const
217  {
218  return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
219  }
220 
221  friend inline const AutoDiffScalar<DerType&> operator+(const Scalar& a, const AutoDiffScalar& b)
222  {
223  return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
224  }
225 
226  // inline const AutoDiffScalar<DerType&> operator+(const Real& other) const
227  // {
228  // return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
229  // }
230 
231  // friend inline const AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar& b)
232  // {
233  // return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
234  // }
235 
236  inline AutoDiffScalar& operator+=(const Scalar& other)
237  {
238  value() += other;
239  return *this;
240  }
241 
242  template <typename OtherDerType>
243  inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const DerType, const typename internal::remove_all<OtherDerType>::type>>
245  {
246  internal::make_coherent(m_derivatives, other.derivatives());
247  return AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const DerType, const typename internal::remove_all<OtherDerType>::type>>(
248  m_value + other.value(),
249  m_derivatives + other.derivatives());
250  }
251 
252  template <typename OtherDerType>
253  inline AutoDiffScalar&
255  {
256  (*this) = (*this) + other;
257  return *this;
258  }
259 
260  inline const AutoDiffScalar<DerType&> operator-(const Scalar& b) const
261  {
262  return AutoDiffScalar<DerType&>(m_value - b, m_derivatives);
263  }
264 
265  friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType>>
266  operator-(const Scalar& a, const AutoDiffScalar& b)
267  {
268  return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType>>(a - b.value(), -b.derivatives());
269  }
270 
271  inline AutoDiffScalar& operator-=(const Scalar& other)
272  {
273  value() -= other;
274  return *this;
275  }
276 
277  template <typename OtherDerType>
278  inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType, const typename internal::remove_all<OtherDerType>::type>>
280  {
281  internal::make_coherent(m_derivatives, other.derivatives());
282  return AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType, const typename internal::remove_all<OtherDerType>::type>>(
283  m_value - other.value(),
284  m_derivatives - other.derivatives());
285  }
286 
287  template <typename OtherDerType>
288  inline AutoDiffScalar&
290  {
291  this = *this - other;
292  return *this;
293  }
294 
295  inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType>>
296  operator-() const
297  {
298  return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType>>(
299  -m_value,
300  -m_derivatives);
301  }
302 
304  operator*(const Scalar& other) const
305  {
306  return MakeAutoDiffScalar(m_value * other, m_derivatives * other);
307  }
308 
310  operator*(const Scalar& other, const AutoDiffScalar& a)
311  {
312  return MakeAutoDiffScalar(a.value() * other, a.derivatives() * other);
313  }
314 
315  // inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
316  // operator*(const Real& other) const
317  // {
318  // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
319  // m_value * other,
320  // (m_derivatives * other));
321  // }
322  //
323  // friend inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
324  // operator*(const Real& other, const AutoDiffScalar& a)
325  // {
326  // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
327  // a.value() * other,
328  // a.derivatives() * other);
329  // }
330 
332  operator/(const Scalar& other) const
333  {
334  return MakeAutoDiffScalar(m_value / other, (m_derivatives * (Scalar(1) / other)));
335  }
336 
338  operator/(const Scalar& other, const AutoDiffScalar& a)
339  {
340  return MakeAutoDiffScalar(other / a.value(), a.derivatives() * (Scalar(-other) / (a.value() * a.value())));
341  }
342 
343  // inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
344  // operator/(const Real& other) const
345  // {
346  // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
347  // m_value / other,
348  // (m_derivatives * (Real(1)/other)));
349  // }
350  //
351  // friend inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
352  // operator/(const Real& other, const AutoDiffScalar& a)
353  // {
354  // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
355  // other / a.value(),
356  // a.derivatives() * (-Real(1)/other));
357  // }
358 
359  template <typename OtherDerType>
360  inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(
361  CwiseBinaryOp<internal::scalar_difference_op<Scalar> EIGEN_COMMA const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType, Scalar, product) EIGEN_COMMA const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<OtherDerType>::type, Scalar, product)>, Scalar, product)>
363  {
364  internal::make_coherent(m_derivatives, other.derivatives());
365  return MakeAutoDiffScalar(
366  m_value / other.value(),
367  ((m_derivatives * other.value()) - (other.derivatives() * m_value)) * (Scalar(1) / (other.value() * other.value())));
368  }
369 
370  template <typename OtherDerType>
372  const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType, Scalar, product),
373  const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<OtherDerType>::type, Scalar, product)>>
375  {
376  internal::make_coherent(m_derivatives, other.derivatives());
377  return MakeAutoDiffScalar(
378  m_value * other.value(),
379  (m_derivatives * other.value()) + (other.derivatives() * m_value));
380  }
381 
382  inline AutoDiffScalar& operator*=(const Scalar& other)
383  {
384  this = *this * other;
385  return *this;
386  }
387 
388  template <typename OtherDerType>
390  {
391  this = *this * other;
392  return *this;
393  }
394 
395  inline AutoDiffScalar& operator/=(const Scalar& other)
396  {
397  this = *this / other;
398  return *this;
399  }
400 
401  template <typename OtherDerType>
403  {
404  this = *this / other;
405  return *this;
406  }
407 
408 protected:
409  Scalar m_value;
410  DerType m_derivatives;
411 };
412 
413 namespace internal
414 {
415 template <typename _DerType>
416 struct auto_diff_special_op<_DerType, true>
417 // : auto_diff_scalar_op<_DerType, typename NumTraits<Scalar>::Real,
418 // is_same<Scalar,typename NumTraits<Scalar>::Real>::value>
419 {
420  typedef typename remove_all<_DerType>::type DerType;
421  typedef typename traits<DerType>::Scalar Scalar;
422  typedef typename NumTraits<Scalar>::Real Real;
423 
424  // typedef auto_diff_scalar_op<_DerType, typename NumTraits<Scalar>::Real,
425  // is_same<Scalar,typename NumTraits<Scalar>::Real>::value> Base;
426 
427  // using Base::operator+;
428  // using Base::operator+=;
429  // using Base::operator-;
430  // using Base::operator-=;
431  // using Base::operator*;
432  // using Base::operator*=;
433 
434  const AutoDiffScalar<_DerType>& derived() const { return *static_cast<const AutoDiffScalar<_DerType>*>(this); }
435  AutoDiffScalar<_DerType>& derived() { return *static_cast<AutoDiffScalar<_DerType>*>(this); }
436  inline const AutoDiffScalar<DerType&> operator+(const Real& other) const
437  {
438  return AutoDiffScalar<DerType&>(derived().value() + other, derived().derivatives());
439  }
440 
441  friend inline const AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar<_DerType>& b)
442  {
443  return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
444  }
445 
446  inline AutoDiffScalar<_DerType>& operator+=(const Real& other)
447  {
448  derived().value() += other;
449  return derived();
450  }
451 
453  operator*(const Real& other) const
454  {
456  derived().value() * other,
457  derived().derivatives() * other);
458  }
459 
461  operator*(const Real& other, const AutoDiffScalar<_DerType>& a)
462  {
463  return AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real, Scalar>>, DerType>::Type>(
464  a.value() * other,
465  a.derivatives() * other);
466  }
467 
468  inline AutoDiffScalar<_DerType>& operator*=(const Scalar& other)
469  {
470  this = *this * other;
471  return derived();
472  }
473 };
474 
475 template <typename _DerType>
476 struct auto_diff_special_op<_DerType, false>
477 {
478  void operator*() const;
479  void operator-() const;
480  void operator+() const;
481 };
482 
483 template <typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols, typename B>
484 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>, B>
485 {
486  typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
487  static void run(A& a, B& b)
488  {
489  if ((A_Rows == Dynamic || A_Cols == Dynamic) && (a.size() == 0))
490  {
491  a.resize(b.size());
492  a.setZero();
493  }
494  eigen_assert(a.size() == b.size() && "Eigen::AutoDiffScalar: derivatives are not compatible.");
495  }
496 };
497 
498 template <typename A, typename B_Scalar, int B_Rows, int B_Cols, int B_Options, int B_MaxRows, int B_MaxCols>
499 struct make_coherent_impl<A, Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols>>
500 {
501  typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
502  static void run(A& a, B& b)
503  {
504  if ((B_Rows == Dynamic || B_Cols == Dynamic) && (b.size() == 0))
505  {
506  b.resize(a.size());
507  b.setZero();
508  }
509  eigen_assert(a.size() == b.size() && "Eigen::AutoDiffScalar: derivatives are not compatible.");
510  }
511 };
512 
513 template <typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols,
514  typename B_Scalar, int B_Rows, int B_Cols, int B_Options, int B_MaxRows, int B_MaxCols>
515 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>,
516  Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols>>
517 {
518  typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
519  typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
520  static void run(A& a, B& b)
521  {
522  if ((A_Rows == Dynamic || A_Cols == Dynamic) && (a.size() == 0))
523  {
524  a.resize(b.size());
525  a.setZero();
526  }
527  else if ((B_Rows == Dynamic || B_Cols == Dynamic) && (b.size() == 0))
528  {
529  b.resize(a.size());
530  b.setZero();
531  }
532  eigen_assert(a.size() == b.size() && "Eigen::AutoDiffScalar: derivatives are not compatible.");
533  }
534 };
535 
536 template <typename A_Scalar, int A_Options, typename A_Index, typename B>
537 struct make_coherent_impl<SparseVector<A_Scalar, A_Options, A_Index>, B>
538 {
539  typedef SparseVector<A_Scalar, A_Options, A_Index> A;
540  static void run(A& a, B& b)
541  {
542  if (a.size() == 0)
543  {
544  a.resize(b.size());
545  }
546  eigen_assert(a.size() == b.size() && "Eigen::AutoDiffScalar: derivatives are not compatible.");
547  }
548 };
549 
550 template <typename A, typename B_Scalar, int B_Options, typename B_Index>
551 struct make_coherent_impl<A, SparseVector<B_Scalar, B_Options, B_Index>>
552 {
553  typedef SparseVector<B_Scalar, B_Options, B_Index> B;
554  static void run(A& a, B& b)
555  {
556  if (b.size() == 0)
557  {
558  b.resize(a.size());
559  }
560  eigen_assert(a.size() == b.size() && "Eigen::AutoDiffScalar: derivatives are not compatible.");
561  }
562 };
563 
564 template <typename A_Scalar, int A_Options, typename A_Index,
565  typename B_Scalar, int B_Options, typename B_Index>
566 struct make_coherent_impl<SparseVector<A_Scalar, A_Options, A_Index>,
567  SparseVector<B_Scalar, B_Options, B_Index>>
568 {
569  typedef SparseVector<A_Scalar, A_Options, A_Index> A;
570  typedef SparseVector<B_Scalar, B_Options, B_Index> B;
571  static void run(A& a, B& b)
572  {
573  if (a.size() == 0)
574  {
575  a.resize(b.size());
576  }
577  else if (b.size() == 0)
578  {
579  b.resize(a.size());
580  }
581  eigen_assert(a.size() == b.size() && "Eigen::AutoDiffScalar: derivatives are not compatible.");
582  }
583 };
584 
585 } // end namespace internal
586 
587 template <typename DerType, typename BinOp>
588 struct ScalarBinaryOpTraits<AutoDiffScalar<DerType>, typename DerType::Scalar, BinOp>
589 {
591 };
592 
593 template <typename DerType, typename BinOp>
594 struct ScalarBinaryOpTraits<typename DerType::Scalar, AutoDiffScalar<DerType>, BinOp>
595 {
597 };
598 
599 // The following is an attempt to let Eigen's known about expression template, but that's more tricky!
600 
601 // template<typename DerType, typename BinOp>
602 // struct ScalarBinaryOpTraits<AutoDiffScalar<DerType>,AutoDiffScalar<DerType>, BinOp>
603 // {
604 // enum { Defined = 1 };
605 // typedef AutoDiffScalar<typename DerType::PlainObject> ReturnType;
606 // };
607 //
608 // template<typename DerType1,typename DerType2, typename BinOp>
609 // struct ScalarBinaryOpTraits<AutoDiffScalar<DerType1>,AutoDiffScalar<DerType2>, BinOp>
610 // {
611 // enum { Defined = 1 };//internal::is_same<typename DerType1::Scalar,typename DerType2::Scalar>::value };
612 // typedef AutoDiffScalar<typename DerType1::PlainObject> ReturnType;
613 // };
614 
615 #define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC, CODE) \
616  template <typename DerType> \
617  inline const Eigen::AutoDiffScalar< \
618  EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename Eigen::internal::remove_all<DerType>::type, typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar, product)> \
619  FUNC(const Eigen::AutoDiffScalar<DerType>& x) \
620  { \
621  using namespace Eigen; \
622  typedef typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar Scalar; \
623  EIGEN_UNUSED_VARIABLE(sizeof(Scalar)); \
624  CODE; \
625  }
626 
627 template <typename DerType>
629 {
630  return x;
631 }
632 template <typename DerType>
634 {
635  return x;
636 }
637 template <typename DerType>
638 inline typename DerType::Scalar imag(const AutoDiffScalar<DerType>&)
639 {
640  return 0.;
641 }
642 template <typename DerType, typename T>
644 {
646  return (x <= y ? ADS(x) : ADS(y));
647 }
648 template <typename DerType, typename T>
650 {
652  return (x >= y ? ADS(x) : ADS(y));
653 }
654 template <typename DerType, typename T>
656 {
658  return (x < y ? ADS(x) : ADS(y));
659 }
660 template <typename DerType, typename T>
662 {
664  return (x > y ? ADS(x) : ADS(y));
665 }
666 template <typename DerType>
668 {
669  return (x.value() < y.value() ? x : y);
670 }
671 template <typename DerType>
673 {
674  return (x.value() >= y.value() ? x : y);
675 }
676 
678  using std::abs;
679  return Eigen::MakeAutoDiffScalar(abs(x.value()), x.derivatives() * (x.value() < 0 ? -1 : 1));)
680 
682  using numext::abs2;
683  return Eigen::MakeAutoDiffScalar(abs2(x.value()), x.derivatives() * (Scalar(2) * x.value()));)
684 
686  using std::sqrt;
687  Scalar sqrtx = sqrt(x.value());
688  return Eigen::MakeAutoDiffScalar(sqrtx, x.derivatives() * (Scalar(0.5) / sqrtx));)
689 
691  using std::cos;
692  using std::sin;
693  return Eigen::MakeAutoDiffScalar(cos(x.value()), x.derivatives() * (-sin(x.value())));)
694 
696  using std::sin;
697  using std::cos;
698  return Eigen::MakeAutoDiffScalar(sin(x.value()), x.derivatives() * cos(x.value()));)
699 
701  using std::exp;
702  Scalar expx = exp(x.value());
703  return Eigen::MakeAutoDiffScalar(expx, x.derivatives() * expx);)
704 
706  using std::log;
707  return Eigen::MakeAutoDiffScalar(log(x.value()), x.derivatives() * (Scalar(1) / x.value()));)
708 
709 template <typename DerType>
710 inline const Eigen::AutoDiffScalar<
711  EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<DerType>::type, typename internal::traits<typename internal::remove_all<DerType>::type>::Scalar, product)>
712 pow(const Eigen::AutoDiffScalar<DerType>& x, const typename internal::traits<typename internal::remove_all<DerType>::type>::Scalar& y)
713 {
714  using namespace Eigen;
715  using std::pow;
716  return Eigen::MakeAutoDiffScalar(pow(x.value(), y), x.derivatives() * (y * pow(x.value(), y - 1)));
717 }
718 
719 template <typename DerTypeA, typename DerTypeB>
722 {
723  using std::atan2;
724  typedef typename internal::traits<typename internal::remove_all<DerTypeA>::type>::Scalar Scalar;
726  PlainADS ret;
727  ret.value() = atan2(a.value(), b.value());
728 
729  Scalar squared_hypot = a.value() * a.value() + b.value() * b.value();
730 
731  // if (squared_hypot==0) the derivation is undefined and the following results in a NaN:
732  ret.derivatives() = (a.derivatives() * b.value() - a.value() * b.derivatives()) / squared_hypot;
733 
734  return ret;
735 }
736 
737 template <typename DerTypeA, typename DerTypeB>
740 {
741  using std::atan2;
742  typedef typename internal::traits<typename internal::remove_all<DerTypeA>::type>::Scalar Scalar;
743  typedef AutoDiffScalar<SparseVector<Scalar>> PlainADS;
744  PlainADS ret;
745  ret.value() = atan2(a.value(), b.value());
746 
747  Scalar squared_hypot = a.value() * a.value() + b.value() * b.value();
748 
749  // if (squared_hypot==0) the derivation is undefined and the following results in a NaN:
750  ret.derivatives() = (a.derivatives() * b.value() - a.value() * b.derivatives()) / squared_hypot;
751 
752  return ret;
753 }
754 
756  using std::tan;
757  using std::cos;
758  return Eigen::MakeAutoDiffScalar(tan(x.value()), x.derivatives() * (Scalar(1) / numext::abs2(cos(x.value()))));)
759 
761  using std::sqrt;
762  using std::asin;
763  return Eigen::MakeAutoDiffScalar(asin(x.value()), x.derivatives() * (Scalar(1) / sqrt(1 - numext::abs2(x.value()))));)
764 
766  using std::sqrt;
767  using std::acos;
768  return Eigen::MakeAutoDiffScalar(acos(x.value()), x.derivatives() * (Scalar(-1) / sqrt(1 - numext::abs2(x.value()))));)
769 
771  using std::cosh;
772  using std::tanh;
773  return Eigen::MakeAutoDiffScalar(tanh(x.value()), x.derivatives() * (Scalar(1) / numext::abs2(cosh(x.value()))));)
774 
776  using std::sinh;
777  using std::cosh;
778  return Eigen::MakeAutoDiffScalar(sinh(x.value()), x.derivatives() * cosh(x.value()));)
779 
781  using std::sinh;
782  using std::cosh;
783  return Eigen::MakeAutoDiffScalar(cosh(x.value()), x.derivatives() * sinh(x.value()));)
784 
786 
787 template <typename DerType>
788 struct NumTraits<AutoDiffScalar<DerType>>
789  : NumTraits<typename NumTraits<typename internal::remove_all<DerType>::type::Scalar>::Real>
790 {
791  typedef typename internal::remove_all<DerType>::type DerTypeCleaned;
792  typedef AutoDiffScalar<Matrix<typename NumTraits<typename DerTypeCleaned::Scalar>::Real, DerTypeCleaned::RowsAtCompileTime, DerTypeCleaned::ColsAtCompileTime,
793  0, DerTypeCleaned::MaxRowsAtCompileTime, DerTypeCleaned::MaxColsAtCompileTime>>
797  typedef typename NumTraits<typename DerTypeCleaned::Scalar>::Literal Literal;
798  enum
799  {
800  RequireInitialization = 1
801  };
802 };
803 
804 template <typename DerType_>
805 struct NumTraits<AutoDiffScalar<SparseVector<DerType_>>>
806  : NumTraits<typename NumTraits<typename internal::remove_all<SparseVector<DerType_>>::type::Scalar>::Real>
807 {
808  typedef typename internal::remove_all<SparseVector<DerType_>>::type DerTypeCleaned;
809  typedef AutoDiffScalar<SparseVector<typename NumTraits<typename DerTypeCleaned::Scalar>::Real, DerTypeCleaned::Options, typename DerTypeCleaned::StorageIndex>> Real;
812  typedef typename NumTraits<typename DerTypeCleaned::Scalar>::Literal Literal;
813  enum
814  {
815  RequireInitialization = 1
816  };
817 };
818 } // namespace Eigen
819 
820 namespace std
821 {
822 template <typename T>
823 class numeric_limits<Eigen::AutoDiffScalar<T>>
824  : public numeric_limits<typename T::Scalar>
825 {
826 };
827 
828 template <typename T>
829 class numeric_limits<Eigen::AutoDiffScalar<T&>>
830  : public numeric_limits<typename T::Scalar>
831 {
832 };
833 } // namespace std
834 
835 #endif // EIGEN_AUTODIFF_SCALAR_H_
bool operator==(const Scalar &other) const
AutoDiffScalar(const Scalar &value, int nbDer, int derNumber)
friend const AutoDiffScalar< CwiseUnaryOp< internal::scalar_opposite_op< Scalar >, const DerType > > operator-(const Scalar &a, const AutoDiffScalar &b)
const AutoDiffScalar< CwiseBinaryOp< internal::scalar_sum_op< Scalar >, const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType, Scalar, product), const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all< OtherDerType >::type, Scalar, product)> > operator*(const AutoDiffScalar< OtherDerType > &other) const
AutoDiffScalar & operator*=(const AutoDiffScalar< OtherDerType > &other)
const AutoDiffScalar< DerType > & conj(const AutoDiffScalar< DerType > &x)
internal::remove_all< _DerType >::type DerType
internal::auto_diff_special_op< _DerType,!internal::is_same< typename internal::traits< typename internal::remove_all< _DerType >::type >::Scalar, typename NumTraits< typename internal::traits< typename internal::remove_all< _DerType >::type >::Scalar >::Real >::value > Base
AutoDiffScalar< SparseVector< DerType_ > > Nested
Type
EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs, using std::abs;return Eigen::MakeAutoDiffScalar(abs(x.value()), x.derivatives()*(x.value()< 0?-1:1));) EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs2
internal::remove_all< SparseVector< DerType_ > >::type DerTypeCleaned
const AutoDiffScalar< typename CwiseUnaryOp< bind2nd_op< scalar_product_op< Scalar, Real > >, DerType >::Type > operator*(const Real &other) const
Scalar expx
friend bool operator<(const Scalar &a, const AutoDiffScalar &b)
INLINE Rall1d< T, V, S > log(const Rall1d< T, V, S > &arg)
AutoDiffScalar & operator+=(const AutoDiffScalar< OtherDerType > &other)
void make_coherent(const A &a, const B &b)
AutoDiffScalar(const AutoDiffScalar< OtherDerType > &other, typename internal::enable_if< internal::is_same< Scalar, typename internal::traits< typename internal::remove_all< OtherDerType >::type >::Scalar >::value &&internal::is_convertible< OtherDerType, DerType >::value, void * >::type=0)
INLINE Rall1d< T, V, S > cosh(const Rall1d< T, V, S > &arg)
DerType::Scalar imag(const AutoDiffScalar< DerType > &)
const AutoDiffScalar< CwiseBinaryOp< internal::scalar_difference_op< Scalar >, const DerType, const typename internal::remove_all< OtherDerType >::type > > operator-(const AutoDiffScalar< OtherDerType > &other) const
AutoDiffScalar< _DerType > & operator+=(const Real &other)
const AutoDiffScalar< DerType & > operator+(const Real &other) const
AutoDiffScalar< SparseVector< typename NumTraits< typename DerTypeCleaned::Scalar >::Real, DerTypeCleaned::Options, typename DerTypeCleaned::StorageIndex > > Real
const AutoDiffScalar< EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType, Scalar, product)> operator/(const Scalar &other) const
AutoDiffScalar & operator-=(const AutoDiffScalar< OtherDerType > &other)
INLINE Rall1d< T, V, S > sinh(const Rall1d< T, V, S > &arg)
friend bool operator!=(const Scalar &a, const AutoDiffScalar &b)
bool operator<(const Scalar &other) const
const AutoDiffScalar< EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType, Scalar, product)> operator*(const Scalar &other) const
const AutoDiffScalar< DerType & > operator+(const Scalar &other) const
friend const AutoDiffScalar< DerType & > operator+(const Real &a, const AutoDiffScalar< _DerType > &b)
INLINE Rall1d< T, V, S > tanh(const Rall1d< T, V, S > &arg)
AutoDiffScalar & operator/=(const Scalar &other)
NumTraits< Scalar >::Real Real
AutoDiffScalar & operator=(const AutoDiffScalar &other)
const AutoDiffScalar< DerType & > operator-(const Scalar &b) const
const AutoDiffScalar< EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(CwiseBinaryOp< internal::scalar_difference_op< Scalar > EIGEN_COMMA const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType, Scalar, product) EIGEN_COMMA const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all< OtherDerType >::type, Scalar, product)>, Scalar, product)> operator/(const AutoDiffScalar< OtherDerType > &other) const
AutoDiffScalar< Matrix< typename NumTraits< typename DerTypeCleaned::Scalar >::Real, DerTypeCleaned::RowsAtCompileTime, DerTypeCleaned::ColsAtCompileTime, 0, DerTypeCleaned::MaxRowsAtCompileTime, DerTypeCleaned::MaxColsAtCompileTime > > Real
bool operator<=(const Scalar &other) const
INLINE Rall1d< T, V, S > asin(const Rall1d< T, V, S > &x)
friend bool operator>(const Scalar &a, const AutoDiffScalar &b)
internal::traits< DerType >::Scalar Scalar
AutoDiffScalar(const Real &value)
AutoDiffScalar< _DerType > & operator*=(const Scalar &other)
bool operator!=(const AutoDiffScalar< OtherDerType > &b) const
friend bool operator<=(const Scalar &a, const AutoDiffScalar &b)
AutoDiffScalar< NewDerType > MakeAutoDiffScalar(const typename NewDerType::Scalar &value, const NewDerType &der)
double min(double a, double b)
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
AutoDiffScalar & operator=(const Scalar &other)
NumTraits< typename DerTypeCleaned::Scalar >::Literal Literal
const AutoDiffScalar< Matrix< typename internal::traits< typename internal::remove_all< DerTypeA >::type >::Scalar, Dynamic, 1 > > atan2(const AutoDiffScalar< DerTypeA > &a, const AutoDiffScalar< DerTypeB > &b)
const AutoDiffScalar< _DerType > & derived() const
friend const AutoDiffScalar< DerType & > operator+(const Scalar &a, const AutoDiffScalar &b)
INLINE Rall1d< T, V, S > exp(const Rall1d< T, V, S > &arg)
const AutoDiffScalar< CwiseUnaryOp< internal::scalar_opposite_op< Scalar >, const DerType > > operator-() const
bool operator>=(const Scalar &other) const
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
AutoDiffScalar & operator=(const AutoDiffScalar< OtherDerType > &other)
friend bool operator==(const Scalar &a, const AutoDiffScalar &b)
INLINE Rall1d< T, V, S > acos(const Rall1d< T, V, S > &x)
INLINE Rall1d< T, V, S > abs(const Rall1d< T, V, S > &x)
const DerType & derivatives() const
bool operator>=(const AutoDiffScalar< OtherDerType > &b) const
friend const AutoDiffScalar< typename CwiseUnaryOp< bind1st_op< scalar_product_op< Real, Scalar > >, DerType >::Type > operator*(const Real &other, const AutoDiffScalar< _DerType > &a)
const AutoDiffScalar< CwiseBinaryOp< internal::scalar_sum_op< Scalar >, const DerType, const typename internal::remove_all< OtherDerType >::type > > operator+(const AutoDiffScalar< OtherDerType > &other) const
friend const AutoDiffScalar< EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType, Scalar, product)> operator/(const Scalar &other, const AutoDiffScalar &a)
friend std::ostream & operator<<(std::ostream &s, const AutoDiffScalar &a)
AutoDiffScalar & operator-=(const Scalar &other)
const Scalar & value() const
internal::remove_all< DerType >::type DerTypeCleaned
NumTraits< typename DerTypeCleaned::Scalar >::Literal Literal
bool operator==(const AutoDiffScalar< OtherDerType > &b) const
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > tan(const Rall1d< T, V, S > &arg)
AutoDiffScalar(const Scalar &value, const DerType &der)
AutoDiffScalar & operator+=(const Scalar &other)
bool operator>(const Scalar &other) const
AutoDiffScalar(const AutoDiffScalar &other)
bool operator!=(const Scalar &other) const
friend const AutoDiffScalar< EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType, Scalar, product)> operator*(const Scalar &other, const AutoDiffScalar &a)
const AutoDiffScalar< DerType > & real(const AutoDiffScalar< DerType > &x)
AutoDiffScalar & operator/=(const AutoDiffScalar< OtherDerType > &other)
double x
double max(double a, double b)
const AutoDiffScalar< SparseVector< typename internal::traits< typename internal::remove_all< DerTypeA >::type >::Scalar > > atan2(const AutoDiffScalar< DerTypeA > &a, const AutoDiffScalar< DerTypeB > &b)
friend bool operator>=(const Scalar &a, const AutoDiffScalar &b)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
bool operator>(const AutoDiffScalar< OtherDerType > &b) const
AutoDiffScalar & operator*=(const Scalar &other)
const T & y
AutoDiffScalar< SparseVector< DerType_ > > NonInteger


exotica_core
Author(s): Yiming Yang, Michael Camilleri
autogenerated on Sat Apr 10 2021 02:34:49