Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:02

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
0005 //
0006 // This Source Code Form is subject to the terms of the Mozilla
0007 // Public License v. 2.0. If a copy of the MPL was not distributed
0008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
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 // resize a to match b is a.size()==0, and conversely.
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 } // end namespace internal
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 /** \class AutoDiffScalar
0041   * \brief A scalar type replacement with automatic differentiation capability
0042   *
0043   * \param DerivativeType the vector type used to store/represent the derivatives. The base scalar type
0044   *                 as well as the number of derivatives to compute are determined from this type.
0045   *                 Typical choices include, e.g., \c Vector4f for 4 derivatives, or \c VectorXf
0046   *                 if the number of derivatives is not known at compile time, and/or, the number
0047   *                 of derivatives is large.
0048   *                 Note that DerivativeType can also be a reference (e.g., \c VectorXf&) to wrap a
0049   *                 existing vector into an AutoDiffScalar.
0050   *                 Finally, DerivativeType can also be any Eigen compatible expression.
0051   *
0052   * This class represents a scalar value while tracking its respective derivatives using Eigen's expression
0053   * template mechanism.
0054   *
0055   * It supports the following list of global math function:
0056   *  - std::abs, std::sqrt, std::pow, std::exp, std::log, std::sin, std::cos,
0057   *  - internal::abs, internal::sqrt, numext::pow, internal::exp, internal::log, internal::sin, internal::cos,
0058   *  - internal::conj, internal::real, internal::imag, numext::abs2.
0059   *
0060   * AutoDiffScalar can be used as the scalar type of an Eigen::Matrix object. However,
0061   * in that case, the expression template mechanism only occurs at the top Matrix level,
0062   * while derivatives are computed right away.
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     /** Default constructor without any initialization. */
0084     AutoDiffScalar() {}
0085 
0086     /** Constructs an active scalar from its \a value,
0087         and initializes the \a nbDer derivatives such that it corresponds to the \a derNumber -th variable */
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     /** Conversion from a scalar constant to an active scalar.
0095       * The derivatives are set to zero. */
0096     /*explicit*/ AutoDiffScalar(const Real& value)
0097       : m_value(value)
0098     {
0099       if(m_derivatives.size()>0)
0100         m_derivatives.setZero();
0101     }
0102 
0103     /** Constructs an active scalar from its \a value and derivatives \a der */
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 //     inline operator const Scalar& () const { return m_value; }
0152 //     inline operator Scalar& () { return m_value; }
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 //     inline const AutoDiffScalar<DerType&> operator+(const Real& other) const
0192 //     {
0193 //       return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
0194 //     }
0195 
0196 //     friend inline const AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar& b)
0197 //     {
0198 //       return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
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 //     inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
0282 //     operator*(const Real& other) const
0283 //     {
0284 //       return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
0285 //         m_value * other,
0286 //         (m_derivatives * other));
0287 //     }
0288 //
0289 //     friend inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
0290 //     operator*(const Real& other, const AutoDiffScalar& a)
0291 //     {
0292 //       return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
0293 //         a.value() * other,
0294 //         a.derivatives() * other);
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 //     inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
0310 //     operator/(const Real& other) const
0311 //     {
0312 //       return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
0313 //         m_value / other,
0314 //         (m_derivatives * (Real(1)/other)));
0315 //     }
0316 //
0317 //     friend inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
0318 //     operator/(const Real& other, const AutoDiffScalar& a)
0319 //     {
0320 //       return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(
0321 //         other / a.value(),
0322 //         a.derivatives() * (-Real(1)/other));
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 //   : auto_diff_scalar_op<DerivativeType, typename NumTraits<Scalar>::Real,
0388 //                            is_same<Scalar,typename NumTraits<Scalar>::Real>::value>
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 //   typedef auto_diff_scalar_op<DerivativeType, typename NumTraits<Scalar>::Real,
0395 //                            is_same<Scalar,typename NumTraits<Scalar>::Real>::value> Base;
0396 
0397 //   using Base::operator+;
0398 //   using Base::operator+=;
0399 //   using Base::operator-;
0400 //   using Base::operator-=;
0401 //   using Base::operator*;
0402 //   using Base::operator*=;
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 // needed for compilation only
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 } // end namespace internal
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 // The following is an attempt to let Eigen's known about expression template, but that's more tricky!
0542 
0543 // template<typename DerType, typename BinOp>
0544 // struct ScalarBinaryOpTraits<AutoDiffScalar<DerType>,AutoDiffScalar<DerType>, BinOp>
0545 // {
0546 //   enum { Defined = 1 };
0547 //   typedef AutoDiffScalar<typename DerType::PlainObject> ReturnType;
0548 // };
0549 //
0550 // template<typename DerType1,typename DerType2, typename BinOp>
0551 // struct ScalarBinaryOpTraits<AutoDiffScalar<DerType1>,AutoDiffScalar<DerType2>, BinOp>
0552 // {
0553 //   enum { Defined = 1 };//internal::is_same<typename DerType1::Scalar,typename DerType2::Scalar>::value };
0554 //   typedef AutoDiffScalar<typename DerType1::PlainObject> ReturnType;
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   // if (squared_hypot==0) the derivation is undefined and the following results in a NaN:
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 }  // namespace std
0729 
0730 #endif // EIGEN_AUTODIFF_SCALAR_H