25 #ifndef EIGEN_AUTODIFF_SCALAR_H
26 #define EIGEN_AUTODIFF_SCALAR_H
32 template<
typename A,
typename B>
33 struct make_coherent_impl {
34 static void run(A&, B&) {}
38 template<
typename A,
typename B>
39 void make_coherent(
const A& a,
const B&b)
41 make_coherent_impl<A,B>::run(a.const_cast_derived(), b.const_cast_derived());
44 template<
typename _DerType,
bool Enable>
struct auto_diff_special_op;
74 template<
typename _DerType>
76 :
public internal::auto_diff_special_op
77 <_DerType, !internal::is_same<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar,
78 typename NumTraits<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar>::Real>::value>
81 typedef internal::auto_diff_special_op
82 <_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> Base;
84 typedef typename internal::remove_all<_DerType>::type DerType;
85 typedef typename internal::traits<DerType>::Scalar Scalar;
86 typedef typename NumTraits<Scalar>::Real Real;
88 using Base::operator+;
89 using Base::operator*;
97 : m_value(value), m_derivatives(DerType::Zero(nbDer))
99 m_derivatives.coeffRef(derNumber) = Scalar(1);
107 if(m_derivatives.size()>0)
108 m_derivatives.setZero();
113 : m_value(value), m_derivatives(der)
116 template<
typename OtherDerType>
118 : m_value(other.value()), m_derivatives(other.derivatives())
121 friend std::ostream & operator << (std::ostream & s,
const AutoDiffScalar& a)
123 return s << a.value();
127 : m_value(other.value()), m_derivatives(other.derivatives())
130 template<
typename OtherDerType>
131 inline AutoDiffScalar& operator=(
const AutoDiffScalar<OtherDerType>& other)
133 m_value = other.value();
134 m_derivatives = other.derivatives();
140 m_value = other.value();
141 m_derivatives = other.derivatives();
148 inline const Scalar& value()
const {
return m_value; }
149 inline Scalar& value() {
return m_value; }
151 inline const DerType& derivatives()
const {
return m_derivatives; }
152 inline DerType& derivatives() {
return m_derivatives; }
154 inline bool operator< (
const Scalar& other)
const {
return m_value < other; }
155 inline bool operator<=(
const Scalar& other)
const {
return m_value <= other; }
156 inline bool operator> (
const Scalar& other)
const {
return m_value > other; }
157 inline bool operator>=(
const Scalar& other)
const {
return m_value >= other; }
158 inline bool operator==(
const Scalar& other)
const {
return m_value == other; }
159 inline bool operator!=(
const Scalar& other)
const {
return m_value != other; }
161 friend inline bool operator< (
const Scalar& a,
const AutoDiffScalar& b) {
return a < b.value(); }
162 friend inline bool operator<=(
const Scalar& a,
const AutoDiffScalar& b) {
return a <= b.value(); }
163 friend inline bool operator> (
const Scalar& a,
const AutoDiffScalar& b) {
return a > b.value(); }
164 friend inline bool operator>=(
const Scalar& a,
const AutoDiffScalar& b) {
return a >= b.value(); }
165 friend inline bool operator==(
const Scalar& a,
const AutoDiffScalar& b) {
return a == b.value(); }
166 friend inline bool operator!=(
const Scalar& a,
const AutoDiffScalar& b) {
return a != b.value(); }
168 template<
typename OtherDerType>
inline bool operator< (const AutoDiffScalar<OtherDerType>& b)
const {
return m_value < b.value(); }
169 template<
typename OtherDerType>
inline bool operator<=(const AutoDiffScalar<OtherDerType>& b)
const {
return m_value <= b.value(); }
170 template<
typename OtherDerType>
inline bool operator> (
const AutoDiffScalar<OtherDerType>& b)
const {
return m_value > b.value(); }
171 template<
typename OtherDerType>
inline bool operator>=(
const AutoDiffScalar<OtherDerType>& b)
const {
return m_value >= b.value(); }
172 template<
typename OtherDerType>
inline bool operator==(
const AutoDiffScalar<OtherDerType>& b)
const {
return m_value == b.value(); }
173 template<
typename OtherDerType>
inline bool operator!=(
const AutoDiffScalar<OtherDerType>& b)
const {
return m_value != b.value(); }
175 inline const AutoDiffScalar<DerType&> operator+(
const Scalar& other)
const
177 return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
180 friend inline const AutoDiffScalar<DerType&> operator+(
const Scalar& a,
const AutoDiffScalar& b)
182 return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
201 template<
typename OtherDerType>
202 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
const DerType,
const typename internal::remove_all<OtherDerType>::type> >
203 operator+(
const AutoDiffScalar<OtherDerType>& other)
const
205 internal::make_coherent(m_derivatives, other.derivatives());
206 return AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
const DerType,
const typename internal::remove_all<OtherDerType>::type> >(
207 m_value + other.value(),
208 m_derivatives + other.derivatives());
211 template<
typename OtherDerType>
213 operator+=(
const AutoDiffScalar<OtherDerType>& other)
215 (*this) = (*this) + other;
219 inline const AutoDiffScalar<DerType&> operator-(
const Scalar& b)
const
221 return AutoDiffScalar<DerType&>(m_value - b, m_derivatives);
224 friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>,
const DerType> >
227 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>,
const DerType> >
228 (a - b.value(), -b.derivatives());
237 template<
typename OtherDerType>
238 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
const DerType,
const typename internal::remove_all<OtherDerType>::type> >
239 operator-(
const AutoDiffScalar<OtherDerType>& other)
const
241 internal::make_coherent(m_derivatives, other.derivatives());
242 return AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
const DerType,
const typename internal::remove_all<OtherDerType>::type> >(
243 m_value - other.value(),
244 m_derivatives - other.derivatives());
247 template<
typename OtherDerType>
249 operator-=(
const AutoDiffScalar<OtherDerType>& other)
251 *
this = *
this - other;
255 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>,
const DerType> >
258 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>,
const DerType> >(
263 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >
264 operator*(
const Scalar& other)
const
266 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >(
268 (m_derivatives * other));
271 friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >
274 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >(
276 a.derivatives() * other);
295 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >
296 operator/(
const Scalar& other)
const
298 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >(
300 (m_derivatives * (Scalar(1)/other)));
303 friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >
306 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >(
308 a.derivatives() * (Scalar(-other) / (a.value()*a.value())));
327 template<
typename OtherDerType>
328 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
329 const CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
330 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType>,
331 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const typename internal::remove_all<OtherDerType>::type > > > >
332 operator/(
const AutoDiffScalar<OtherDerType>& other)
const
334 internal::make_coherent(m_derivatives, other.derivatives());
335 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
336 const CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
337 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType>,
338 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const typename internal::remove_all<OtherDerType>::type > > > >(
339 m_value / other.value(),
340 ((m_derivatives * other.value()) - (m_value * other.derivatives()))
341 * (Scalar(1)/(other.value()*other.value())));
344 template<
typename OtherDerType>
345 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
346 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType>,
347 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const typename internal::remove_all<OtherDerType>::type> > >
348 operator*(
const AutoDiffScalar<OtherDerType>& other)
const
350 internal::make_coherent(m_derivatives, other.derivatives());
351 return AutoDiffScalar<const CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
352 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType>,
353 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const typename internal::remove_all<OtherDerType>::type > > >(
354 m_value * other.value(),
355 (m_derivatives * other.value()) + (m_value * other.derivatives()));
360 *
this = *
this * other;
364 template<
typename OtherDerType>
365 inline AutoDiffScalar& operator*=(
const AutoDiffScalar<OtherDerType>& other)
367 *
this = *
this * other;
373 *
this = *
this / other;
377 template<
typename OtherDerType>
378 inline AutoDiffScalar& operator/=(
const AutoDiffScalar<OtherDerType>& other)
380 *
this = *
this / other;
386 DerType m_derivatives;
392 template<
typename _DerType>
393 struct auto_diff_special_op<_DerType, true>
397 typedef typename remove_all<_DerType>::type DerType;
398 typedef typename traits<DerType>::Scalar Scalar;
399 typedef typename NumTraits<Scalar>::Real Real;
411 const AutoDiffScalar<_DerType>& derived()
const {
return *
static_cast<const AutoDiffScalar<_DerType>*
>(
this); }
412 AutoDiffScalar<_DerType>& derived() {
return *
static_cast<AutoDiffScalar<_DerType>*
>(
this); }
415 inline const AutoDiffScalar<DerType&>
operator+(
const Real& other)
const
417 return AutoDiffScalar<DerType&>(derived().value() + other, derived().derivatives());
420 friend inline const AutoDiffScalar<DerType&>
operator+(
const Real& a,
const AutoDiffScalar<_DerType>& b)
422 return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
425 inline AutoDiffScalar<_DerType>& operator+=(
const Real& other)
427 derived().value() += other;
432 inline const AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>
::Type >
435 return AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>
::Type >(
436 derived().value() * other,
437 derived().derivatives() * other);
440 friend inline const AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>
::Type >
441 operator*(
const Real& other,
const AutoDiffScalar<_DerType>& a)
443 return AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>
::Type >(
445 a.derivatives() * other);
448 inline AutoDiffScalar<_DerType>& operator*=(
const Scalar& other)
450 *
this = *
this * other;
455 template<
typename _DerType>
456 struct auto_diff_special_op<_DerType, false>
463 template<
typename A_Scalar,
int A_Rows,
int A_Cols,
int A_Options,
int A_MaxRows,
int A_MaxCols,
typename B>
464 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>, B> {
465 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
466 static void run(A& a, B& b) {
467 if((A_Rows==Dynamic || A_Cols==Dynamic) && (a.size()==0))
475 template<
typename A,
typename B_Scalar,
int B_Rows,
int B_Cols,
int B_Options,
int B_MaxRows,
int B_MaxCols>
476 struct make_coherent_impl<A, Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {
477 typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
478 static void run(A& a, B& b) {
479 if((B_Rows==Dynamic || B_Cols==Dynamic) && (b.size()==0))
487 template<
typename A_Scalar,
int A_Rows,
int A_Cols,
int A_Options,
int A_MaxRows,
int A_MaxCols,
488 typename B_Scalar,
int B_Rows,
int B_Cols,
int B_Options,
int B_MaxRows,
int B_MaxCols>
489 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>,
490 Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {
491 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
492 typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
493 static void run(A& a, B& b) {
494 if((A_Rows==Dynamic || A_Cols==Dynamic) && (a.size()==0))
499 else if((B_Rows==Dynamic || B_Cols==Dynamic) && (b.size()==0))
507 template<
typename A_Scalar,
int A_Rows,
int A_Cols,
int A_Options,
int A_MaxRows,
int A_MaxCols>
struct scalar_product_traits<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>,A_Scalar>
509 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> ReturnType;
512 template<
typename A_Scalar,
int A_Rows,
int A_Cols,
int A_Options,
int A_MaxRows,
int A_MaxCols>
struct scalar_product_traits<A_Scalar, Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> >
514 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> ReturnType;
517 template<
typename DerType>
518 struct scalar_product_traits<AutoDiffScalar<DerType>,typename DerType::Scalar>
520 typedef AutoDiffScalar<DerType> ReturnType;
525 #define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC,CODE) \
526 template<typename DerType> \
527 inline const Eigen::AutoDiffScalar<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar>, const typename Eigen::internal::remove_all<DerType>::type> > \
528 FUNC(const Eigen::AutoDiffScalar<DerType>& x) { \
529 using namespace Eigen; \
530 typedef typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar Scalar; \
531 typedef AutoDiffScalar<CwiseUnaryOp<Eigen::internal::scalar_multiple_op<Scalar>, const typename Eigen::internal::remove_all<DerType>::type> > ReturnType; \
535 template<
typename DerType>
536 inline const AutoDiffScalar<DerType>& conj(
const AutoDiffScalar<DerType>& x) {
return x; }
537 template<
typename DerType>
538 inline const AutoDiffScalar<DerType>&
real(
const AutoDiffScalar<DerType>& x) {
return x; }
539 template<
typename DerType>
540 inline typename DerType::Scalar
imag(
const AutoDiffScalar<DerType>&) {
return 0.; }
541 template<
typename DerType,
typename T>
542 inline AutoDiffScalar<DerType> (min)(
const AutoDiffScalar<DerType>& x,
const T& y) {
return (x <= y ? x : y); }
543 template<
typename DerType,
typename T>
544 inline AutoDiffScalar<DerType> (max)(
const AutoDiffScalar<DerType>& x,
const T& y) {
return (x >= y ? x : y); }
545 template<
typename DerType,
typename T>
546 inline AutoDiffScalar<DerType> (min)(
const T& x,
const AutoDiffScalar<DerType>& y) {
return (x < y ? x : y); }
547 template<
typename DerType,
typename T>
548 inline AutoDiffScalar<DerType> (max)(
const T& x,
const AutoDiffScalar<DerType>& y) {
return (x > y ? x : y); }
550 #define sign(x) x >= 0 ? 1 : -1 // required for abs function below
552 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs,
554 return ReturnType(
abs(x.value()), x.derivatives() * (sign(x.value())));)
556 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs2,
557 using internal::abs2;
558 return ReturnType(
abs2(x.value()), x.derivatives() * (Scalar(2)*x.value()));)
560 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sqrt,
562 Scalar sqrtx =
sqrt(x.value());
563 return ReturnType(sqrtx,x.derivatives() * (Scalar(0.5) / sqrtx));)
565 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cos,
568 return ReturnType(
cos(x.value()), x.derivatives() * (-
sin(x.value())));)
570 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sin,
573 return ReturnType(
sin(x.value()),x.derivatives() *
cos(x.value()));)
575 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(exp,
577 Scalar expx =
exp(x.value());
578 return ReturnType(expx,x.derivatives() * expx);)
580 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log,
582 return ReturnType(
log(x.value()),x.derivatives() * (Scalar(1)/x.value()));)
584 template<typename DerType>
585 inline const Eigen::AutoDiffScalar<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<
typename Eigen::internal::traits<DerType>::Scalar>,
const DerType> >
588 using namespace Eigen;
589 typedef typename Eigen::internal::traits<DerType>::Scalar Scalar;
591 std::pow(x.value(),y),
592 x.derivatives() * (y * std::pow(x.value(),y-1)));
596 template<
typename DerTypeA,
typename DerTypeB>
602 typedef typename internal::traits<DerTypeA>::Scalar Scalar;
605 ret.value() = atan2(a.value(), b.value());
607 Scalar tmp2 = a.value() * a.value();
608 Scalar tmp3 = b.value() * b.value();
609 Scalar tmp4 = tmp3/(tmp2+tmp3);
612 ret.derivatives() = (a.derivatives() * b.value() - a.value() * b.derivatives()) * (tmp2+tmp3);
617 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tan,
620 return ReturnType(
tan(x.value()),x.derivatives() * (Scalar(1)/internal::abs2(
cos(x.value()))));)
622 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(asin,
625 return ReturnType(
asin(x.value()),x.derivatives() * (Scalar(1)/
sqrt(1-internal::abs2(x.value()))));)
627 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(acos,
630 return ReturnType(
acos(x.value()),x.derivatives() * (Scalar(-1)/
sqrt(1-internal::abs2(x.value()))));)
632 #undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY
635 : NumTraits<
typename NumTraits<typename DerType::Scalar>::Real >
641 RequireInitialization = 1
647 #endif // EIGEN_AUTODIFF_SCALAR_H