From 35f7829af10c61e33dd2e2a7a015058e11a11ea0 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 25 Mar 2017 14:17:07 +0100 Subject: update --- .../Eigen/src/AutoDiff/AutoDiffJacobian.h | 49 +++-- .../Eigen/src/AutoDiff/AutoDiffScalar.h | 224 ++++++++++++--------- .../unsupported/Eigen/src/AutoDiff/CMakeLists.txt | 6 - 3 files changed, 171 insertions(+), 108 deletions(-) delete mode 100644 eigen/unsupported/Eigen/src/AutoDiff/CMakeLists.txt (limited to 'eigen/unsupported/Eigen/src/AutoDiff') diff --git a/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h b/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h index 1a61e33..33b6c39 100644 --- a/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h +++ b/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h @@ -20,37 +20,60 @@ public: AutoDiffJacobian(const Functor& f) : Functor(f) {} // forward constructors +#if EIGEN_HAS_VARIADIC_TEMPLATES + template + AutoDiffJacobian(const T& ...Values) : Functor(Values...) {} +#else template AutoDiffJacobian(const T0& a0) : Functor(a0) {} template AutoDiffJacobian(const T0& a0, const T1& a1) : Functor(a0, a1) {} template AutoDiffJacobian(const T0& a0, const T1& a1, const T2& a2) : Functor(a0, a1, a2) {} +#endif + + typedef typename Functor::InputType InputType; + typedef typename Functor::ValueType ValueType; + typedef typename ValueType::Scalar Scalar; enum { - InputsAtCompileTime = Functor::InputsAtCompileTime, - ValuesAtCompileTime = Functor::ValuesAtCompileTime + InputsAtCompileTime = InputType::RowsAtCompileTime, + ValuesAtCompileTime = ValueType::RowsAtCompileTime }; - typedef typename Functor::InputType InputType; - typedef typename Functor::ValueType ValueType; - typedef typename Functor::JacobianType JacobianType; - typedef typename JacobianType::Scalar Scalar; + typedef Matrix JacobianType; typedef typename JacobianType::Index Index; - typedef Matrix DerivativeType; + typedef Matrix DerivativeType; typedef AutoDiffScalar ActiveScalar; - typedef Matrix ActiveInput; typedef Matrix ActiveValue; +#if EIGEN_HAS_VARIADIC_TEMPLATES + // Some compilers don't accept variadic parameters after a default parameter, + // i.e., we can't just write _jac=0 but we need to overload operator(): + EIGEN_STRONG_INLINE + void operator() (const InputType& x, ValueType* v) const + { + this->operator()(x, v, 0); + } + template + void operator() (const InputType& x, ValueType* v, JacobianType* _jac, + const ParamsType&... Params) const +#else void operator() (const InputType& x, ValueType* v, JacobianType* _jac=0) const +#endif { eigen_assert(v!=0); + if (!_jac) { +#if EIGEN_HAS_VARIADIC_TEMPLATES + Functor::operator()(x, v, Params...); +#else Functor::operator()(x, v); +#endif return; } @@ -61,12 +84,16 @@ public: if(InputsAtCompileTime==Dynamic) for (Index j=0; jinputs()); + av[j].derivatives().resize(x.rows()); for (Index i=0; iinputs(),i); + ax[i].derivatives() = DerivativeType::Unit(x.rows(),i); +#if EIGEN_HAS_VARIADIC_TEMPLATES + Functor::operator()(ax, &av, Params...); +#else Functor::operator()(ax, &av); +#endif for (Index i=0; i struct auto_diff_special_op; } // end namespace internal +template class AutoDiffScalar; + +template +inline AutoDiffScalar MakeAutoDiffScalar(const typename NewDerType::Scalar& value, const NewDerType &der) { + return AutoDiffScalar(value,der); +} + /** \class AutoDiffScalar * \brief A scalar type replacement with automatic differentation capability * @@ -60,7 +67,7 @@ template class AutoDiffScalar : public internal::auto_diff_special_op <_DerType, !internal::is_same::type>::Scalar, - typename NumTraits::type>::Scalar>::Real>::value> + typename NumTraits::type>::Scalar>::Real>::value> { public: typedef internal::auto_diff_special_op @@ -99,7 +106,13 @@ class AutoDiffScalar {} template - AutoDiffScalar(const AutoDiffScalar& other) + AutoDiffScalar(const AutoDiffScalar& other +#ifndef EIGEN_PARSED_BY_DOXYGEN + , typename internal::enable_if< + internal::is_same::type>::Scalar>::value + && internal::is_convertible::value , void*>::type = 0 +#endif + ) : m_value(other.value()), m_derivatives(other.derivatives()) {} @@ -127,6 +140,14 @@ class AutoDiffScalar return *this; } + inline AutoDiffScalar& operator=(const Scalar& other) + { + m_value = other; + if(m_derivatives.size()>0) + m_derivatives.setZero(); + return *this; + } + // inline operator const Scalar& () const { return m_value; } // inline operator Scalar& () { return m_value; } @@ -245,20 +266,16 @@ class AutoDiffScalar -m_derivatives); } - inline const AutoDiffScalar, const DerType> > + inline const AutoDiffScalar operator*(const Scalar& other) const { - return AutoDiffScalar, const DerType> >( - m_value * other, - (m_derivatives * other)); + return MakeAutoDiffScalar(m_value * other, m_derivatives * other); } - friend inline const AutoDiffScalar, const DerType> > + friend inline const AutoDiffScalar operator*(const Scalar& other, const AutoDiffScalar& a) { - return AutoDiffScalar, const DerType> >( - a.value() * other, - a.derivatives() * other); + return MakeAutoDiffScalar(a.value() * other, a.derivatives() * other); } // inline const AutoDiffScalar, DerType>::Type > @@ -277,20 +294,16 @@ class AutoDiffScalar // a.derivatives() * other); // } - inline const AutoDiffScalar, const DerType> > + inline const AutoDiffScalar operator/(const Scalar& other) const { - return AutoDiffScalar, const DerType> >( - m_value / other, - (m_derivatives * (Scalar(1)/other))); + return MakeAutoDiffScalar(m_value / other, (m_derivatives * (Scalar(1)/other))); } - friend inline const AutoDiffScalar, const DerType> > + friend inline const AutoDiffScalar operator/(const Scalar& other, const AutoDiffScalar& a) { - return AutoDiffScalar, const DerType> >( - other / a.value(), - a.derivatives() * (Scalar(-other) / (a.value()*a.value()))); + return MakeAutoDiffScalar(other / a.value(), a.derivatives() * (Scalar(-other) / (a.value()*a.value()))); } // inline const AutoDiffScalar, DerType>::Type > @@ -310,34 +323,29 @@ class AutoDiffScalar // } template - inline const AutoDiffScalar, - const CwiseBinaryOp, - const CwiseUnaryOp, const DerType>, - const CwiseUnaryOp, const typename internal::remove_all::type > > > > + inline const AutoDiffScalar EIGEN_COMMA + const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) EIGEN_COMMA + const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all::type,Scalar,product) >,Scalar,product) > operator/(const AutoDiffScalar& other) const { internal::make_coherent(m_derivatives, other.derivatives()); - return AutoDiffScalar, - const CwiseBinaryOp, - const CwiseUnaryOp, const DerType>, - const CwiseUnaryOp, const typename internal::remove_all::type > > > >( + return MakeAutoDiffScalar( m_value / other.value(), - ((m_derivatives * other.value()) - (m_value * other.derivatives())) + ((m_derivatives * other.value()) - (other.derivatives() * m_value)) * (Scalar(1)/(other.value()*other.value()))); } template inline const AutoDiffScalar, - const CwiseUnaryOp, const DerType>, - const CwiseUnaryOp, const typename internal::remove_all::type> > > + const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product), + const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all::type,Scalar,product) > > operator*(const AutoDiffScalar& other) const { internal::make_coherent(m_derivatives, other.derivatives()); - return AutoDiffScalar, - const CwiseUnaryOp, const DerType>, - const CwiseUnaryOp, const typename internal::remove_all::type > > >( + return MakeAutoDiffScalar( m_value * other.value(), - (m_derivatives * other.value()) + (m_value * other.derivatives())); + (m_derivatives * other.value()) + (other.derivatives() * m_value)); } inline AutoDiffScalar& operator*=(const Scalar& other) @@ -414,18 +422,18 @@ struct auto_diff_special_op<_DerType, true> } - inline const AutoDiffScalar, DerType>::Type > + inline const AutoDiffScalar >, DerType>::Type > operator*(const Real& other) const { - return AutoDiffScalar, DerType>::Type >( + return AutoDiffScalar >, DerType>::Type >( derived().value() * other, derived().derivatives() * other); } - friend inline const AutoDiffScalar, DerType>::Type > + friend inline const AutoDiffScalar >, DerType>::Type > operator*(const Real& other, const AutoDiffScalar<_DerType>& a) { - return AutoDiffScalar, DerType>::Type >( + return AutoDiffScalar >, DerType>::Type >( a.value() * other, a.derivatives() * other); } @@ -489,43 +497,44 @@ struct make_coherent_impl -struct scalar_product_traits,A_Scalar> -{ - enum { Defined = 1 }; - typedef Matrix ReturnType; -}; - -template -struct scalar_product_traits > -{ - enum { Defined = 1 }; - typedef Matrix ReturnType; -}; +} // end namespace internal -template -struct scalar_product_traits,typename DerType::Scalar> +template +struct ScalarBinaryOpTraits,typename DerType::Scalar,BinOp> { - enum { Defined = 1 }; typedef AutoDiffScalar ReturnType; }; -template -struct scalar_product_traits > +template +struct ScalarBinaryOpTraits, BinOp> { - enum { Defined = 1 }; typedef AutoDiffScalar ReturnType; }; -} // end namespace internal + +// The following is an attempt to let Eigen's known about expression template, but that's more tricky! + +// template +// struct ScalarBinaryOpTraits,AutoDiffScalar, BinOp> +// { +// enum { Defined = 1 }; +// typedef AutoDiffScalar ReturnType; +// }; +// +// template +// struct ScalarBinaryOpTraits,AutoDiffScalar, BinOp> +// { +// enum { Defined = 1 };//internal::is_same::value }; +// typedef AutoDiffScalar ReturnType; +// }; #define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC,CODE) \ template \ - inline const Eigen::AutoDiffScalar::type>::Scalar>, const typename Eigen::internal::remove_all::type> > \ + inline const Eigen::AutoDiffScalar< \ + EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename Eigen::internal::remove_all::type, typename Eigen::internal::traits::type>::Scalar, product) > \ FUNC(const Eigen::AutoDiffScalar& x) { \ using namespace Eigen; \ - typedef typename Eigen::internal::traits::type>::Scalar Scalar; \ - typedef AutoDiffScalar, const typename Eigen::internal::remove_all::type> > ReturnType; \ + EIGEN_UNUSED typedef typename Eigen::internal::traits::type>::Scalar Scalar; \ CODE; \ } @@ -536,75 +545,92 @@ inline const AutoDiffScalar& real(const AutoDiffScalar& x) { template inline typename DerType::Scalar imag(const AutoDiffScalar&) { return 0.; } template -inline AutoDiffScalar (min)(const AutoDiffScalar& x, const T& y) { return (x <= y ? x : y); } +inline AutoDiffScalar::type::PlainObject> (min)(const AutoDiffScalar& x, const T& y) { + typedef AutoDiffScalar::type::PlainObject> ADS; + return (x <= y ? ADS(x) : ADS(y)); +} template -inline AutoDiffScalar (max)(const AutoDiffScalar& x, const T& y) { return (x >= y ? x : y); } +inline AutoDiffScalar::type::PlainObject> (max)(const AutoDiffScalar& x, const T& y) { + typedef AutoDiffScalar::type::PlainObject> ADS; + return (x >= y ? ADS(x) : ADS(y)); +} template -inline AutoDiffScalar (min)(const T& x, const AutoDiffScalar& y) { return (x < y ? x : y); } +inline AutoDiffScalar::type::PlainObject> (min)(const T& x, const AutoDiffScalar& y) { + typedef AutoDiffScalar::type::PlainObject> ADS; + return (x < y ? ADS(x) : ADS(y)); +} template -inline AutoDiffScalar (max)(const T& x, const AutoDiffScalar& y) { return (x > y ? x : y); } +inline AutoDiffScalar::type::PlainObject> (max)(const T& x, const AutoDiffScalar& y) { + typedef AutoDiffScalar::type::PlainObject> ADS; + return (x > y ? ADS(x) : ADS(y)); +} +template +inline AutoDiffScalar::type::PlainObject> (min)(const AutoDiffScalar& x, const AutoDiffScalar& y) { + return (x.value() < y.value() ? x : y); +} +template +inline AutoDiffScalar::type::PlainObject> (max)(const AutoDiffScalar& x, const AutoDiffScalar& y) { + return (x.value() >= y.value() ? x : y); +} + EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs, using std::abs; - return ReturnType(abs(x.value()), x.derivatives() * (x.value()<0 ? -1 : 1) );) + return Eigen::MakeAutoDiffScalar(abs(x.value()), x.derivatives() * (x.value()<0 ? -1 : 1) );) EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs2, using numext::abs2; - return ReturnType(abs2(x.value()), x.derivatives() * (Scalar(2)*x.value()));) + return Eigen::MakeAutoDiffScalar(abs2(x.value()), x.derivatives() * (Scalar(2)*x.value()));) EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sqrt, using std::sqrt; Scalar sqrtx = sqrt(x.value()); - return ReturnType(sqrtx,x.derivatives() * (Scalar(0.5) / sqrtx));) + return Eigen::MakeAutoDiffScalar(sqrtx,x.derivatives() * (Scalar(0.5) / sqrtx));) EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cos, using std::cos; using std::sin; - return ReturnType(cos(x.value()), x.derivatives() * (-sin(x.value())));) + return Eigen::MakeAutoDiffScalar(cos(x.value()), x.derivatives() * (-sin(x.value())));) EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sin, using std::sin; using std::cos; - return ReturnType(sin(x.value()),x.derivatives() * cos(x.value()));) + return Eigen::MakeAutoDiffScalar(sin(x.value()),x.derivatives() * cos(x.value()));) EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(exp, using std::exp; Scalar expx = exp(x.value()); - return ReturnType(expx,x.derivatives() * expx);) + return Eigen::MakeAutoDiffScalar(expx,x.derivatives() * expx);) EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log, using std::log; - return ReturnType(log(x.value()),x.derivatives() * (Scalar(1)/x.value()));) + return Eigen::MakeAutoDiffScalar(log(x.value()),x.derivatives() * (Scalar(1)/x.value()));) template -inline const Eigen::AutoDiffScalar::Scalar>, const DerType> > -pow(const Eigen::AutoDiffScalar& x, typename Eigen::internal::traits::Scalar y) +inline const Eigen::AutoDiffScalar< +EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all::type,typename internal::traits::type>::Scalar,product) > +pow(const Eigen::AutoDiffScalar &x, const typename internal::traits::type>::Scalar &y) { using namespace Eigen; - typedef typename Eigen::internal::traits::Scalar Scalar; - return AutoDiffScalar, const DerType> >( - std::pow(x.value(),y), - x.derivatives() * (y * std::pow(x.value(),y-1))); + using std::pow; + return Eigen::MakeAutoDiffScalar(pow(x.value(),y), x.derivatives() * (y * pow(x.value(),y-1))); } template -inline const AutoDiffScalar::Scalar,Dynamic,1> > +inline const AutoDiffScalar::type>::Scalar,Dynamic,1> > atan2(const AutoDiffScalar& a, const AutoDiffScalar& b) { using std::atan2; - using std::max; - typedef typename internal::traits::Scalar Scalar; + typedef typename internal::traits::type>::Scalar Scalar; typedef AutoDiffScalar > PlainADS; PlainADS ret; ret.value() = atan2(a.value(), b.value()); - Scalar tmp2 = a.value() * a.value(); - Scalar tmp3 = b.value() * b.value(); - Scalar tmp4 = tmp3/(tmp2+tmp3); + Scalar squared_hypot = a.value() * a.value() + b.value() * b.value(); - if (tmp4!=0) - ret.derivatives() = (a.derivatives() * b.value() - a.value() * b.derivatives()) * (tmp2+tmp3); + // if (squared_hypot==0) the derivation is undefined and the following results in a NaN: + ret.derivatives() = (a.derivatives() * b.value() - a.value() * b.derivatives()) / squared_hypot; return ret; } @@ -612,26 +638,44 @@ atan2(const AutoDiffScalar& a, const AutoDiffScalar& b) EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tan, using std::tan; using std::cos; - return ReturnType(tan(x.value()),x.derivatives() * (Scalar(1)/numext::abs2(cos(x.value()))));) + return Eigen::MakeAutoDiffScalar(tan(x.value()),x.derivatives() * (Scalar(1)/numext::abs2(cos(x.value()))));) EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(asin, using std::sqrt; using std::asin; - return ReturnType(asin(x.value()),x.derivatives() * (Scalar(1)/sqrt(1-numext::abs2(x.value()))));) + return Eigen::MakeAutoDiffScalar(asin(x.value()),x.derivatives() * (Scalar(1)/sqrt(1-numext::abs2(x.value()))));) EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(acos, using std::sqrt; using std::acos; - return ReturnType(acos(x.value()),x.derivatives() * (Scalar(-1)/sqrt(1-numext::abs2(x.value()))));) + return Eigen::MakeAutoDiffScalar(acos(x.value()),x.derivatives() * (Scalar(-1)/sqrt(1-numext::abs2(x.value()))));) + +EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tanh, + using std::cosh; + using std::tanh; + return Eigen::MakeAutoDiffScalar(tanh(x.value()),x.derivatives() * (Scalar(1)/numext::abs2(cosh(x.value()))));) + +EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sinh, + using std::sinh; + using std::cosh; + return Eigen::MakeAutoDiffScalar(sinh(x.value()),x.derivatives() * cosh(x.value()));) + +EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cosh, + using std::sinh; + using std::cosh; + return Eigen::MakeAutoDiffScalar(cosh(x.value()),x.derivatives() * sinh(x.value()));) #undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY template struct NumTraits > - : NumTraits< typename NumTraits::Real > + : NumTraits< typename NumTraits::type::Scalar>::Real > { - typedef AutoDiffScalar::Real,DerType::RowsAtCompileTime,DerType::ColsAtCompileTime> > Real; + typedef typename internal::remove_all::type DerTypeCleaned; + typedef AutoDiffScalar::Real,DerTypeCleaned::RowsAtCompileTime,DerTypeCleaned::ColsAtCompileTime, + 0, DerTypeCleaned::MaxRowsAtCompileTime, DerTypeCleaned::MaxColsAtCompileTime> > Real; typedef AutoDiffScalar NonInteger; typedef AutoDiffScalar Nested; + typedef typename NumTraits::Literal Literal; enum{ RequireInitialization = 1 }; diff --git a/eigen/unsupported/Eigen/src/AutoDiff/CMakeLists.txt b/eigen/unsupported/Eigen/src/AutoDiff/CMakeLists.txt deleted file mode 100644 index ad91fd9..0000000 --- a/eigen/unsupported/Eigen/src/AutoDiff/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -FILE(GLOB Eigen_AutoDiff_SRCS "*.h") - -INSTALL(FILES - ${Eigen_AutoDiff_SRCS} - DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/AutoDiff COMPONENT Devel - ) -- cgit v1.2.3