10 #ifndef EIGEN_AUTODIFF_SCALAR_H
11 #define EIGEN_AUTODIFF_SCALAR_H
17 template<
typename A,
typename B>
18 struct make_coherent_impl {
19 static void run(A&, B&) {}
23 template<
typename A,
typename B>
24 void make_coherent(
const A& a,
const B&b)
26 make_coherent_impl<A,B>::run(a.const_cast_derived(), b.const_cast_derived());
29 template<
typename _DerType,
bool Enable>
struct auto_diff_special_op;
59 template<
typename _DerType>
61 :
public internal::auto_diff_special_op
62 <_DerType, !internal::is_same<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar,
63 typename NumTraits<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar>::Real>::value>
66 typedef internal::auto_diff_special_op
67 <_DerType, !internal::is_same<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar,
69 typedef typename internal::remove_all<_DerType>::type DerType;
70 typedef typename internal::traits<DerType>::Scalar Scalar;
73 using Base::operator+;
74 using Base::operator*;
82 : m_value(value), m_derivatives(DerType::Zero(nbDer))
84 m_derivatives.coeffRef(derNumber) = Scalar(1);
92 if(m_derivatives.size()>0)
93 m_derivatives.setZero();
98 : m_value(value), m_derivatives(der)
101 template<
typename OtherDerType>
103 : m_value(other.value()), m_derivatives(other.derivatives())
106 friend std::ostream & operator << (std::ostream & s,
const AutoDiffScalar& a)
108 return s << a.value();
112 : m_value(other.value()), m_derivatives(other.derivatives())
115 template<
typename OtherDerType>
116 inline AutoDiffScalar& operator=(
const AutoDiffScalar<OtherDerType>& other)
118 m_value = other.value();
119 m_derivatives = other.derivatives();
125 m_value = other.value();
126 m_derivatives = other.derivatives();
133 inline const Scalar& value()
const {
return m_value; }
134 inline Scalar& value() {
return m_value; }
136 inline const DerType& derivatives()
const {
return m_derivatives; }
137 inline DerType& derivatives() {
return m_derivatives; }
139 inline bool operator< (
const Scalar& other)
const {
return m_value < other; }
140 inline bool operator<=(
const Scalar& other)
const {
return m_value <= other; }
141 inline bool operator> (
const Scalar& other)
const {
return m_value > other; }
142 inline bool operator>=(
const Scalar& other)
const {
return m_value >= other; }
143 inline bool operator==(
const Scalar& other)
const {
return m_value == other; }
144 inline bool operator!=(
const Scalar& other)
const {
return m_value != other; }
146 friend inline bool operator< (
const Scalar& a,
const AutoDiffScalar& b) {
return a < b.value(); }
147 friend inline bool operator<=(
const Scalar& a,
const AutoDiffScalar& b) {
return a <= b.value(); }
148 friend inline bool operator> (
const Scalar& a,
const AutoDiffScalar& b) {
return a > b.value(); }
149 friend inline bool operator>=(
const Scalar& a,
const AutoDiffScalar& b) {
return a >= b.value(); }
150 friend inline bool operator==(
const Scalar& a,
const AutoDiffScalar& b) {
return a == b.value(); }
151 friend inline bool operator!=(
const Scalar& a,
const AutoDiffScalar& b) {
return a != b.value(); }
153 template<
typename OtherDerType>
inline bool operator< (const AutoDiffScalar<OtherDerType>& b)
const {
return m_value < b.value(); }
154 template<
typename OtherDerType>
inline bool operator<=(const AutoDiffScalar<OtherDerType>& b)
const {
return m_value <= b.value(); }
155 template<
typename OtherDerType>
inline bool operator> (
const AutoDiffScalar<OtherDerType>& b)
const {
return m_value > b.value(); }
156 template<
typename OtherDerType>
inline bool operator>=(
const AutoDiffScalar<OtherDerType>& b)
const {
return m_value >= b.value(); }
157 template<
typename OtherDerType>
inline bool operator==(
const AutoDiffScalar<OtherDerType>& b)
const {
return m_value == b.value(); }
158 template<
typename OtherDerType>
inline bool operator!=(
const AutoDiffScalar<OtherDerType>& b)
const {
return m_value != b.value(); }
160 inline const AutoDiffScalar<DerType&> operator+(
const Scalar& other)
const
162 return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
165 friend inline const AutoDiffScalar<DerType&> operator+(
const Scalar& a,
const AutoDiffScalar& b)
167 return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
186 template<
typename OtherDerType>
187 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
const DerType,
const typename internal::remove_all<OtherDerType>::type> >
188 operator+(
const AutoDiffScalar<OtherDerType>& other)
const
190 internal::make_coherent(m_derivatives, other.derivatives());
191 return AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
const DerType,
const typename internal::remove_all<OtherDerType>::type> >(
192 m_value + other.value(),
193 m_derivatives + other.derivatives());
196 template<
typename OtherDerType>
198 operator+=(
const AutoDiffScalar<OtherDerType>& other)
200 (*this) = (*this) + other;
204 inline const AutoDiffScalar<DerType&> operator-(
const Scalar& b)
const
206 return AutoDiffScalar<DerType&>(m_value - b, m_derivatives);
209 friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>,
const DerType> >
212 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>,
const DerType> >
213 (a - b.value(), -b.derivatives());
222 template<
typename OtherDerType>
223 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
const DerType,
const typename internal::remove_all<OtherDerType>::type> >
224 operator-(
const AutoDiffScalar<OtherDerType>& other)
const
226 internal::make_coherent(m_derivatives, other.derivatives());
227 return AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
const DerType,
const typename internal::remove_all<OtherDerType>::type> >(
228 m_value - other.value(),
229 m_derivatives - other.derivatives());
232 template<
typename OtherDerType>
234 operator-=(
const AutoDiffScalar<OtherDerType>& other)
236 *
this = *
this - other;
240 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>,
const DerType> >
243 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>,
const DerType> >(
248 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >
249 operator*(
const Scalar& other)
const
251 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >(
253 (m_derivatives * other));
256 friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >
259 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >(
261 a.derivatives() * other);
280 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >
281 operator/(
const Scalar& other)
const
283 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >(
285 (m_derivatives * (Scalar(1)/other)));
288 friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >
291 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType> >(
293 a.derivatives() * (Scalar(-other) / (a.value()*a.value())));
312 template<
typename OtherDerType>
313 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
314 const CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
315 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType>,
316 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const typename internal::remove_all<OtherDerType>::type > > > >
317 operator/(
const AutoDiffScalar<OtherDerType>& other)
const
319 internal::make_coherent(m_derivatives, other.derivatives());
320 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
321 const CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
322 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType>,
323 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const typename internal::remove_all<OtherDerType>::type > > > >(
324 m_value / other.value(),
325 ((m_derivatives * other.value()) - (m_value * other.derivatives()))
326 * (Scalar(1)/(other.value()*other.value())));
329 template<
typename OtherDerType>
330 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
331 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const DerType>,
332 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
const typename internal::remove_all<OtherDerType>::type> > >
333 operator*(
const AutoDiffScalar<OtherDerType>& other)
const
335 internal::make_coherent(m_derivatives, other.derivatives());
336 return AutoDiffScalar<const CwiseBinaryOp<internal::scalar_sum_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()));
345 *
this = *
this * other;
349 template<
typename OtherDerType>
350 inline AutoDiffScalar& operator*=(
const AutoDiffScalar<OtherDerType>& other)
352 *
this = *
this * other;
358 *
this = *
this / other;
362 template<
typename OtherDerType>
363 inline AutoDiffScalar& operator/=(
const AutoDiffScalar<OtherDerType>& other)
365 *
this = *
this / other;
371 DerType m_derivatives;
377 template<
typename _DerType>
378 struct auto_diff_special_op<_DerType, true>
382 typedef typename remove_all<_DerType>::type DerType;
383 typedef typename traits<DerType>::Scalar Scalar;
384 typedef typename NumTraits<Scalar>::Real Real;
396 const AutoDiffScalar<_DerType>& derived()
const {
return *
static_cast<const AutoDiffScalar<_DerType>*
>(
this); }
397 AutoDiffScalar<_DerType>& derived() {
return *
static_cast<AutoDiffScalar<_DerType>*
>(
this); }
400 inline const AutoDiffScalar<DerType&> operator+(
const Real& other)
const
402 return AutoDiffScalar<DerType&>(derived().value() + other, derived().derivatives());
405 friend inline const AutoDiffScalar<DerType&> operator+(
const Real& a,
const AutoDiffScalar<_DerType>& b)
407 return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
410 inline AutoDiffScalar<_DerType>& operator+=(
const Real& other)
412 derived().value() += other;
417 inline const AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >
420 return AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >(
421 derived().value() * other,
422 derived().derivatives() * other);
425 friend inline const AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >
426 operator*(
const Real& other,
const AutoDiffScalar<_DerType>& a)
428 return AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >(
430 a.derivatives() * other);
433 inline AutoDiffScalar<_DerType>& operator*=(
const Scalar& other)
435 *
this = *
this * other;
440 template<
typename _DerType>
441 struct auto_diff_special_op<_DerType, false>
444 void operator-()
const;
445 void operator+()
const;
448 template<
typename A_Scalar,
int A_Rows,
int A_Cols,
int A_Options,
int A_MaxRows,
int A_MaxCols,
typename B>
449 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>, B> {
450 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
451 static void run(A& a, B& b) {
460 template<
typename A,
typename B_Scalar,
int B_Rows,
int B_Cols,
int B_Options,
int B_MaxRows,
int B_MaxCols>
461 struct make_coherent_impl<A, Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {
462 typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
463 static void run(A& a, B& b) {
472 template<
typename A_Scalar,
int A_Rows,
int A_Cols,
int A_Options,
int A_MaxRows,
int A_MaxCols,
473 typename B_Scalar,
int B_Rows,
int B_Cols,
int B_Options,
int B_MaxRows,
int B_MaxCols>
474 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>,
475 Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {
476 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
477 typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
478 static void run(A& a, B& b) {
492 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>
494 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> ReturnType;
497 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> >
499 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> ReturnType;
502 template<
typename DerType>
503 struct scalar_product_traits<AutoDiffScalar<DerType>,typename DerType::Scalar>
505 typedef AutoDiffScalar<DerType> ReturnType;
510 #define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC,CODE) \
511 template<typename DerType> \
512 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> > \
513 FUNC(const Eigen::AutoDiffScalar<DerType>& x) { \
514 using namespace Eigen; \
515 typedef typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar Scalar; \
516 typedef AutoDiffScalar<CwiseUnaryOp<Eigen::internal::scalar_multiple_op<Scalar>, const typename Eigen::internal::remove_all<DerType>::type> > ReturnType; \
520 template<
typename DerType>
521 inline const AutoDiffScalar<DerType>& conj(
const AutoDiffScalar<DerType>& x) {
return x; }
522 template<
typename DerType>
523 inline const AutoDiffScalar<DerType>& real(
const AutoDiffScalar<DerType>& x) {
return x; }
524 template<
typename DerType>
525 inline typename DerType::Scalar imag(
const AutoDiffScalar<DerType>&) {
return 0.; }
526 template<
typename DerType,
typename T>
527 inline AutoDiffScalar<DerType> (min)(
const AutoDiffScalar<DerType>& x,
const T& y) {
return (x <= y ? x : y); }
528 template<
typename DerType,
typename T>
529 inline AutoDiffScalar<DerType> (max)(
const AutoDiffScalar<DerType>& x,
const T& y) {
return (x >= y ? x : y); }
530 template<
typename DerType,
typename T>
531 inline AutoDiffScalar<DerType> (min)(
const T& x,
const AutoDiffScalar<DerType>& y) {
return (x < y ? x : y); }
532 template<
typename DerType,
typename T>
533 inline AutoDiffScalar<DerType> (max)(
const T& x,
const AutoDiffScalar<DerType>& y) {
return (x > y ? x : y); }
535 #define sign(x) x >= 0 ? 1 : -1 // required for abs function below
537 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs,
539 return ReturnType(abs(x.value()), x.derivatives() * (sign(x.value())));)
541 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs2,
542 using internal::abs2;
543 return ReturnType(abs2(x.value()), x.derivatives() * (Scalar(2)*x.value()));)
545 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sqrt,
547 Scalar sqrtx = sqrt(x.value());
548 return ReturnType(sqrtx,x.derivatives() * (Scalar(0.5) / sqrtx));)
550 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cos,
553 return ReturnType(cos(x.value()), x.derivatives() * (-sin(x.value())));)
555 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sin,
558 return ReturnType(sin(x.value()),x.derivatives() * cos(x.value()));)
560 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(exp,
562 Scalar expx = exp(x.value());
563 return ReturnType(expx,x.derivatives() * expx);)
565 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log,
567 return ReturnType(log(x.value()),x.derivatives() * (Scalar(1)/x.value()));)
569 template<typename DerType>
573 using namespace Eigen;
574 typedef typename Eigen::internal::traits<DerType>::Scalar Scalar;
576 std::pow(x.value(),y),
577 x.derivatives() * (y * std::pow(x.value(),y-1)));
581 template<
typename DerTypeA,
typename DerTypeB>
587 typedef typename internal::traits<DerTypeA>::Scalar Scalar;
590 ret.value() = atan2(a.value(), b.value());
592 Scalar tmp2 = a.value() * a.value();
593 Scalar tmp3 = b.value() * b.value();
594 Scalar tmp4 = tmp3/(tmp2+tmp3);
597 ret.derivatives() = (a.derivatives() * b.value() - a.value() * b.derivatives()) * (tmp2+tmp3);
602 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tan,
605 return ReturnType(tan(x.value()),x.derivatives() * (Scalar(1)/internal::abs2(cos(x.value()))));)
607 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(asin,
610 return ReturnType(asin(x.value()),x.derivatives() * (Scalar(1)/sqrt(1-internal::abs2(x.value()))));)
612 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(acos,
615 return ReturnType(acos(x.value()),x.derivatives() * (Scalar(-1)/sqrt(1-internal::abs2(x.value()))));)
617 #undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY
626 RequireInitialization = 1
632 #endif // EIGEN_AUTODIFF_SCALAR_H