Update AutoDiffScalar wrt to scalar-multiple.

This commit is contained in:
Gael Guennebaud 2016-06-14 15:06:35 +02:00
parent 5d38203735
commit 62134082aa
2 changed files with 43 additions and 48 deletions

View File

@ -462,6 +462,8 @@
#define EIGEN_CAT2(a,b) a ## b #define EIGEN_CAT2(a,b) a ## b
#define EIGEN_CAT(a,b) EIGEN_CAT2(a,b) #define EIGEN_CAT(a,b) EIGEN_CAT2(a,b)
#define EIGEN_COMMA ,
// convert a token to a string // convert a token to a string
#define EIGEN_MAKESTRING2(a) #a #define EIGEN_MAKESTRING2(a) #a
#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a) #define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a)

View File

@ -30,6 +30,13 @@ template<typename _DerType, bool Enable> struct auto_diff_special_op;
} // end namespace internal } // end namespace internal
template<typename _DerType> class AutoDiffScalar;
template<typename NewDerType>
inline AutoDiffScalar<NewDerType> MakeAutoDiffScalar(const typename NewDerType::Scalar& value, const NewDerType &der) {
return AutoDiffScalar<NewDerType>(value,der);
}
/** \class AutoDiffScalar /** \class AutoDiffScalar
* \brief A scalar type replacement with automatic differentation capability * \brief A scalar type replacement with automatic differentation capability
* *
@ -257,20 +264,16 @@ class AutoDiffScalar
-m_derivatives); -m_derivatives);
} }
inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> > inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
operator*(const Scalar& other) const operator*(const Scalar& other) const
{ {
return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >( return MakeAutoDiffScalar(m_value * other, m_derivatives * other);
m_value * other,
(m_derivatives * other));
} }
friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> > friend inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
operator*(const Scalar& other, const AutoDiffScalar& a) operator*(const Scalar& other, const AutoDiffScalar& a)
{ {
return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >( return MakeAutoDiffScalar(a.value() * other, a.derivatives() * other);
a.value() * other,
a.derivatives() * other);
} }
// inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type > // inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
@ -289,20 +292,16 @@ class AutoDiffScalar
// a.derivatives() * other); // a.derivatives() * other);
// } // }
inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> > inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
operator/(const Scalar& other) const operator/(const Scalar& other) const
{ {
return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >( return MakeAutoDiffScalar(m_value / other, (m_derivatives * (Scalar(1)/other)));
m_value / other,
(m_derivatives * (Scalar(1)/other)));
} }
friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> > friend inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
operator/(const Scalar& other, const AutoDiffScalar& a) operator/(const Scalar& other, const AutoDiffScalar& a)
{ {
return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >( return MakeAutoDiffScalar(other / a.value(), a.derivatives() * (Scalar(-other) / (a.value()*a.value())));
other / a.value(),
a.derivatives() * (Scalar(-other) / (a.value()*a.value())));
} }
// inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type > // inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >
@ -322,34 +321,29 @@ class AutoDiffScalar
// } // }
template<typename OtherDerType> template<typename OtherDerType>
inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(
const CwiseBinaryOp<internal::scalar_difference_op<Scalar>, CwiseBinaryOp<internal::scalar_difference_op<Scalar> EIGEN_COMMA
const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>, const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) EIGEN_COMMA
const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type > > > > const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<OtherDerType>::type,Scalar,product) >,Scalar,product) >
operator/(const AutoDiffScalar<OtherDerType>& other) const operator/(const AutoDiffScalar<OtherDerType>& other) const
{ {
internal::make_coherent(m_derivatives, other.derivatives()); internal::make_coherent(m_derivatives, other.derivatives());
return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, return MakeAutoDiffScalar(
const CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>,
const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type > > > >(
m_value / other.value(), 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()))); * (Scalar(1)/(other.value()*other.value())));
} }
template<typename OtherDerType> template<typename OtherDerType>
inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>, inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>, const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product),
const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type> > > const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<OtherDerType>::type,Scalar,product) > >
operator*(const AutoDiffScalar<OtherDerType>& other) const operator*(const AutoDiffScalar<OtherDerType>& other) const
{ {
internal::make_coherent(m_derivatives, other.derivatives()); internal::make_coherent(m_derivatives, other.derivatives());
return AutoDiffScalar<const CwiseBinaryOp<internal::scalar_sum_op<Scalar>, return MakeAutoDiffScalar(
const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>,
const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type > > >(
m_value * other.value(), 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) inline AutoDiffScalar& operator*=(const Scalar& other)
@ -533,11 +527,11 @@ struct ScalarBinaryOpTraits<typename DerType::Scalar,AutoDiffScalar<DerType> >
#define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC,CODE) \ #define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC,CODE) \
template<typename DerType> \ template<typename DerType> \
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> > \ inline const Eigen::AutoDiffScalar< \
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) > \
FUNC(const Eigen::AutoDiffScalar<DerType>& x) { \ FUNC(const Eigen::AutoDiffScalar<DerType>& x) { \
using namespace Eigen; \ using namespace Eigen; \
typedef typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar Scalar; \ typedef typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar Scalar; \
typedef AutoDiffScalar<CwiseUnaryOp<Eigen::internal::scalar_multiple_op<Scalar>, const typename Eigen::internal::remove_all<DerType>::type> > ReturnType; \
CODE; \ CODE; \
} }
@ -570,46 +564,45 @@ inline AutoDiffScalar<typename Eigen::internal::remove_all<DerType>::type::Plain
EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs, EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs,
using std::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, EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs2,
using numext::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, EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sqrt,
using std::sqrt; using std::sqrt;
Scalar sqrtx = sqrt(x.value()); 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, EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cos,
using std::cos; using std::cos;
using std::sin; 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, EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sin,
using std::sin; using std::sin;
using std::cos; 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, EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(exp,
using std::exp; using std::exp;
Scalar expx = exp(x.value()); Scalar expx = exp(x.value());
return ReturnType(expx,x.derivatives() * expx);) return Eigen::MakeAutoDiffScalar(expx,x.derivatives() * expx);)
EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log, EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log,
using std::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<typename DerType> template<typename DerType>
inline const Eigen::AutoDiffScalar<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<typename internal::traits<typename internal::remove_all<DerType>::type>::Scalar>, const typename internal::remove_all<DerType>::type> > inline const Eigen::AutoDiffScalar<
EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<DerType>::type,typename internal::traits<typename internal::remove_all<DerType>::type>::Scalar,product) >
pow(const Eigen::AutoDiffScalar<DerType> &x, const typename internal::traits<typename internal::remove_all<DerType>::type>::Scalar &y) pow(const Eigen::AutoDiffScalar<DerType> &x, const typename internal::traits<typename internal::remove_all<DerType>::type>::Scalar &y)
{ {
using namespace Eigen; using namespace Eigen;
typedef typename internal::remove_all<DerType>::type DerTypeCleaned; typedef typename internal::remove_all<DerType>::type DerTypeCleaned;
typedef typename Eigen::internal::traits<DerTypeCleaned>::Scalar Scalar; typedef typename Eigen::internal::traits<DerTypeCleaned>::Scalar Scalar;
return AutoDiffScalar<CwiseUnaryOp<Eigen::internal::scalar_multiple_op<Scalar>, const DerTypeCleaned> >( return Eigen::MakeAutoDiffScalar(std::pow(x.value(),y), x.derivatives() * (y * std::pow(x.value(),y-1)));
std::pow(x.value(),y),
x.derivatives() * (y * std::pow(x.value(),y-1)));
} }
@ -634,17 +627,17 @@ atan2(const AutoDiffScalar<DerTypeA>& a, const AutoDiffScalar<DerTypeB>& b)
EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tan, EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tan,
using std::tan; using std::tan;
using std::cos; 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, EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(asin,
using std::sqrt; using std::sqrt;
using std::asin; 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, EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(acos,
using std::sqrt; using std::sqrt;
using std::acos; 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()))));)
#undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY #undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY