File indexing completed on 2025-01-18 09:57:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef EIGEN_AUTODIFF_SCALAR_H
0011 #define EIGEN_AUTODIFF_SCALAR_H
0012
0013 namespace Eigen {
0014
0015 namespace internal {
0016
0017 template<typename A, typename B>
0018 struct make_coherent_impl {
0019 static void run(A&, B&) {}
0020 };
0021
0022
0023 template<typename A, typename B>
0024 void make_coherent(const A& a, const B&b)
0025 {
0026 make_coherent_impl<A,B>::run(a.const_cast_derived(), b.const_cast_derived());
0027 }
0028
0029 template<typename DerivativeType, bool Enable> struct auto_diff_special_op;
0030
0031 }
0032
0033 template<typename DerivativeType> class AutoDiffScalar;
0034
0035 template<typename NewDerType>
0036 inline AutoDiffScalar<NewDerType> MakeAutoDiffScalar(const typename NewDerType::Scalar& value, const NewDerType &der) {
0037 return AutoDiffScalar<NewDerType>(value,der);
0038 }
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 template<typename DerivativeType>
0067 class AutoDiffScalar
0068 : public internal::auto_diff_special_op
0069 <DerivativeType, !internal::is_same<typename internal::traits<typename internal::remove_all<DerivativeType>::type>::Scalar,
0070 typename NumTraits<typename internal::traits<typename internal::remove_all<DerivativeType>::type>::Scalar>::Real>::value>
0071 {
0072 public:
0073 typedef internal::auto_diff_special_op
0074 <DerivativeType, !internal::is_same<typename internal::traits<typename internal::remove_all<DerivativeType>::type>::Scalar,
0075 typename NumTraits<typename internal::traits<typename internal::remove_all<DerivativeType>::type>::Scalar>::Real>::value> Base;
0076 typedef typename internal::remove_all<DerivativeType>::type DerType;
0077 typedef typename internal::traits<DerType>::Scalar Scalar;
0078 typedef typename NumTraits<Scalar>::Real Real;
0079
0080 using Base::operator+;
0081 using Base::operator*;
0082
0083
0084 AutoDiffScalar() {}
0085
0086
0087
0088 AutoDiffScalar(const Scalar& value, int nbDer, int derNumber)
0089 : m_value(value), m_derivatives(DerType::Zero(nbDer))
0090 {
0091 m_derivatives.coeffRef(derNumber) = Scalar(1);
0092 }
0093
0094
0095
0096 AutoDiffScalar(const Real& value)
0097 : m_value(value)
0098 {
0099 if(m_derivatives.size()>0)
0100 m_derivatives.setZero();
0101 }
0102
0103
0104 AutoDiffScalar(const Scalar& value, const DerType& der)
0105 : m_value(value), m_derivatives(der)
0106 {}
0107
0108 template<typename OtherDerType>
0109 AutoDiffScalar(const AutoDiffScalar<OtherDerType>& other
0110 #ifndef EIGEN_PARSED_BY_DOXYGEN
0111 , typename internal::enable_if<
0112 internal::is_same<Scalar, typename internal::traits<typename internal::remove_all<OtherDerType>::type>::Scalar>::value
0113 && internal::is_convertible<OtherDerType,DerType>::value , void*>::type = 0
0114 #endif
0115 )
0116 : m_value(other.value()), m_derivatives(other.derivatives())
0117 {}
0118
0119 friend std::ostream & operator << (std::ostream & s, const AutoDiffScalar& a)
0120 {
0121 return s << a.value();
0122 }
0123
0124 AutoDiffScalar(const AutoDiffScalar& other)
0125 : m_value(other.value()), m_derivatives(other.derivatives())
0126 {}
0127
0128 template<typename OtherDerType>
0129 inline AutoDiffScalar& operator=(const AutoDiffScalar<OtherDerType>& other)
0130 {
0131 m_value = other.value();
0132 m_derivatives = other.derivatives();
0133 return *this;
0134 }
0135
0136 inline AutoDiffScalar& operator=(const AutoDiffScalar& other)
0137 {
0138 m_value = other.value();
0139 m_derivatives = other.derivatives();
0140 return *this;
0141 }
0142
0143 inline AutoDiffScalar& operator=(const Scalar& other)
0144 {
0145 m_value = other;
0146 if(m_derivatives.size()>0)
0147 m_derivatives.setZero();
0148 return *this;
0149 }
0150
0151
0152
0153
0154 inline const Scalar& value() const { return m_value; }
0155 inline Scalar& value() { return m_value; }
0156
0157 inline const DerType& derivatives() const { return m_derivatives; }
0158 inline DerType& derivatives() { return m_derivatives; }
0159
0160 inline bool operator< (const Scalar& other) const { return m_value < other; }
0161 inline bool operator<=(const Scalar& other) const { return m_value <= other; }
0162 inline bool operator> (const Scalar& other) const { return m_value > other; }
0163 inline bool operator>=(const Scalar& other) const { return m_value >= other; }
0164 inline bool operator==(const Scalar& other) const { return m_value == other; }
0165 inline bool operator!=(const Scalar& other) const { return m_value != other; }
0166
0167 friend inline bool operator< (const Scalar& a, const AutoDiffScalar& b) { return a < b.value(); }
0168 friend inline bool operator<=(const Scalar& a, const AutoDiffScalar& b) { return a <= b.value(); }
0169 friend inline bool operator> (const Scalar& a, const AutoDiffScalar& b) { return a > b.value(); }
0170 friend inline bool operator>=(const Scalar& a, const AutoDiffScalar& b) { return a >= b.value(); }
0171 friend inline bool operator==(const Scalar& a, const AutoDiffScalar& b) { return a == b.value(); }
0172 friend inline bool operator!=(const Scalar& a, const AutoDiffScalar& b) { return a != b.value(); }
0173
0174 template<typename OtherDerType> inline bool operator< (const AutoDiffScalar<OtherDerType>& b) const { return m_value < b.value(); }
0175 template<typename OtherDerType> inline bool operator<=(const AutoDiffScalar<OtherDerType>& b) const { return m_value <= b.value(); }
0176 template<typename OtherDerType> inline bool operator> (const AutoDiffScalar<OtherDerType>& b) const { return m_value > b.value(); }
0177 template<typename OtherDerType> inline bool operator>=(const AutoDiffScalar<OtherDerType>& b) const { return m_value >= b.value(); }
0178 template<typename OtherDerType> inline bool operator==(const AutoDiffScalar<OtherDerType>& b) const { return m_value == b.value(); }
0179 template<typename OtherDerType> inline bool operator!=(const AutoDiffScalar<OtherDerType>& b) const { return m_value != b.value(); }
0180
0181 inline const AutoDiffScalar<DerType&> operator+(const Scalar& other) const
0182 {
0183 return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
0184 }
0185
0186 friend inline const AutoDiffScalar<DerType&> operator+(const Scalar& a, const AutoDiffScalar& b)
0187 {
0188 return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
0189 }
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 inline AutoDiffScalar& operator+=(const Scalar& other)
0202 {
0203 value() += other;
0204 return *this;
0205 }
0206
0207 template<typename OtherDerType>
0208 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,const DerType,const typename internal::remove_all<OtherDerType>::type> >
0209 operator+(const AutoDiffScalar<OtherDerType>& other) const
0210 {
0211 internal::make_coherent(m_derivatives, other.derivatives());
0212 return AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,const DerType,const typename internal::remove_all<OtherDerType>::type> >(
0213 m_value + other.value(),
0214 m_derivatives + other.derivatives());
0215 }
0216
0217 template<typename OtherDerType>
0218 inline AutoDiffScalar&
0219 operator+=(const AutoDiffScalar<OtherDerType>& other)
0220 {
0221 (*this) = (*this) + other;
0222 return *this;
0223 }
0224
0225 inline const AutoDiffScalar<DerType&> operator-(const Scalar& b) const
0226 {
0227 return AutoDiffScalar<DerType&>(m_value - b, m_derivatives);
0228 }
0229
0230 friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
0231 operator-(const Scalar& a, const AutoDiffScalar& b)
0232 {
0233 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
0234 (a - b.value(), -b.derivatives());
0235 }
0236
0237 inline AutoDiffScalar& operator-=(const Scalar& other)
0238 {
0239 value() -= other;
0240 return *this;
0241 }
0242
0243 template<typename OtherDerType>
0244 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType,const typename internal::remove_all<OtherDerType>::type> >
0245 operator-(const AutoDiffScalar<OtherDerType>& other) const
0246 {
0247 internal::make_coherent(m_derivatives, other.derivatives());
0248 return AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType,const typename internal::remove_all<OtherDerType>::type> >(
0249 m_value - other.value(),
0250 m_derivatives - other.derivatives());
0251 }
0252
0253 template<typename OtherDerType>
0254 inline AutoDiffScalar&
0255 operator-=(const AutoDiffScalar<OtherDerType>& other)
0256 {
0257 *this = *this - other;
0258 return *this;
0259 }
0260
0261 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
0262 operator-() const
0263 {
0264 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >(
0265 -m_value,
0266 -m_derivatives);
0267 }
0268
0269 inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
0270 operator*(const Scalar& other) const
0271 {
0272 return MakeAutoDiffScalar(m_value * other, m_derivatives * other);
0273 }
0274
0275 friend inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
0276 operator*(const Scalar& other, const AutoDiffScalar& a)
0277 {
0278 return MakeAutoDiffScalar(a.value() * other, a.derivatives() * other);
0279 }
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
0298 operator/(const Scalar& other) const
0299 {
0300 return MakeAutoDiffScalar(m_value / other, (m_derivatives * (Scalar(1)/other)));
0301 }
0302
0303 friend inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
0304 operator/(const Scalar& other, const AutoDiffScalar& a)
0305 {
0306 return MakeAutoDiffScalar(other / a.value(), a.derivatives() * (Scalar(-other) / (a.value()*a.value())));
0307 }
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325 template<typename OtherDerType>
0326 inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(
0327 CwiseBinaryOp<internal::scalar_difference_op<Scalar> EIGEN_COMMA
0328 const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) EIGEN_COMMA
0329 const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<OtherDerType>::type,Scalar,product) >,Scalar,product) >
0330 operator/(const AutoDiffScalar<OtherDerType>& other) const
0331 {
0332 internal::make_coherent(m_derivatives, other.derivatives());
0333 return MakeAutoDiffScalar(
0334 m_value / other.value(),
0335 ((m_derivatives * other.value()) - (other.derivatives() * m_value))
0336 * (Scalar(1)/(other.value()*other.value())));
0337 }
0338
0339 template<typename OtherDerType>
0340 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
0341 const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product),
0342 const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<OtherDerType>::type,Scalar,product) > >
0343 operator*(const AutoDiffScalar<OtherDerType>& other) const
0344 {
0345 internal::make_coherent(m_derivatives, other.derivatives());
0346 return MakeAutoDiffScalar(
0347 m_value * other.value(),
0348 (m_derivatives * other.value()) + (other.derivatives() * m_value));
0349 }
0350
0351 inline AutoDiffScalar& operator*=(const Scalar& other)
0352 {
0353 *this = *this * other;
0354 return *this;
0355 }
0356
0357 template<typename OtherDerType>
0358 inline AutoDiffScalar& operator*=(const AutoDiffScalar<OtherDerType>& other)
0359 {
0360 *this = *this * other;
0361 return *this;
0362 }
0363
0364 inline AutoDiffScalar& operator/=(const Scalar& other)
0365 {
0366 *this = *this / other;
0367 return *this;
0368 }
0369
0370 template<typename OtherDerType>
0371 inline AutoDiffScalar& operator/=(const AutoDiffScalar<OtherDerType>& other)
0372 {
0373 *this = *this / other;
0374 return *this;
0375 }
0376
0377 protected:
0378 Scalar m_value;
0379 DerType m_derivatives;
0380
0381 };
0382
0383 namespace internal {
0384
0385 template<typename DerivativeType>
0386 struct auto_diff_special_op<DerivativeType, true>
0387
0388
0389 {
0390 typedef typename remove_all<DerivativeType>::type DerType;
0391 typedef typename traits<DerType>::Scalar Scalar;
0392 typedef typename NumTraits<Scalar>::Real Real;
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404 const AutoDiffScalar<DerivativeType>& derived() const { return *static_cast<const AutoDiffScalar<DerivativeType>*>(this); }
0405 AutoDiffScalar<DerivativeType>& derived() { return *static_cast<AutoDiffScalar<DerivativeType>*>(this); }
0406
0407
0408 inline const AutoDiffScalar<DerType&> operator+(const Real& other) const
0409 {
0410 return AutoDiffScalar<DerType&>(derived().value() + other, derived().derivatives());
0411 }
0412
0413 friend inline const AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar<DerivativeType>& b)
0414 {
0415 return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
0416 }
0417
0418 inline AutoDiffScalar<DerivativeType>& operator+=(const Real& other)
0419 {
0420 derived().value() += other;
0421 return derived();
0422 }
0423
0424
0425 inline const AutoDiffScalar<typename CwiseUnaryOp<bind2nd_op<scalar_product_op<Scalar,Real> >, DerType>::Type >
0426 operator*(const Real& other) const
0427 {
0428 return AutoDiffScalar<typename CwiseUnaryOp<bind2nd_op<scalar_product_op<Scalar,Real> >, DerType>::Type >(
0429 derived().value() * other,
0430 derived().derivatives() * other);
0431 }
0432
0433 friend inline const AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real,Scalar> >, DerType>::Type >
0434 operator*(const Real& other, const AutoDiffScalar<DerivativeType>& a)
0435 {
0436 return AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real,Scalar> >, DerType>::Type >(
0437 a.value() * other,
0438 a.derivatives() * other);
0439 }
0440
0441 inline AutoDiffScalar<DerivativeType>& operator*=(const Scalar& other)
0442 {
0443 *this = *this * other;
0444 return derived();
0445 }
0446 };
0447
0448 template<typename DerivativeType>
0449 struct auto_diff_special_op<DerivativeType, false>
0450 {
0451 void operator*() const;
0452 void operator-() const;
0453 void operator+() const;
0454 };
0455
0456 template<typename BinOp, typename A, typename B, typename RefType>
0457 void make_coherent_expression(CwiseBinaryOp<BinOp,A,B> xpr, const RefType &ref)
0458 {
0459 make_coherent(xpr.const_cast_derived().lhs(), ref);
0460 make_coherent(xpr.const_cast_derived().rhs(), ref);
0461 }
0462
0463 template<typename UnaryOp, typename A, typename RefType>
0464 void make_coherent_expression(const CwiseUnaryOp<UnaryOp,A> &xpr, const RefType &ref)
0465 {
0466 make_coherent(xpr.nestedExpression().const_cast_derived(), ref);
0467 }
0468
0469
0470 template<typename UnaryOp, typename A, typename RefType>
0471 void make_coherent_expression(const CwiseNullaryOp<UnaryOp,A> &, const RefType &)
0472 {}
0473
0474 template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols, typename B>
0475 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>, B> {
0476 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
0477 static void run(A& a, B& b) {
0478 if((A_Rows==Dynamic || A_Cols==Dynamic) && (a.size()==0))
0479 {
0480 a.resize(b.size());
0481 a.setZero();
0482 }
0483 else if (B::SizeAtCompileTime==Dynamic && a.size()!=0 && b.size()==0)
0484 {
0485 make_coherent_expression(b,a);
0486 }
0487 }
0488 };
0489
0490 template<typename A, typename B_Scalar, int B_Rows, int B_Cols, int B_Options, int B_MaxRows, int B_MaxCols>
0491 struct make_coherent_impl<A, Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {
0492 typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
0493 static void run(A& a, B& b) {
0494 if((B_Rows==Dynamic || B_Cols==Dynamic) && (b.size()==0))
0495 {
0496 b.resize(a.size());
0497 b.setZero();
0498 }
0499 else if (A::SizeAtCompileTime==Dynamic && b.size()!=0 && a.size()==0)
0500 {
0501 make_coherent_expression(a,b);
0502 }
0503 }
0504 };
0505
0506 template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols,
0507 typename B_Scalar, int B_Rows, int B_Cols, int B_Options, int B_MaxRows, int B_MaxCols>
0508 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>,
0509 Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {
0510 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
0511 typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
0512 static void run(A& a, B& b) {
0513 if((A_Rows==Dynamic || A_Cols==Dynamic) && (a.size()==0))
0514 {
0515 a.resize(b.size());
0516 a.setZero();
0517 }
0518 else if((B_Rows==Dynamic || B_Cols==Dynamic) && (b.size()==0))
0519 {
0520 b.resize(a.size());
0521 b.setZero();
0522 }
0523 }
0524 };
0525
0526 }
0527
0528 template<typename DerType, typename BinOp>
0529 struct ScalarBinaryOpTraits<AutoDiffScalar<DerType>,typename DerType::Scalar,BinOp>
0530 {
0531 typedef AutoDiffScalar<DerType> ReturnType;
0532 };
0533
0534 template<typename DerType, typename BinOp>
0535 struct ScalarBinaryOpTraits<typename DerType::Scalar,AutoDiffScalar<DerType>, BinOp>
0536 {
0537 typedef AutoDiffScalar<DerType> ReturnType;
0538 };
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557 #define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC,CODE) \
0558 template<typename DerType> \
0559 inline const Eigen::AutoDiffScalar< \
0560 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) > \
0561 FUNC(const Eigen::AutoDiffScalar<DerType>& x) { \
0562 using namespace Eigen; \
0563 typedef typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar Scalar; \
0564 EIGEN_UNUSED_VARIABLE(sizeof(Scalar)); \
0565 CODE; \
0566 }
0567
0568 template<typename DerType>
0569 struct CleanedUpDerType {
0570 typedef AutoDiffScalar<typename Eigen::internal::remove_all<DerType>::type::PlainObject> type;
0571 };
0572
0573 template<typename DerType>
0574 inline const AutoDiffScalar<DerType>& conj(const AutoDiffScalar<DerType>& x) { return x; }
0575 template<typename DerType>
0576 inline const AutoDiffScalar<DerType>& real(const AutoDiffScalar<DerType>& x) { return x; }
0577 template<typename DerType>
0578 inline typename DerType::Scalar imag(const AutoDiffScalar<DerType>&) { return 0.; }
0579 template<typename DerType, typename T>
0580 inline typename CleanedUpDerType<DerType>::type (min)(const AutoDiffScalar<DerType>& x, const T& y) {
0581 typedef typename CleanedUpDerType<DerType>::type ADS;
0582 return (x <= y ? ADS(x) : ADS(y));
0583 }
0584 template<typename DerType, typename T>
0585 inline typename CleanedUpDerType<DerType>::type (max)(const AutoDiffScalar<DerType>& x, const T& y) {
0586 typedef typename CleanedUpDerType<DerType>::type ADS;
0587 return (x >= y ? ADS(x) : ADS(y));
0588 }
0589 template<typename DerType, typename T>
0590 inline typename CleanedUpDerType<DerType>::type (min)(const T& x, const AutoDiffScalar<DerType>& y) {
0591 typedef typename CleanedUpDerType<DerType>::type ADS;
0592 return (x < y ? ADS(x) : ADS(y));
0593 }
0594 template<typename DerType, typename T>
0595 inline typename CleanedUpDerType<DerType>::type (max)(const T& x, const AutoDiffScalar<DerType>& y) {
0596 typedef typename CleanedUpDerType<DerType>::type ADS;
0597 return (x > y ? ADS(x) : ADS(y));
0598 }
0599 template<typename DerType>
0600 inline typename CleanedUpDerType<DerType>::type (min)(const AutoDiffScalar<DerType>& x, const AutoDiffScalar<DerType>& y) {
0601 return (x.value() < y.value() ? x : y);
0602 }
0603 template<typename DerType>
0604 inline typename CleanedUpDerType<DerType>::type (max)(const AutoDiffScalar<DerType>& x, const AutoDiffScalar<DerType>& y) {
0605 return (x.value() >= y.value() ? x : y);
0606 }
0607
0608
0609 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs,
0610 using std::abs;
0611 return Eigen::MakeAutoDiffScalar(abs(x.value()), x.derivatives() * (x.value()<0 ? -1 : 1) );)
0612
0613 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs2,
0614 using numext::abs2;
0615 return Eigen::MakeAutoDiffScalar(abs2(x.value()), x.derivatives() * (Scalar(2)*x.value()));)
0616
0617 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sqrt,
0618 using std::sqrt;
0619 Scalar sqrtx = sqrt(x.value());
0620 return Eigen::MakeAutoDiffScalar(sqrtx,x.derivatives() * (Scalar(0.5) / sqrtx));)
0621
0622 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cos,
0623 using std::cos;
0624 using std::sin;
0625 return Eigen::MakeAutoDiffScalar(cos(x.value()), x.derivatives() * (-sin(x.value())));)
0626
0627 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sin,
0628 using std::sin;
0629 using std::cos;
0630 return Eigen::MakeAutoDiffScalar(sin(x.value()),x.derivatives() * cos(x.value()));)
0631
0632 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(exp,
0633 using std::exp;
0634 Scalar expx = exp(x.value());
0635 return Eigen::MakeAutoDiffScalar(expx,x.derivatives() * expx);)
0636
0637 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log,
0638 using std::log;
0639 return Eigen::MakeAutoDiffScalar(log(x.value()),x.derivatives() * (Scalar(1)/x.value()));)
0640
0641 template<typename DerType>
0642 inline const Eigen::AutoDiffScalar<
0643 EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<DerType>::type,typename internal::traits<typename internal::remove_all<DerType>::type>::Scalar,product) >
0644 pow(const Eigen::AutoDiffScalar<DerType> &x, const typename internal::traits<typename internal::remove_all<DerType>::type>::Scalar &y)
0645 {
0646 using namespace Eigen;
0647 using std::pow;
0648 return Eigen::MakeAutoDiffScalar(pow(x.value(),y), x.derivatives() * (y * pow(x.value(),y-1)));
0649 }
0650
0651
0652 template<typename DerTypeA,typename DerTypeB>
0653 inline const AutoDiffScalar<Matrix<typename internal::traits<typename internal::remove_all<DerTypeA>::type>::Scalar,Dynamic,1> >
0654 atan2(const AutoDiffScalar<DerTypeA>& a, const AutoDiffScalar<DerTypeB>& b)
0655 {
0656 using std::atan2;
0657 typedef typename internal::traits<typename internal::remove_all<DerTypeA>::type>::Scalar Scalar;
0658 typedef AutoDiffScalar<Matrix<Scalar,Dynamic,1> > PlainADS;
0659 PlainADS ret;
0660 ret.value() = atan2(a.value(), b.value());
0661
0662 Scalar squared_hypot = a.value() * a.value() + b.value() * b.value();
0663
0664
0665 ret.derivatives() = (a.derivatives() * b.value() - a.value() * b.derivatives()) / squared_hypot;
0666
0667 return ret;
0668 }
0669
0670 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tan,
0671 using std::tan;
0672 using std::cos;
0673 return Eigen::MakeAutoDiffScalar(tan(x.value()),x.derivatives() * (Scalar(1)/numext::abs2(cos(x.value()))));)
0674
0675 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(asin,
0676 using std::sqrt;
0677 using std::asin;
0678 return Eigen::MakeAutoDiffScalar(asin(x.value()),x.derivatives() * (Scalar(1)/sqrt(1-numext::abs2(x.value()))));)
0679
0680 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(acos,
0681 using std::sqrt;
0682 using std::acos;
0683 return Eigen::MakeAutoDiffScalar(acos(x.value()),x.derivatives() * (Scalar(-1)/sqrt(1-numext::abs2(x.value()))));)
0684
0685 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tanh,
0686 using std::cosh;
0687 using std::tanh;
0688 return Eigen::MakeAutoDiffScalar(tanh(x.value()),x.derivatives() * (Scalar(1)/numext::abs2(cosh(x.value()))));)
0689
0690 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sinh,
0691 using std::sinh;
0692 using std::cosh;
0693 return Eigen::MakeAutoDiffScalar(sinh(x.value()),x.derivatives() * cosh(x.value()));)
0694
0695 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cosh,
0696 using std::sinh;
0697 using std::cosh;
0698 return Eigen::MakeAutoDiffScalar(cosh(x.value()),x.derivatives() * sinh(x.value()));)
0699
0700 #undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY
0701
0702 template<typename DerType> struct NumTraits<AutoDiffScalar<DerType> >
0703 : NumTraits< typename NumTraits<typename internal::remove_all<DerType>::type::Scalar>::Real >
0704 {
0705 typedef typename internal::remove_all<DerType>::type DerTypeCleaned;
0706 typedef AutoDiffScalar<Matrix<typename NumTraits<typename DerTypeCleaned::Scalar>::Real,DerTypeCleaned::RowsAtCompileTime,DerTypeCleaned::ColsAtCompileTime,
0707 0, DerTypeCleaned::MaxRowsAtCompileTime, DerTypeCleaned::MaxColsAtCompileTime> > Real;
0708 typedef AutoDiffScalar<DerType> NonInteger;
0709 typedef AutoDiffScalar<DerType> Nested;
0710 typedef typename NumTraits<typename DerTypeCleaned::Scalar>::Literal Literal;
0711 enum{
0712 RequireInitialization = 1
0713 };
0714 };
0715
0716 }
0717
0718 namespace std {
0719
0720 template <typename T>
0721 class numeric_limits<Eigen::AutoDiffScalar<T> >
0722 : public numeric_limits<typename T::Scalar> {};
0723
0724 template <typename T>
0725 class numeric_limits<Eigen::AutoDiffScalar<T&> >
0726 : public numeric_limits<typename T::Scalar> {};
0727
0728 }
0729
0730 #endif