From 7b0c4102facc9b5f6ca99ef76febb05a9499b8b0 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Fri, 16 Oct 2009 13:22:38 +0200 Subject: * add a Make* expression type builder to allow the construction of generic expressions working for both dense and sparse matrix. A nicer solution would be to use CwiseBinaryOp for any kind of matrix. To this end we either need to change the overall design so that the base class(es) depends on the kind of matrix, or we could add a template parameter to each expression type (e.g., int Kind = ei_traits::Kind) allowing to specialize each expression for each kind of matrix. * Extend AutoDiffScalar to work with sparse vector expression for the derivatives. --- unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h | 85 ++++++++++++++----------- 1 file changed, 47 insertions(+), 38 deletions(-) (limited to 'unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h') diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h index fc5e237ab..2fb733a99 100644 --- a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h +++ b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h @@ -42,9 +42,17 @@ void ei_make_coherent(const A& a, const B&b) /** \class AutoDiffScalar * \brief A scalar type replacement with automatic differentation capability * - * \param DerType the vector type used to store/represent the derivatives (e.g. Vector3f) + * \param _DerType the vector type used to store/represent the derivatives. The base scalar type + * as well as the number of derivatives to compute are determined from this type. + * Typical choices include, e.g., \c Vector4f for 4 derivatives, or \c VectorXf + * if the number of derivatives is not known at compile time, and/or, the number + * of derivatives is large. + * Note that _DerType can also be a reference (e.g., \c VectorXf&) to wrap a + * existing vector into an AutoDiffScalar. + * Finally, _DerType can also be any Eigen compatible expression. * - * This class represents a scalar value while tracking its respective derivatives. + * This class represents a scalar value while tracking its respective derivatives using Eigen's expression + * template mechanism. * * It supports the following list of global math function: * - std::abs, std::sqrt, std::pow, std::exp, std::log, std::sin, std::cos, @@ -56,10 +64,11 @@ void ei_make_coherent(const A& a, const B&b) * while derivatives are computed right away. * */ -template +template class AutoDiffScalar { public: + typedef typename ei_cleantype<_DerType>::type DerType; typedef typename ei_traits::Scalar Scalar; inline AutoDiffScalar() {} @@ -108,12 +117,12 @@ class AutoDiffScalar inline const DerType& derivatives() const { return m_derivatives; } inline DerType& derivatives() { return m_derivatives; } - inline const AutoDiffScalar operator+(const Scalar& other) const + inline const AutoDiffScalar operator+(const Scalar& other) const { return AutoDiffScalar(m_value + other, m_derivatives); } - friend inline const AutoDiffScalar operator+(const Scalar& a, const AutoDiffScalar& b) + friend inline const AutoDiffScalar operator+(const Scalar& a, const AutoDiffScalar& b) { return AutoDiffScalar(a + b.value(), b.derivatives()); } @@ -125,11 +134,11 @@ class AutoDiffScalar } template - inline const AutoDiffScalar,DerType,OtherDerType> > + inline const AutoDiffScalar,DerType,typename ei_cleantype::type>::Type > operator+(const AutoDiffScalar& other) const { ei_make_coherent(m_derivatives, other.derivatives()); - return AutoDiffScalar,DerType,OtherDerType> >( + return AutoDiffScalar,DerType,typename ei_cleantype::type>::Type >( m_value + other.value(), m_derivatives + other.derivatives()); } @@ -143,11 +152,11 @@ class AutoDiffScalar } template - inline const AutoDiffScalar, DerType,OtherDerType> > + inline const AutoDiffScalar, DerType,typename ei_cleantype::type>::Type > operator-(const AutoDiffScalar& other) const { ei_make_coherent(m_derivatives, other.derivatives()); - return AutoDiffScalar, DerType,OtherDerType> >( + return AutoDiffScalar, DerType,typename ei_cleantype::type>::Type >( m_value - other.value(), m_derivatives - other.derivatives()); } @@ -161,73 +170,73 @@ class AutoDiffScalar } template - inline const AutoDiffScalar, DerType> > + inline const AutoDiffScalar, DerType>::Type > operator-() const { - return AutoDiffScalar, DerType> >( + return AutoDiffScalar, DerType>::Type >( -m_value, -m_derivatives); } - inline const AutoDiffScalar, DerType> > + inline const AutoDiffScalar, DerType>::Type > operator*(const Scalar& other) const { - return AutoDiffScalar, DerType> >( + return AutoDiffScalar, DerType>::Type >( m_value * other, (m_derivatives * other)); } - friend inline const AutoDiffScalar, DerType> > + friend inline const AutoDiffScalar, DerType>::Type > operator*(const Scalar& other, const AutoDiffScalar& a) { - return AutoDiffScalar, DerType> >( + return AutoDiffScalar, DerType>::Type >( a.value() * other, a.derivatives() * other); } - inline const AutoDiffScalar, DerType> > + inline const AutoDiffScalar, DerType>::Type > operator/(const Scalar& other) const { - return AutoDiffScalar, DerType> >( + return AutoDiffScalar, DerType>::Type >( m_value / other, (m_derivatives * (Scalar(1)/other))); } - friend inline const AutoDiffScalar, DerType> > + friend inline const AutoDiffScalar, DerType>::Type > operator/(const Scalar& other, const AutoDiffScalar& a) { - return AutoDiffScalar, DerType> >( + return AutoDiffScalar, DerType>::Type >( other / a.value(), a.derivatives() * (-Scalar(1)/other)); } template - inline const AutoDiffScalar, - NestByValue, - NestByValue, DerType> >, - NestByValue, OtherDerType> > > > > > + inline const AutoDiffScalar, + typename MakeNestByValue, + typename MakeNestByValue, DerType>::Type>::Type, + typename MakeNestByValue, typename ei_cleantype::type>::Type>::Type >::Type >::Type >::Type > operator/(const AutoDiffScalar& other) const { ei_make_coherent(m_derivatives, other.derivatives()); - return AutoDiffScalar, - NestByValue, - NestByValue, DerType> >, - NestByValue, OtherDerType> > > > > >( + return AutoDiffScalar, + typename MakeNestByValue, + typename MakeNestByValue, DerType>::Type>::Type, + typename MakeNestByValue, typename ei_cleantype::type>::Type>::Type >::Type >::Type >::Type >( m_value / other.value(), ((m_derivatives * other.value()).nestByValue() - (m_value * other.derivatives()).nestByValue()).nestByValue() * (Scalar(1)/(other.value()*other.value()))); } template - inline const AutoDiffScalar, - NestByValue, DerType> >, - NestByValue, OtherDerType> > > > + inline const AutoDiffScalar, + typename MakeNestByValue, DerType>::Type>::Type, + typename MakeNestByValue, typename ei_cleantype::type>::Type>::Type >::Type > operator*(const AutoDiffScalar& other) const { ei_make_coherent(m_derivatives, other.derivatives()); - return AutoDiffScalar, - NestByValue, DerType> >, - NestByValue, OtherDerType> > > >( + return AutoDiffScalar, + typename MakeNestByValue, DerType>::Type>::Type, + typename MakeNestByValue, typename ei_cleantype::type>::Type>::Type >::Type >( m_value * other.value(), (m_derivatives * other.value()).nestByValue() + (m_value * other.derivatives()).nestByValue()); } @@ -299,11 +308,11 @@ struct ei_make_coherent_impl \ - inline const Eigen::AutoDiffScalar::Scalar>, DerType> > \ + inline const Eigen::AutoDiffScalar::Scalar>, DerType>::Type > \ FUNC(const Eigen::AutoDiffScalar& x) { \ using namespace Eigen; \ typedef typename ei_traits::Scalar Scalar; \ - typedef AutoDiffScalar, DerType> > ReturnType; \ + typedef AutoDiffScalar, DerType>::Type > ReturnType; \ CODE; \ } @@ -330,12 +339,12 @@ namespace std return ReturnType(std::log(x.value),x.derivatives() * (Scalar(1).x.value()));) template - inline const Eigen::AutoDiffScalar::Scalar>, DerType> > + inline const Eigen::AutoDiffScalar::Scalar>, DerType>::Type > pow(const Eigen::AutoDiffScalar& x, typename Eigen::ei_traits::Scalar y) { using namespace Eigen; typedef typename ei_traits::Scalar Scalar; - return AutoDiffScalar, DerType> >( + return AutoDiffScalar, DerType>::Type >( std::pow(x.value(),y), x.derivatives() * (y * std::pow(x.value(),y-1))); } @@ -375,7 +384,7 @@ EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(ei_log, return ReturnType(ei_log(x.value),x.derivatives() * (Scalar(1).x.value()));) template -inline const AutoDiffScalar::Scalar>, DerType> > +inline const AutoDiffScalar::Scalar>, DerType>::Type > ei_pow(const AutoDiffScalar& x, typename ei_traits::Scalar y) { return std::pow(x,y);} -- cgit v1.2.3