00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_AUTODIFF_SCALAR_H
00026 #define EIGEN_AUTODIFF_SCALAR_H
00027
00028 namespace Eigen {
00029
00030 namespace internal {
00031
00032 template<typename A, typename B>
00033 struct make_coherent_impl {
00034 static void run(A&, B&) {}
00035 };
00036
00037
00038 template<typename A, typename B>
00039 void make_coherent(const A& a, const B&b)
00040 {
00041 make_coherent_impl<A,B>::run(a.const_cast_derived(), b.const_cast_derived());
00042 }
00043
00044 template<typename _DerType, bool Enable> struct auto_diff_special_op;
00045
00046 }
00047
00074 template<typename _DerType>
00075 class AutoDiffScalar
00076 : public internal::auto_diff_special_op
00077 <_DerType, !internal::is_same<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar,
00078 typename NumTraits<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar>::Real>::value>
00079 {
00080 public:
00081 typedef internal::auto_diff_special_op
00082 <_DerType, !internal::is_same<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar,
00083 typename NumTraits<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar>::Real>::value> Base;
00084 typedef typename internal::remove_all<_DerType>::type DerType;
00085 typedef typename internal::traits<DerType>::Scalar Scalar;
00086 typedef typename NumTraits<Scalar>::Real Real;
00087
00088 using Base::operator+;
00089 using Base::operator*;
00090
00092 AutoDiffScalar() {}
00093
00096 AutoDiffScalar(const Scalar& value, int nbDer, int derNumber)
00097 : m_value(value), m_derivatives(DerType::Zero(nbDer))
00098 {
00099 m_derivatives.coeffRef(derNumber) = Scalar(1);
00100 }
00101
00104 explicit AutoDiffScalar(const Real& value)
00105 : m_value(value)
00106 {
00107 if(m_derivatives.size()>0)
00108 m_derivatives.setZero();
00109 }
00110
00112 AutoDiffScalar(const Scalar& value, const DerType& der)
00113 : m_value(value), m_derivatives(der)
00114 {}
00115
00116 template<typename OtherDerType>
00117 AutoDiffScalar(const AutoDiffScalar<OtherDerType>& other)
00118 : m_value(other.value()), m_derivatives(other.derivatives())
00119 {}
00120
00121 friend std::ostream & operator << (std::ostream & s, const AutoDiffScalar& a)
00122 {
00123 return s << a.value();
00124 }
00125
00126 AutoDiffScalar(const AutoDiffScalar& other)
00127 : m_value(other.value()), m_derivatives(other.derivatives())
00128 {}
00129
00130 template<typename OtherDerType>
00131 inline AutoDiffScalar& operator=(const AutoDiffScalar<OtherDerType>& other)
00132 {
00133 m_value = other.value();
00134 m_derivatives = other.derivatives();
00135 return *this;
00136 }
00137
00138 inline AutoDiffScalar& operator=(const AutoDiffScalar& other)
00139 {
00140 m_value = other.value();
00141 m_derivatives = other.derivatives();
00142 return *this;
00143 }
00144
00145
00146
00147
00148 inline const Scalar& value() const { return m_value; }
00149 inline Scalar& value() { return m_value; }
00150
00151 inline const DerType& derivatives() const { return m_derivatives; }
00152 inline DerType& derivatives() { return m_derivatives; }
00153
00154 inline const AutoDiffScalar<DerType&> operator+(const Scalar& other) const
00155 {
00156 return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
00157 }
00158
00159 friend inline const AutoDiffScalar<DerType&> operator+(const Scalar& a, const AutoDiffScalar& b)
00160 {
00161 return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 inline AutoDiffScalar& operator+=(const Scalar& other)
00175 {
00176 value() += other;
00177 return *this;
00178 }
00179
00180 template<typename OtherDerType>
00181 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,const DerType,const typename internal::remove_all<OtherDerType>::type> >
00182 operator+(const AutoDiffScalar<OtherDerType>& other) const
00183 {
00184 internal::make_coherent(m_derivatives, other.derivatives());
00185 return AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,const DerType,const typename internal::remove_all<OtherDerType>::type> >(
00186 m_value + other.value(),
00187 m_derivatives + other.derivatives());
00188 }
00189
00190 template<typename OtherDerType>
00191 inline AutoDiffScalar&
00192 operator+=(const AutoDiffScalar<OtherDerType>& other)
00193 {
00194 (*this) = (*this) + other;
00195 return *this;
00196 }
00197
00198 template<typename OtherDerType>
00199 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType,const typename internal::remove_all<OtherDerType>::type> >
00200 operator-(const AutoDiffScalar<OtherDerType>& other) const
00201 {
00202 internal::make_coherent(m_derivatives, other.derivatives());
00203 return AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType,const typename internal::remove_all<OtherDerType>::type> >(
00204 m_value - other.value(),
00205 m_derivatives - other.derivatives());
00206 }
00207
00208 template<typename OtherDerType>
00209 inline AutoDiffScalar&
00210 operator-=(const AutoDiffScalar<OtherDerType>& other)
00211 {
00212 *this = *this - other;
00213 return *this;
00214 }
00215
00216 template<typename OtherDerType>
00217 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
00218 operator-() const
00219 {
00220 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >(
00221 -m_value,
00222 -m_derivatives);
00223 }
00224
00225 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >
00226 operator*(const Scalar& other) const
00227 {
00228 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >(
00229 m_value * other,
00230 (m_derivatives * other));
00231 }
00232
00233 friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >
00234 operator*(const Scalar& other, const AutoDiffScalar& a)
00235 {
00236 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >(
00237 a.value() * other,
00238 a.derivatives() * other);
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >
00258 operator/(const Scalar& other) const
00259 {
00260 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >(
00261 m_value / other,
00262 (m_derivatives * (Scalar(1)/other)));
00263 }
00264
00265 friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >
00266 operator/(const Scalar& other, const AutoDiffScalar& a)
00267 {
00268 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >(
00269 other / a.value(),
00270 a.derivatives() * (-Scalar(1)/other));
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 template<typename OtherDerType>
00290 inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
00291 const CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
00292 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>,
00293 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type > > > >
00294 operator/(const AutoDiffScalar<OtherDerType>& other) const
00295 {
00296 internal::make_coherent(m_derivatives, other.derivatives());
00297 return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,
00298 const CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
00299 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>,
00300 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type > > > >(
00301 m_value / other.value(),
00302 ((m_derivatives * other.value()) - (m_value * other.derivatives()))
00303 * (Scalar(1)/(other.value()*other.value())));
00304 }
00305
00306 template<typename OtherDerType>
00307 inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
00308 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>,
00309 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type> > >
00310 operator*(const AutoDiffScalar<OtherDerType>& other) const
00311 {
00312 internal::make_coherent(m_derivatives, other.derivatives());
00313 return AutoDiffScalar<const CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
00314 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>,
00315 const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type > > >(
00316 m_value * other.value(),
00317 (m_derivatives * other.value()) + (m_value * other.derivatives()));
00318 }
00319
00320 inline AutoDiffScalar& operator*=(const Scalar& other)
00321 {
00322 *this = *this * other;
00323 return *this;
00324 }
00325
00326 template<typename OtherDerType>
00327 inline AutoDiffScalar& operator*=(const AutoDiffScalar<OtherDerType>& other)
00328 {
00329 *this = *this * other;
00330 return *this;
00331 }
00332
00333 protected:
00334 Scalar m_value;
00335 DerType m_derivatives;
00336
00337 };
00338
00339 namespace internal {
00340
00341 template<typename _DerType>
00342 struct auto_diff_special_op<_DerType, true>
00343
00344
00345 {
00346 typedef typename remove_all<_DerType>::type DerType;
00347 typedef typename traits<DerType>::Scalar Scalar;
00348 typedef typename NumTraits<Scalar>::Real Real;
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 const AutoDiffScalar<_DerType>& derived() const { return *static_cast<const AutoDiffScalar<_DerType>*>(this); }
00361 AutoDiffScalar<_DerType>& derived() { return *static_cast<AutoDiffScalar<_DerType>*>(this); }
00362
00363
00364 inline const AutoDiffScalar<DerType&> operator+(const Real& other) const
00365 {
00366 return AutoDiffScalar<DerType&>(derived().value() + other, derived().derivatives());
00367 }
00368
00369 friend inline const AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar<_DerType>& b)
00370 {
00371 return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
00372 }
00373
00374 inline AutoDiffScalar<_DerType>& operator+=(const Real& other)
00375 {
00376 derived().value() += other;
00377 return derived();
00378 }
00379
00380
00381 inline const AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >
00382 operator*(const Real& other) const
00383 {
00384 return AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >(
00385 derived().value() * other,
00386 derived().derivatives() * other);
00387 }
00388
00389 friend inline const AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >
00390 operator*(const Real& other, const AutoDiffScalar<_DerType>& a)
00391 {
00392 return AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >(
00393 a.value() * other,
00394 a.derivatives() * other);
00395 }
00396
00397 inline AutoDiffScalar<_DerType>& operator*=(const Scalar& other)
00398 {
00399 *this = *this * other;
00400 return derived();
00401 }
00402 };
00403
00404 template<typename _DerType>
00405 struct auto_diff_special_op<_DerType, false>
00406 {
00407 void operator*() const;
00408 void operator-() const;
00409 void operator+() const;
00410 };
00411
00412 template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols, typename B>
00413 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>, B> {
00414 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
00415 static void run(A& a, B& b) {
00416 if((A_Rows==Dynamic || A_Cols==Dynamic) && (a.size()==0))
00417 {
00418 a.resize(b.size());
00419 a.setZero();
00420 }
00421 }
00422 };
00423
00424 template<typename A, typename B_Scalar, int B_Rows, int B_Cols, int B_Options, int B_MaxRows, int B_MaxCols>
00425 struct make_coherent_impl<A, Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {
00426 typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
00427 static void run(A& a, B& b) {
00428 if((B_Rows==Dynamic || B_Cols==Dynamic) && (b.size()==0))
00429 {
00430 b.resize(a.size());
00431 b.setZero();
00432 }
00433 }
00434 };
00435
00436 template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols,
00437 typename B_Scalar, int B_Rows, int B_Cols, int B_Options, int B_MaxRows, int B_MaxCols>
00438 struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>,
00439 Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {
00440 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;
00441 typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;
00442 static void run(A& a, B& b) {
00443 if((A_Rows==Dynamic || A_Cols==Dynamic) && (a.size()==0))
00444 {
00445 a.resize(b.size());
00446 a.setZero();
00447 }
00448 else if((B_Rows==Dynamic || B_Cols==Dynamic) && (b.size()==0))
00449 {
00450 b.resize(a.size());
00451 b.setZero();
00452 }
00453 }
00454 };
00455
00456 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>
00457 {
00458 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> ReturnType;
00459 };
00460
00461 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> >
00462 {
00463 typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> ReturnType;
00464 };
00465
00466 template<typename DerType, typename T>
00467 struct scalar_product_traits<AutoDiffScalar<DerType>,T>
00468 {
00469 typedef AutoDiffScalar<DerType> ReturnType;
00470 };
00471
00472 }
00473
00474 }
00475
00476 #define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC,CODE) \
00477 template<typename DerType> \
00478 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> > \
00479 FUNC(const Eigen::AutoDiffScalar<DerType>& x) { \
00480 using namespace Eigen; \
00481 typedef typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar Scalar; \
00482 typedef AutoDiffScalar<CwiseUnaryOp<Eigen::internal::scalar_multiple_op<Scalar>, const typename Eigen::internal::remove_all<DerType>::type> > ReturnType; \
00483 CODE; \
00484 }
00485
00486 namespace std
00487 {
00488 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs,
00489 return ReturnType(std::abs(x.value()), x.derivatives() * (sign(x.value())));)
00490
00491 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sqrt,
00492 Scalar sqrtx = std::sqrt(x.value());
00493 return ReturnType(sqrtx,x.derivatives() * (Scalar(0.5) / sqrtx));)
00494
00495 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cos,
00496 return ReturnType(std::cos(x.value()), x.derivatives() * (-std::sin(x.value())));)
00497
00498 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sin,
00499 return ReturnType(std::sin(x.value()),x.derivatives() * std::cos(x.value()));)
00500
00501 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(exp,
00502 Scalar expx = std::exp(x.value());
00503 return ReturnType(expx,x.derivatives() * expx);)
00504
00505 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log,
00506 return ReturnType(std::log(x.value()),x.derivatives() * (Scalar(1)/x.value()));)
00507
00508 template<typename DerType>
00509 inline const Eigen::AutoDiffScalar<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<typename Eigen::internal::traits<DerType>::Scalar>, const DerType> >
00510 pow(const Eigen::AutoDiffScalar<DerType>& x, typename Eigen::internal::traits<DerType>::Scalar y)
00511 {
00512 using namespace Eigen;
00513 typedef typename Eigen::internal::traits<DerType>::Scalar Scalar;
00514 return AutoDiffScalar<CwiseUnaryOp<Eigen::internal::scalar_multiple_op<Scalar>, const DerType> >(
00515 std::pow(x.value(),y),
00516 x.derivatives() * (y * std::pow(x.value(),y-1)));
00517 }
00518
00519 }
00520
00521 namespace Eigen {
00522
00523 namespace internal {
00524
00525 template<typename DerType>
00526 inline const AutoDiffScalar<DerType>& conj(const AutoDiffScalar<DerType>& x) { return x; }
00527 template<typename DerType>
00528 inline const AutoDiffScalar<DerType>& real(const AutoDiffScalar<DerType>& x) { return x; }
00529 template<typename DerType>
00530 inline typename DerType::Scalar imag(const AutoDiffScalar<DerType>&) { return 0.; }
00531
00532 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs,
00533 return ReturnType(abs(x.value()), x.derivatives() * (sign(x.value())));)
00534
00535 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs2,
00536 return ReturnType(abs2(x.value()), x.derivatives() * (Scalar(2)*x.value()));)
00537
00538 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sqrt,
00539 Scalar sqrtx = sqrt(x.value());
00540 return ReturnType(sqrtx,x.derivatives() * (Scalar(0.5) / sqrtx));)
00541
00542 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cos,
00543 return ReturnType(cos(x.value()), x.derivatives() * (-sin(x.value())));)
00544
00545 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sin,
00546 return ReturnType(sin(x.value()),x.derivatives() * cos(x.value()));)
00547
00548 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(exp,
00549 Scalar expx = exp(x.value());
00550 return ReturnType(expx,x.derivatives() * expx);)
00551
00552 EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log,
00553 return ReturnType(log(x.value()),x.derivatives() * (Scalar(1)/x.value()));)
00554
00555 template<typename DerType>
00556 inline const AutoDiffScalar<CwiseUnaryOp<scalar_multiple_op<typename traits<DerType>::Scalar>, DerType> >
00557 pow(const AutoDiffScalar<DerType>& x, typename traits<DerType>::Scalar y)
00558 { return std::pow(x,y);}
00559
00560 }
00561
00562 #undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY
00563
00564 template<typename DerType> struct NumTraits<AutoDiffScalar<DerType> >
00565 : NumTraits< typename NumTraits<typename DerType::Scalar>::Real >
00566 {
00567 typedef AutoDiffScalar<DerType> NonInteger;
00568 typedef AutoDiffScalar<DerType>& Nested;
00569 enum{
00570 RequireInitialization = 1
00571 };
00572 };
00573
00574 }
00575
00576 #endif // EIGEN_AUTODIFF_SCALAR_H