10#ifndef EIGEN_AUTODIFF_SCALAR_H
11#define EIGEN_AUTODIFF_SCALAR_H
14#include "./InternalHeaderCheck.h"
20template <
typename DerivativeType,
bool Enable>
21struct auto_diff_special_op;
23template <
typename DerivativeType,
typename OtherDerivativeType,
typename EnableIf =
void>
24struct maybe_coherent_pad_helper {
25 static constexpr int SizeAtCompileTime =
26 max_size_prefer_dynamic(DerivativeType::SizeAtCompileTime, OtherDerivativeType::SizeAtCompileTime);
27 using type = CoherentPadOp<DerivativeType, SizeAtCompileTime>;
28 static type pad(
const DerivativeType& x,
const OtherDerivativeType& y) {
31 return CoherentPadOp<DerivativeType, SizeAtCompileTime>(x, numext::maxi(x.size(), y.size()));
37template <
typename DerivativeType,
typename OtherDerivativeType>
38struct maybe_coherent_pad_helper<
39 DerivativeType, OtherDerivativeType,
40 std::enable_if_t<enum_ge_not_dynamic(DerivativeType::SizeAtCompileTime, OtherDerivativeType::SizeAtCompileTime)>> {
41 using type =
const DerivativeType&;
42 static const DerivativeType& pad(
const DerivativeType& x,
const OtherDerivativeType& ) {
return x; }
45template <
typename DerivativeType,
typename OtherDerivativeType>
46typename maybe_coherent_pad_helper<DerivativeType, OtherDerivativeType>::type MaybeCoherentPad(
47 const DerivativeType& x,
const OtherDerivativeType& y) {
48 return maybe_coherent_pad_helper<DerivativeType, OtherDerivativeType>::pad(x, y);
51template <
typename Op,
typename LhsDerivativeType,
typename RhsDerivativeType>
52auto MakeCoherentCwiseBinaryOp(
const LhsDerivativeType& x,
const RhsDerivativeType& y, Op op = Op()) {
53 const auto& lhs = MaybeCoherentPad(x, y);
54 const auto& rhs = MaybeCoherentPad(y, x);
55 return CwiseBinaryOp<Op, remove_all_t<
decltype(lhs)>, remove_all_t<
decltype(rhs)>>(lhs, rhs, op);
60template <
typename DerivativeType>
63template <
typename NewDerType>
94template <
typename DerivativeType>
96 :
public internal::auto_diff_special_op<
97 DerivativeType, !internal::is_same<typename internal::traits<internal::remove_all_t<DerivativeType>>::Scalar,
98 typename NumTraits<typename internal::traits<
99 internal::remove_all_t<DerivativeType>>::Scalar>::Real>::value> {
101 typedef internal::auto_diff_special_op<
104 typename internal::traits<internal::remove_all_t<DerivativeType>>::Scalar,
107 typedef internal::remove_all_t<DerivativeType> DerType;
108 typedef typename internal::traits<DerType>::Scalar Scalar;
111 using Base::operator+;
112 using Base::operator*;
119 AutoDiffScalar(
const Scalar& value,
int nbDer,
int derNumber) : m_value(value), m_derivatives(DerType::Zero(nbDer)) {
120 m_derivatives.coeffRef(derNumber) = Scalar(1);
126 if (m_derivatives.size() > 0) m_derivatives.setZero();
130 AutoDiffScalar(
const Scalar& value,
const DerType& der) : m_value(value), m_derivatives(der) {}
132 template <
typename OtherDerType>
135#ifndef EIGEN_PARSED_BY_DOXYGEN
138 internal::is_same<
Scalar,
typename internal::traits<internal::remove_all_t<OtherDerType>>
::Scalar>::value &&
139 internal::is_convertible<OtherDerType, DerType>::value,
143 : m_value(other.value()), m_derivatives(other.derivatives()) {
146 friend std::ostream& operator<<(std::ostream& s,
const AutoDiffScalar& a) {
return s << a.value(); }
150 template <
typename OtherDerType>
152 m_value = other.value();
153 m_derivatives = other.derivatives();
158 m_value = other.value();
159 m_derivatives = other.derivatives();
165 if (m_derivatives.size() > 0) m_derivatives.setZero();
172 inline const Scalar& value()
const {
return m_value; }
173 inline Scalar& value() {
return m_value; }
175 inline const DerType& derivatives()
const {
return m_derivatives; }
176 inline DerType& derivatives() {
return m_derivatives; }
178 inline bool operator<(
const Scalar& other)
const {
return m_value < other; }
179 inline bool operator<=(
const Scalar& other)
const {
return m_value <= other; }
180 inline bool operator>(
const Scalar& other)
const {
return m_value > other; }
181 inline bool operator>=(
const Scalar& other)
const {
return m_value >= other; }
182 inline bool operator==(
const Scalar& other)
const {
return m_value == other; }
183 inline bool operator!=(
const Scalar& other)
const {
return m_value != other; }
185 friend inline bool operator<(
const Scalar& a,
const AutoDiffScalar& b) {
return a < b.value(); }
186 friend inline bool operator<=(
const Scalar& a,
const AutoDiffScalar& b) {
return a <= b.value(); }
187 friend inline bool operator>(
const Scalar& a,
const AutoDiffScalar& b) {
return a > b.value(); }
188 friend inline bool operator>=(
const Scalar& a,
const AutoDiffScalar& b) {
return a >= b.value(); }
189 friend inline bool operator==(
const Scalar& a,
const AutoDiffScalar& b) {
return a == b.value(); }
190 friend inline bool operator!=(
const Scalar& a,
const AutoDiffScalar& b) {
return a != b.value(); }
192 template <
typename OtherDerType>
194 return m_value < b.value();
196 template <
typename OtherDerType>
198 return m_value <= b.value();
200 template <
typename OtherDerType>
202 return m_value > b.value();
204 template <
typename OtherDerType>
206 return m_value >= b.value();
208 template <
typename OtherDerType>
210 return m_value == b.value();
212 template <
typename OtherDerType>
214 return m_value != b.value();
240 template <
typename OtherDerType>
242 return MakeAutoDiffScalar(
243 m_value + other.value(),
244 internal::MakeCoherentCwiseBinaryOp<internal::scalar_sum_op<Scalar>>(m_derivatives, other.derivatives()));
247 template <
typename OtherDerType>
249 (*this) = (*this) + other;
268 template <
typename OtherDerType>
270 return MakeAutoDiffScalar(m_value - other.value(),
271 internal::MakeCoherentCwiseBinaryOp<internal::scalar_difference_op<Scalar>>(
272 m_derivatives, other.derivatives()));
275 template <
typename OtherDerType>
277 *
this = *
this - other;
285 inline auto operator*(
const Scalar& other)
const {
286 return MakeAutoDiffScalar(m_value * other, m_derivatives * other);
289 friend inline auto operator*(
const Scalar& other,
const AutoDiffScalar& a) {
290 return MakeAutoDiffScalar(a.value() * other, a.derivatives() * other);
309 inline auto operator/(
const Scalar& other)
const {
310 return MakeAutoDiffScalar(m_value / other, (m_derivatives * (Scalar(1) / other)));
313 friend inline auto operator/(
const Scalar& other,
const AutoDiffScalar& a) {
314 return MakeAutoDiffScalar(other / a.value(), a.derivatives() * (Scalar(-other) / (a.value() * a.value())));
333 template <
typename OtherDerType>
335 return MakeAutoDiffScalar(m_value / other.value(),
336 internal::MakeCoherentCwiseBinaryOp<internal::scalar_difference_op<Scalar>>(
337 m_derivatives * other.value(), (other.derivatives() * m_value)) *
338 (Scalar(1) / (other.value() * other.value())));
341 template <
typename OtherDerType>
343 return MakeAutoDiffScalar(m_value * other.value(),
344 internal::MakeCoherentCwiseBinaryOp<internal::scalar_sum_op<Scalar>>(
345 m_derivatives * other.value(), other.derivatives() * m_value));
349 *
this = *
this * other;
353 template <
typename OtherDerType>
355 *
this = *
this * other;
360 *
this = *
this / other;
364 template <
typename OtherDerType>
366 *
this = *
this / other;
372 DerType m_derivatives;
377template <
typename DerivativeType>
378struct auto_diff_special_op<DerivativeType, true>
382 typedef remove_all_t<DerivativeType> DerType;
383 typedef typename traits<DerType>::Scalar Scalar;
384 typedef typename NumTraits<Scalar>::Real Real;
396 const AutoDiffScalar<DerivativeType>& derived()
const {
397 return *
static_cast<const AutoDiffScalar<DerivativeType>*
>(
this);
399 AutoDiffScalar<DerivativeType>& derived() {
return *
static_cast<AutoDiffScalar<DerivativeType>*
>(
this); }
401 inline AutoDiffScalar<DerType&> operator+(
const Real& other)
const {
402 return AutoDiffScalar<DerType&>(derived().value() + other, derived().derivatives());
405 friend inline AutoDiffScalar<DerType&> operator+(
const Real& a,
const AutoDiffScalar<DerivativeType>& b) {
406 return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
409 inline AutoDiffScalar<DerivativeType>& operator+=(
const Real& other) {
410 derived().value() += other;
414 inline AutoDiffScalar<typename CwiseUnaryOp<bind2nd_op<scalar_product_op<Scalar, Real>>, DerType>::Type>
operator*(
415 const Real& other)
const {
416 return AutoDiffScalar<typename CwiseUnaryOp<bind2nd_op<scalar_product_op<Scalar, Real>>, DerType>::Type>(
417 derived().value() * other, derived().derivatives() * other);
420 friend inline AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real, Scalar>>, DerType>::Type>
421 operator*(
const Real& other,
const AutoDiffScalar<DerivativeType>& a) {
422 return AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real, Scalar>>, DerType>::Type>(
423 a.value() * other, a.derivatives() * other);
426 inline AutoDiffScalar<DerivativeType>& operator*=(
const Scalar& other) {
427 *
this = *
this * other;
432template <
typename DerivativeType>
433struct auto_diff_special_op<DerivativeType, false> {
435 void operator-()
const;
436 void operator+()
const;
441template <
typename DerType,
typename BinOp>
443 typedef AutoDiffScalar<DerType> ReturnType;
446template <
typename DerType,
typename BinOp>
448 typedef AutoDiffScalar<DerType> ReturnType;
467#define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC, CODE) \
468 template <typename DerType> \
469 inline auto FUNC(const Eigen::AutoDiffScalar<DerType>& x) { \
470 using namespace Eigen; \
471 typedef typename Eigen::internal::traits<Eigen::internal::remove_all_t<DerType>>::Scalar Scalar; \
472 EIGEN_UNUSED_VARIABLE(sizeof(Scalar)); \
476template <
typename DerType>
477struct CleanedUpDerType {
478 typedef AutoDiffScalar<typename Eigen::internal::remove_all_t<DerType>::PlainObject> type;
481template <
typename DerType>
485template <
typename DerType>
489template <
typename DerType>
493template <
typename DerType,
typename T>
495 typedef typename CleanedUpDerType<DerType>::type ADS;
496 return (x <= y ? ADS(x) : ADS(y));
498template <
typename DerType,
typename T>
500 typedef typename CleanedUpDerType<DerType>::type ADS;
501 return (x >= y ? ADS(x) : ADS(y));
503template <
typename DerType,
typename T>
505 typedef typename CleanedUpDerType<DerType>::type ADS;
506 return (x < y ? ADS(x) : ADS(y));
508template <
typename DerType,
typename T>
510 typedef typename CleanedUpDerType<DerType>::type ADS;
511 return (x > y ? ADS(x) : ADS(y));
513template <
typename DerType>
516 return (x.value() < y.value() ? x : y);
518template <
typename DerType>
521 return (x.value() >= y.value() ? x : y);
524EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
abs,
using std::abs;
525 return Eigen::MakeAutoDiffScalar(
abs(x.value()),
526 x.derivatives() * (x.value() < 0 ? -1 : 1));)
528EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
abs2,
using numext::abs2;
529 return Eigen::MakeAutoDiffScalar(
abs2(x.value()),
530 x.derivatives() * (
Scalar(2) * x.value()));)
532EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
sqrt,
using std::sqrt;
Scalar sqrtx =
sqrt(x.value());
533 return Eigen::MakeAutoDiffScalar(sqrtx, x.derivatives() * (
Scalar(0.5) / sqrtx));)
535EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
cos,
using std::cos;
using std::sin;
536 return Eigen::MakeAutoDiffScalar(
cos(x.value()),
537 x.derivatives() * (-
sin(x.value())));)
539EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
sin,
using std::sin;
using std::cos;
540 return Eigen::MakeAutoDiffScalar(
sin(x.value()), x.derivatives() *
cos(x.value()));)
542EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
exp,
using std::exp;
Scalar expx =
exp(x.value());
543 return Eigen::MakeAutoDiffScalar(expx, x.derivatives() * expx);)
545EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
log,
using std::log;
546 return Eigen::MakeAutoDiffScalar(
log(x.value()),
547 x.derivatives() * (
Scalar(1) / x.value()));)
549template <typename DerType>
550inline auto pow(
const Eigen::AutoDiffScalar<DerType>& x,
551 const typename internal::traits<internal::remove_all_t<DerType>>::Scalar& y) {
552 using namespace Eigen;
554 return Eigen::MakeAutoDiffScalar(pow(x.value(), y), x.derivatives() * (y * pow(x.value(), y - 1)));
557template <
typename DerTypeA,
typename DerTypeB>
561 typedef typename internal::traits<internal::remove_all_t<DerTypeA>>::Scalar
Scalar;
564 ret.value() = atan2(a.value(), b.value());
566 Scalar squared_hypot = a.value() * a.value() + b.value() * b.value();
569 ret.derivatives() = (a.derivatives() * b.value() - a.value() * b.derivatives()) / squared_hypot;
574EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
tan,
using std::tan;
using std::cos;
return Eigen::MakeAutoDiffScalar(
575 tan(x.value()), x.derivatives() * (
Scalar(1) / numext::abs2(
cos(x.value()))));)
577EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
asin,
using std::sqrt;
using std::asin;
return Eigen::MakeAutoDiffScalar(
579 x.derivatives() * (
Scalar(1) /
sqrt(1 - numext::abs2(x.value()))));)
581EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
acos,
using std::sqrt;
using std::acos;
return Eigen::MakeAutoDiffScalar(
583 x.derivatives() * (
Scalar(-1) /
sqrt(1 - numext::abs2(x.value()))));)
585EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
586 tanh,
using std::cosh;
using std::tanh;
587 return Eigen::MakeAutoDiffScalar(
tanh(x.value()), x.derivatives() * (
Scalar(1) / numext::abs2(
cosh(x.value()))));)
589EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
sinh,
using std::sinh;
using std::cosh;
590 return Eigen::MakeAutoDiffScalar(
sinh(x.value()),
591 x.derivatives() *
cosh(x.value()));)
593EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(
cosh,
using std::sinh;
using std::cosh;
594 return Eigen::MakeAutoDiffScalar(
cosh(x.value()),
595 x.derivatives() *
sinh(x.value()));)
597#undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY
599template <typename DerType>
602 typedef internal::remove_all_t<DerType> DerTypeCleaned;
604 DerTypeCleaned::RowsAtCompileTime, DerTypeCleaned::ColsAtCompileTime, 0,
605 DerTypeCleaned::MaxRowsAtCompileTime, DerTypeCleaned::MaxColsAtCompileTime>>
610 enum { RequireInitialization = 1 };
614template <
typename DerivativeType>
615struct is_identically_zero_impl<AutoDiffScalar<DerivativeType>> {
616 static inline bool run(
const AutoDiffScalar<DerivativeType>& s) {
617 const DerivativeType& derivatives = s.derivatives();
618 for (
int i = 0; i < derivatives.size(); ++i) {
619 if (!numext::is_exactly_zero(derivatives[i])) {
623 return numext::is_exactly_zero(s.value());
632class numeric_limits<Eigen::AutoDiffScalar<T>> :
public numeric_limits<typename T::Scalar> {};
635class numeric_limits<Eigen::AutoDiffScalar<T&>> :
public numeric_limits<typename T::Scalar> {};
A scalar type replacement with automatic differentiation capability.
Definition AutoDiffScalar.h:99
AutoDiffScalar()
Definition AutoDiffScalar.h:115
AutoDiffScalar(const Scalar &value, int nbDer, int derNumber)
Definition AutoDiffScalar.h:119
AutoDiffScalar(const Real &value)
Definition AutoDiffScalar.h:125
AutoDiffScalar(const Scalar &value, const DerType &der)
Definition AutoDiffScalar.h:130
Namespace containing all symbols from the Eigen library.
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_cos_op< typename Derived::Scalar >, const Derived > cos(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_real_op< typename Derived::Scalar >, const Derived > real(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_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_tan_op< typename Derived::Scalar >, const Derived > tan(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 Product< Inverse< PermutationType >, SparseDerived, AliasFreeProduct > operator*(const InverseImpl< PermutationType, PermutationStorage > &tperm, const SparseMatrixBase< SparseDerived > &matrix)
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_log_op< typename Derived::Scalar >, const Derived > log(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_asin_op< typename Derived::Scalar >, const Derived > asin(const Eigen::ArrayBase< Derived > &x)
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_acos_op< typename Derived::Scalar >, const Derived > acos(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sinh_op< typename Derived::Scalar >, const Derived > sinh(const Eigen::ArrayBase< Derived > &x)