Eigen-unsupported  3.4.90 (git rev 67eeba6e720c5745abc77ae6c92ce0a44aa7b7ae)
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 #include "./InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
17 namespace internal {
18 
19 template<typename A, typename B>
20 struct make_coherent_impl {
21  static void run(A&, B&) {}
22 };
23 
24 // resize a to match b is a.size()==0, and conversely.
25 template<typename A, typename B>
26 void make_coherent(const A& a, const B&b)
27 {
28  make_coherent_impl<A,B>::run(a.const_cast_derived(), b.const_cast_derived());
29 }
30 
31 template<typename DerivativeType, bool Enable> struct auto_diff_special_op;
32 
33 } // end namespace internal
34 
35 template<typename DerivativeType> class AutoDiffScalar;
36 
37 template<typename NewDerType>
38 inline AutoDiffScalar<NewDerType> MakeAutoDiffScalar(const typename NewDerType::Scalar& value, const NewDerType &der) {
39  return AutoDiffScalar<NewDerType>(value,der);
40 }
41 
68 template<typename DerivativeType>
70  : public internal::auto_diff_special_op
71  <DerivativeType, !internal::is_same<typename internal::traits<internal::remove_all_t<DerivativeType>>::Scalar,
72  typename NumTraits<typename internal::traits<internal::remove_all_t<DerivativeType>>::Scalar>::Real>::value>
73 {
74  public:
75  typedef internal::auto_diff_special_op
76  <DerivativeType, !internal::is_same<typename internal::traits<internal::remove_all_t<DerivativeType>>::Scalar,
78  typedef internal::remove_all_t<DerivativeType> DerType;
79  typedef typename internal::traits<DerType>::Scalar Scalar;
80  typedef typename NumTraits<Scalar>::Real Real;
81 
82  using Base::operator+;
83  using Base::operator*;
84 
87 
90  AutoDiffScalar(const Scalar& value, int nbDer, int derNumber)
91  : m_value(value), m_derivatives(DerType::Zero(nbDer))
92  {
93  m_derivatives.coeffRef(derNumber) = Scalar(1);
94  }
95 
98  /*explicit*/ AutoDiffScalar(const Real& value)
99  : m_value(value)
100  {
101  if(m_derivatives.size()>0)
102  m_derivatives.setZero();
103  }
104 
106  AutoDiffScalar(const Scalar& value, const DerType& der)
107  : m_value(value), m_derivatives(der)
108  {}
109 
110  template<typename OtherDerType>
112 #ifndef EIGEN_PARSED_BY_DOXYGEN
113  , std::enable_if_t<
114  internal::is_same<Scalar, typename internal::traits<internal::remove_all_t<OtherDerType>>::Scalar>::value
115  && internal::is_convertible<OtherDerType,DerType>::value , void*> = 0
116 #endif
117  )
118  : m_value(other.value()), m_derivatives(other.derivatives())
119  {}
120 
121  friend std::ostream & operator << (std::ostream & s, const AutoDiffScalar& a)
122  {
123  return s << a.value();
124  }
125 
126  AutoDiffScalar(const AutoDiffScalar& other)
127  : m_value(other.value()), m_derivatives(other.derivatives())
128  {}
129 
130  template<typename OtherDerType>
131  inline AutoDiffScalar& operator=(const AutoDiffScalar<OtherDerType>& other)
132  {
133  m_value = other.value();
134  m_derivatives = other.derivatives();
135  return *this;
136  }
137 
138  inline AutoDiffScalar& operator=(const AutoDiffScalar& other)
139  {
140  m_value = other.value();
141  m_derivatives = other.derivatives();
142  return *this;
143  }
144 
145  inline AutoDiffScalar& operator=(const Scalar& other)
146  {
147  m_value = other;
148  if(m_derivatives.size()>0)
149  m_derivatives.setZero();
150  return *this;
151  }
152 
153 // inline operator const Scalar& () const { return m_value; }
154 // inline operator Scalar& () { return m_value; }
155 
156  inline const Scalar& value() const { return m_value; }
157  inline Scalar& value() { return m_value; }
158 
159  inline const DerType& derivatives() const { return m_derivatives; }
160  inline DerType& derivatives() { return m_derivatives; }
161 
162  inline bool operator< (const Scalar& other) const { return m_value < other; }
163  inline bool operator<=(const Scalar& other) const { return m_value <= other; }
164  inline bool operator> (const Scalar& other) const { return m_value > other; }
165  inline bool operator>=(const Scalar& other) const { return m_value >= other; }
166  inline bool operator==(const Scalar& other) const { return m_value == other; }
167  inline bool operator!=(const Scalar& other) const { return m_value != other; }
168 
169  friend inline bool operator< (const Scalar& a, const AutoDiffScalar& b) { return a < b.value(); }
170  friend inline bool operator<=(const Scalar& a, const AutoDiffScalar& b) { return a <= b.value(); }
171  friend inline bool operator> (const Scalar& a, const AutoDiffScalar& b) { return a > b.value(); }
172  friend inline bool operator>=(const Scalar& a, const AutoDiffScalar& b) { return a >= b.value(); }
173  friend inline bool operator==(const Scalar& a, const AutoDiffScalar& b) { return a == b.value(); }
174  friend inline bool operator!=(const Scalar& a, const AutoDiffScalar& b) { return a != b.value(); }
175 
176  template<typename OtherDerType> inline bool operator< (const AutoDiffScalar<OtherDerType>& b) const { return m_value < b.value(); }
177  template<typename OtherDerType> inline bool operator<=(const AutoDiffScalar<OtherDerType>& b) const { return m_value <= b.value(); }
178  template<typename OtherDerType> inline bool operator> (const AutoDiffScalar<OtherDerType>& b) const { return m_value > b.value(); }
179  template<typename OtherDerType> inline bool operator>=(const AutoDiffScalar<OtherDerType>& b) const { return m_value >= b.value(); }
180  template<typename OtherDerType> inline bool operator==(const AutoDiffScalar<OtherDerType>& b) const { return m_value == b.value(); }
181  template<typename OtherDerType> inline bool operator!=(const AutoDiffScalar<OtherDerType>& b) const { return m_value != b.value(); }
182 
183  inline AutoDiffScalar<DerType&> operator+(const Scalar& other) const
184  {
185  return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
186  }
187 
188  friend inline AutoDiffScalar<DerType&> operator+(const Scalar& a, const AutoDiffScalar& b)
189  {
190  return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
191  }
192 
193 // inline const AutoDiffScalar<DerType&> operator+(const Real& other) const
194 // {
195 // return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
196 // }
197 
198 // friend inline const AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar& b)
199 // {
200 // return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
201 // }
202 
203  inline AutoDiffScalar& operator+=(const Scalar& other)
204  {
205  value() += other;
206  return *this;
207  }
208 
209  template<typename OtherDerType>
210  inline AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,const DerType,const internal::remove_all_t<OtherDerType>> >
211  operator+(const AutoDiffScalar<OtherDerType>& other) const
212  {
213  internal::make_coherent(m_derivatives, other.derivatives());
214  return AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,const DerType,const internal::remove_all_t<OtherDerType>> >(
215  m_value + other.value(),
216  m_derivatives + other.derivatives());
217  }
218 
219  template<typename OtherDerType>
220  inline AutoDiffScalar&
221  operator+=(const AutoDiffScalar<OtherDerType>& other)
222  {
223  (*this) = (*this) + other;
224  return *this;
225  }
226 
227  inline AutoDiffScalar<DerType&> operator-(const Scalar& b) const
228  {
229  return AutoDiffScalar<DerType&>(m_value - b, m_derivatives);
230  }
231 
232  friend inline AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
233  operator-(const Scalar& a, const AutoDiffScalar& b)
234  {
235  return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
236  (a - b.value(), -b.derivatives());
237  }
238 
239  inline AutoDiffScalar& operator-=(const Scalar& other)
240  {
241  value() -= other;
242  return *this;
243  }
244 
245  template<typename OtherDerType>
246  inline AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType,const internal::remove_all_t<OtherDerType>> >
247  operator-(const AutoDiffScalar<OtherDerType>& other) const
248  {
249  internal::make_coherent(m_derivatives, other.derivatives());
250  return AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType,const internal::remove_all_t<OtherDerType>> >(
251  m_value - other.value(),
252  m_derivatives - other.derivatives());
253  }
254 
255  template<typename OtherDerType>
256  inline AutoDiffScalar&
257  operator-=(const AutoDiffScalar<OtherDerType>& other)
258  {
259  *this = *this - other;
260  return *this;
261  }
262 
263  inline AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
264  operator-() const
265  {
266  return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >(
267  -m_value,
268  -m_derivatives);
269  }
270 
271  inline AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
272  operator*(const Scalar& other) const
273  {
274  return MakeAutoDiffScalar(m_value * other, m_derivatives * other);
275  }
276 
277  friend inline AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
278  operator*(const Scalar& other, const AutoDiffScalar& a)
279  {
280  return MakeAutoDiffScalar(a.value() * other, a.derivatives() * other);
281  }
282 
283 // inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
284 // operator*(const Real& other) const
285 // {
286 // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
287 // m_value * other,
288 // (m_derivatives * other));
289 // }
290 //
291 // friend inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
292 // operator*(const Real& other, const AutoDiffScalar& a)
293 // {
294 // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
295 // a.value() * other,
296 // a.derivatives() * other);
297 // }
298 
299  inline AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
300  operator/(const Scalar& other) const
301  {
302  return MakeAutoDiffScalar(m_value / other, (m_derivatives * (Scalar(1)/other)));
303  }
304 
305  friend inline AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
306  operator/(const Scalar& other, const AutoDiffScalar& a)
307  {
308  return MakeAutoDiffScalar(other / a.value(), a.derivatives() * (Scalar(-other) / (a.value()*a.value())));
309  }
310 
311 // inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
312 // operator/(const Real& other) const
313 // {
314 // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
315 // m_value / other,
316 // (m_derivatives * (Real(1)/other)));
317 // }
318 //
319 // friend inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
320 // operator/(const Real& other, const AutoDiffScalar& a)
321 // {
322 // return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
323 // other / a.value(),
324 // a.derivatives() * (-Real(1)/other));
325 // }
326 
327  template<typename OtherDerType>
328  inline AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(
329  CwiseBinaryOp<internal::scalar_difference_op<Scalar> EIGEN_COMMA
330  const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) EIGEN_COMMA
331  const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(internal::remove_all_t<OtherDerType>,Scalar,product) >,Scalar,product) >
332  operator/(const AutoDiffScalar<OtherDerType>& other) const
333  {
334  internal::make_coherent(m_derivatives, other.derivatives());
335  return MakeAutoDiffScalar(
336  m_value / other.value(),
337  ((m_derivatives * other.value()) - (other.derivatives() * m_value))
338  * (Scalar(1)/(other.value()*other.value())));
339  }
340 
341  template<typename OtherDerType>
342  inline AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
343  const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product),
344  const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(internal::remove_all_t<OtherDerType>,Scalar,product) > >
345  operator*(const AutoDiffScalar<OtherDerType>& other) const
346  {
347  internal::make_coherent(m_derivatives, other.derivatives());
348  return MakeAutoDiffScalar(
349  m_value * other.value(),
350  (m_derivatives * other.value()) + (other.derivatives() * m_value));
351  }
352 
353  inline AutoDiffScalar& operator*=(const Scalar& other)
354  {
355  *this = *this * other;
356  return *this;
357  }
358 
359  template<typename OtherDerType>
360  inline AutoDiffScalar& operator*=(const AutoDiffScalar<OtherDerType>& other)
361  {
362  *this = *this * other;
363  return *this;
364  }
365 
366  inline AutoDiffScalar& operator/=(const Scalar& other)
367  {
368  *this = *this / other;
369  return *this;
370  }
371 
372  template<typename OtherDerType>
373  inline AutoDiffScalar& operator/=(const AutoDiffScalar<OtherDerType>& other)
374  {
375  *this = *this / other;
376  return *this;
377  }
378 
379  protected:
380  Scalar m_value;
381  DerType m_derivatives;
382 
383 };
384 
385 namespace internal {
386 
387 template<typename DerivativeType>
388 struct auto_diff_special_op<DerivativeType, true>
389 // : auto_diff_scalar_op<DerivativeType, typename NumTraits<Scalar>::Real,
390 // is_same<Scalar,typename NumTraits<Scalar>::Real>::value>
391 {
392  typedef remove_all_t<DerivativeType> DerType;
393  typedef typename traits<DerType>::Scalar Scalar;
394  typedef typename NumTraits<Scalar>::Real Real;
395 
396 // typedef auto_diff_scalar_op<DerivativeType, typename NumTraits<Scalar>::Real,
397 // is_same<Scalar,typename NumTraits<Scalar>::Real>::value> Base;
398 
399 // using Base::operator+;
400 // using Base::operator+=;
401 // using Base::operator-;
402 // using Base::operator-=;
403 // using Base::operator*;
404 // using Base::operator*=;
405 
406  const AutoDiffScalar<DerivativeType>& derived() const { return *static_cast<const AutoDiffScalar<DerivativeType>*>(this); }
407  AutoDiffScalar<DerivativeType>& derived() { return *static_cast<AutoDiffScalar<DerivativeType>*>(this); }
408 
409 
410  inline AutoDiffScalar<DerType&> operator+(const Real& other) const
411  {
412  return AutoDiffScalar<DerType&>(derived().value() + other, derived().derivatives());
413  }
414 
415  friend inline AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar<DerivativeType>& b)
416  {
417  return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
418  }
419 
420  inline AutoDiffScalar<DerivativeType>& operator+=(const Real& other)
421  {
422  derived().value() += other;
423  return derived();
424  }
425 
426 
427  inline AutoDiffScalar<typename CwiseUnaryOp<bind2nd_op<scalar_product_op<Scalar,Real> >, DerType>::Type >
428  operator*(const Real& other) const
429  {
430  return AutoDiffScalar<typename CwiseUnaryOp<bind2nd_op<scalar_product_op<Scalar,Real> >, DerType>::Type >(
431  derived().value() * other,
432  derived().derivatives() * other);
433  }
434 
435  friend inline AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real,Scalar> >, DerType>::Type >
436  operator*(const Real& other, const AutoDiffScalar<DerivativeType>& a)
437  {
438  return AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real,Scalar> >, DerType>::Type >(
439  a.value() * other,
440  a.derivatives() * other);
441  }
442 
443  inline AutoDiffScalar<DerivativeType>& operator*=(const Scalar& other)
444  {
445  *this = *this * other;
446  return derived();
447  }
448 };
449 
450 template<typename DerivativeType>
451 struct auto_diff_special_op<DerivativeType, false>
452 {
453  void operator*() const;
454  void operator-() const;
455  void operator+() const;
456 };
457 
458 template<typename BinOp, typename A, typename B, typename RefType>
459 void make_coherent_expression(CwiseBinaryOp<BinOp,A,B> xpr, const RefType &ref)
460 {
461  make_coherent(xpr.const_cast_derived().lhs(), ref);
462  make_coherent(xpr.const_cast_derived().rhs(), ref);
463 }
464 
465 template<typename UnaryOp, typename A, typename RefType>
466 void make_coherent_expression(const CwiseUnaryOp<UnaryOp,A> &xpr, const RefType &ref)
467 {
468  make_coherent(xpr.nestedExpression().const_cast_derived(), ref);
469 }
470 
471 // needed for compilation only
472 template<typename UnaryOp, typename A, typename RefType>
473 void make_coherent_expression(const CwiseNullaryOp<UnaryOp,A> &, const RefType &)
474 {}
475 
476 template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols, typename B>
477 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>, B> {
478  typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
479  static void run(A& a, B& b) {
480  if((A_Rows==Dynamic || A_Cols==Dynamic) && (a.size()==0))
481  {
482  a.resize(b.size());
483  a.setZero();
484  }
485  else if (B::SizeAtCompileTime==Dynamic && a.size()!=0 && b.size()==0)
486  {
487  make_coherent_expression(b,a);
488  }
489  }
490 };
491 
492 template<typename A, typename B_Scalar, int B_Rows, int B_Cols, int B_Options, int B_MaxRows, int B_MaxCols>
493 struct make_coherent_impl<A, Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {
494  typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
495  static void run(A& a, B& b) {
496  if((B_Rows==Dynamic || B_Cols==Dynamic) && (b.size()==0))
497  {
498  b.resize(a.size());
499  b.setZero();
500  }
501  else if (A::SizeAtCompileTime==Dynamic && b.size()!=0 && a.size()==0)
502  {
503  make_coherent_expression(a,b);
504  }
505  }
506 };
507 
508 template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols,
509  typename B_Scalar, int B_Rows, int B_Cols, int B_Options, int B_MaxRows, int B_MaxCols>
510 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>,
511  Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {
512  typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
513  typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
514  static void run(A& a, B& b) {
515  if((A_Rows==Dynamic || A_Cols==Dynamic) && (a.size()==0))
516  {
517  a.resize(b.size());
518  a.setZero();
519  }
520  else if((B_Rows==Dynamic || B_Cols==Dynamic) && (b.size()==0))
521  {
522  b.resize(a.size());
523  b.setZero();
524  }
525  }
526 };
527 
528 } // end namespace internal
529 
530 template<typename DerType, typename BinOp>
531 struct ScalarBinaryOpTraits<AutoDiffScalar<DerType>,typename DerType::Scalar,BinOp>
532 {
533  typedef AutoDiffScalar<DerType> ReturnType;
534 };
535 
536 template<typename DerType, typename BinOp>
537 struct ScalarBinaryOpTraits<typename DerType::Scalar,AutoDiffScalar<DerType>, BinOp>
538 {
539  typedef AutoDiffScalar<DerType> ReturnType;
540 };
541 
542 
543 // The following is an attempt to let Eigen's known about expression template, but that's more tricky!
544 
545 // template<typename DerType, typename BinOp>
546 // struct ScalarBinaryOpTraits<AutoDiffScalar<DerType>,AutoDiffScalar<DerType>, BinOp>
547 // {
548 // enum { Defined = 1 };
549 // typedef AutoDiffScalar<typename DerType::PlainObject> ReturnType;
550 // };
551 //
552 // template<typename DerType1,typename DerType2, typename BinOp>
553 // struct ScalarBinaryOpTraits<AutoDiffScalar<DerType1>,AutoDiffScalar<DerType2>, BinOp>
554 // {
555 // enum { Defined = 1 };//internal::is_same<typename DerType1::Scalar,typename DerType2::Scalar>::value };
556 // typedef AutoDiffScalar<typename DerType1::PlainObject> ReturnType;
557 // };
558 
559 #define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC,CODE) \
560  template<typename DerType> \
561  inline Eigen::AutoDiffScalar< \
562  EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Eigen::internal::remove_all_t<DerType>, typename Eigen::internal::traits<Eigen::internal::remove_all_t<DerType>>::Scalar, product) > \
563  FUNC(const Eigen::AutoDiffScalar<DerType>& x) { \
564  using namespace Eigen; \
565  typedef typename Eigen::internal::traits<Eigen::internal::remove_all_t<DerType>>::Scalar Scalar; \
566  EIGEN_UNUSED_VARIABLE(sizeof(Scalar)); \
567  CODE; \
568  }
569 
570 template<typename DerType>
571 struct CleanedUpDerType {
572  typedef AutoDiffScalar<typename Eigen::internal::remove_all_t<DerType>::PlainObject> type;
573 };
574 
575 template<typename DerType>
576 inline const AutoDiffScalar<DerType>& conj(const AutoDiffScalar<DerType>& x) { return x; }
577 template<typename DerType>
578 inline const AutoDiffScalar<DerType>& real(const AutoDiffScalar<DerType>& x) { return x; }
579 template<typename DerType>
580 inline typename DerType::Scalar imag(const AutoDiffScalar<DerType>&) { return 0.; }
581 template<typename DerType, typename T>
582 inline typename CleanedUpDerType<DerType>::type (min)(const AutoDiffScalar<DerType>& x, const T& y) {
583  typedef typename CleanedUpDerType<DerType>::type ADS;
584  return (x <= y ? ADS(x) : ADS(y));
585 }
586 template<typename DerType, typename T>
587 inline typename CleanedUpDerType<DerType>::type (max)(const AutoDiffScalar<DerType>& x, const T& y) {
588  typedef typename CleanedUpDerType<DerType>::type ADS;
589  return (x >= y ? ADS(x) : ADS(y));
590 }
591 template<typename DerType, typename T>
592 inline typename CleanedUpDerType<DerType>::type (min)(const T& x, const AutoDiffScalar<DerType>& y) {
593  typedef typename CleanedUpDerType<DerType>::type ADS;
594  return (x < y ? ADS(x) : ADS(y));
595 }
596 template<typename DerType, typename T>
597 inline typename CleanedUpDerType<DerType>::type (max)(const T& x, const AutoDiffScalar<DerType>& y) {
598  typedef typename CleanedUpDerType<DerType>::type ADS;
599  return (x > y ? ADS(x) : ADS(y));
600 }
601 template<typename DerType>
602 inline typename CleanedUpDerType<DerType>::type (min)(const AutoDiffScalar<DerType>& x, const AutoDiffScalar<DerType>& y) {
603  return (x.value() < y.value() ? x : y);
604 }
605 template<typename DerType>
606 inline typename CleanedUpDerType<DerType>::type (max)(const AutoDiffScalar<DerType>& x, const AutoDiffScalar<DerType>& y) {
607  return (x.value() >= y.value() ? x : y);
608 }
609 
610 
611 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs,
612  using std::abs;
613  return Eigen::MakeAutoDiffScalar(abs(x.value()), x.derivatives() * (x.value()<0 ? -1 : 1) );)
614 
615 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs2,
616  using numext::abs2;
617  return Eigen::MakeAutoDiffScalar(abs2(x.value()), x.derivatives() * (Scalar(2)*x.value()));)
618 
619 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sqrt,
620  using std::sqrt;
621  Scalar sqrtx = sqrt(x.value());
622  return Eigen::MakeAutoDiffScalar(sqrtx,x.derivatives() * (Scalar(0.5) / sqrtx));)
623 
624 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cos,
625  using std::cos;
626  using std::sin;
627  return Eigen::MakeAutoDiffScalar(cos(x.value()), x.derivatives() * (-sin(x.value())));)
628 
629 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sin,
630  using std::sin;
631  using std::cos;
632  return Eigen::MakeAutoDiffScalar(sin(x.value()),x.derivatives() * cos(x.value()));)
633 
634 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(exp,
635  using std::exp;
636  Scalar expx = exp(x.value());
637  return Eigen::MakeAutoDiffScalar(expx,x.derivatives() * expx);)
638 
639 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log,
640  using std::log;
641  return Eigen::MakeAutoDiffScalar(log(x.value()),x.derivatives() * (Scalar(1)/x.value()));)
642 
643 template<typename DerType>
644 inline Eigen::AutoDiffScalar<
645 EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(internal::remove_all_t<DerType>, typename internal::traits<internal::remove_all_t<DerType>>::Scalar,product) >
646 pow(const Eigen::AutoDiffScalar<DerType> &x, const typename internal::traits<internal::remove_all_t<DerType>>::Scalar &y)
647 {
648  using namespace Eigen;
649  using std::pow;
650  return Eigen::MakeAutoDiffScalar(pow(x.value(),y), x.derivatives() * (y * pow(x.value(),y-1)));
651 }
652 
653 
654 template<typename DerTypeA,typename DerTypeB>
656 atan2(const AutoDiffScalar<DerTypeA>& a, const AutoDiffScalar<DerTypeB>& b)
657 {
658  using std::atan2;
659  typedef typename internal::traits<internal::remove_all_t<DerTypeA>>::Scalar Scalar;
660  typedef AutoDiffScalar<Matrix<Scalar,Dynamic,1> > PlainADS;
661  PlainADS ret;
662  ret.value() = atan2(a.value(), b.value());
663 
664  Scalar squared_hypot = a.value() * a.value() + b.value() * b.value();
665 
666  // if (squared_hypot==0) the derivation is undefined and the following results in a NaN:
667  ret.derivatives() = (a.derivatives() * b.value() - a.value() * b.derivatives()) / squared_hypot;
668 
669  return ret;
670 }
671 
672 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tan,
673  using std::tan;
674  using std::cos;
675  return Eigen::MakeAutoDiffScalar(tan(x.value()),x.derivatives() * (Scalar(1)/numext::abs2(cos(x.value()))));)
676 
677 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(asin,
678  using std::sqrt;
679  using std::asin;
680  return Eigen::MakeAutoDiffScalar(asin(x.value()),x.derivatives() * (Scalar(1)/sqrt(1-numext::abs2(x.value()))));)
681 
682 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(acos,
683  using std::sqrt;
684  using std::acos;
685  return Eigen::MakeAutoDiffScalar(acos(x.value()),x.derivatives() * (Scalar(-1)/sqrt(1-numext::abs2(x.value()))));)
686 
687 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tanh,
688  using std::cosh;
689  using std::tanh;
690  return Eigen::MakeAutoDiffScalar(tanh(x.value()),x.derivatives() * (Scalar(1)/numext::abs2(cosh(x.value()))));)
691 
692 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sinh,
693  using std::sinh;
694  using std::cosh;
695  return Eigen::MakeAutoDiffScalar(sinh(x.value()),x.derivatives() * cosh(x.value()));)
696 
697 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cosh,
698  using std::sinh;
699  using std::cosh;
700  return Eigen::MakeAutoDiffScalar(cosh(x.value()),x.derivatives() * sinh(x.value()));)
701 
702 #undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY
703 
704 template<typename DerType> struct NumTraits<AutoDiffScalar<DerType> >
705  : NumTraits< typename NumTraits<typename internal::remove_all_t<DerType>::Scalar>::Real >
706 {
707  typedef internal::remove_all_t<DerType> DerTypeCleaned;
708  typedef AutoDiffScalar<Matrix<typename NumTraits<typename DerTypeCleaned::Scalar>::Real,DerTypeCleaned::RowsAtCompileTime,DerTypeCleaned::ColsAtCompileTime,
709  0, DerTypeCleaned::MaxRowsAtCompileTime, DerTypeCleaned::MaxColsAtCompileTime> > Real;
710  typedef AutoDiffScalar<DerType> NonInteger;
711  typedef AutoDiffScalar<DerType> Nested;
713  enum{
714  RequireInitialization = 1
715  };
716 };
717 
718 }
719 
720 namespace std {
721 
722 template <typename T>
723 class numeric_limits<Eigen::AutoDiffScalar<T> >
724  : public numeric_limits<typename T::Scalar> {};
725 
726 template <typename T>
727 class numeric_limits<Eigen::AutoDiffScalar<T&> >
728  : public numeric_limits<typename T::Scalar> {};
729 
730 } // namespace std
731 
732 #endif // EIGEN_AUTODIFF_SCALAR_H
A scalar type replacement with automatic differentiation capability.
Definition: AutoDiffScalar.h:73
AutoDiffScalar()
Definition: AutoDiffScalar.h:86
AutoDiffScalar(const Scalar &value, int nbDer, int derNumber)
Definition: AutoDiffScalar.h:90
AutoDiffScalar(const Real &value)
Definition: AutoDiffScalar.h:98
AutoDiffScalar(const Scalar &value, const DerType &der)
Definition: AutoDiffScalar.h:106
Namespace containing all symbols from the Eigen library.
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_imag_op< typename Derived::Scalar >, const Derived > imag(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_tan_op< typename Derived::Scalar >, const Derived > tan(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_abs2_op< typename Derived::Scalar >, const Derived > abs2(const Eigen::ArrayBase< Derived > &x)
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_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)
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_cos_op< typename Derived::Scalar >, const Derived > cos(const Eigen::ArrayBase< Derived > &x)
const Product< Inverse< PermutationType >, SparseDerived, AliasFreeProduct > operator*(const InverseImpl< PermutationType, PermutationStorage > &tperm, const SparseMatrixBase< SparseDerived > &matrix)
const int Dynamic
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_exp_op< typename Derived::Scalar >, const Derived > exp(const Eigen::ArrayBase< Derived > &x)
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_log_op< typename Derived::Scalar >, const Derived > log(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sinh_op< typename Derived::Scalar >, const Derived > sinh(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)