New user self-registration is currently disabled. Please email eigen-core-team @ lists.tuxfamily.org if you need an account.
Bug 1189 - AutoDiff pow doesn't work with expression
AutoDiff pow doesn't work with expression
Status: RESOLVED FIXED
Product: Eigen
Classification: Unclassified
Component: Unsupported modules
3.2
All All
: Normal Compilation Problem
Assigned To: Nobody
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2016-04-04 15:57 UTC by Daniel Vollmer
Modified: 2016-07-25 13:06 UTC (History)
2 users (show)



Attachments
failing example (362 bytes, text/x-csrc)
2016-04-04 15:57 UTC, Daniel Vollmer
no flags Details

Description Daniel Vollmer 2016-04-04 15:57:37 UTC
Created attachment 692 [details]
failing example

Trying to use the following expression with an AutoDiffScalar variable triggers a compilation problem:

#include "Eigen/Core"
#include "unsupported/Eigen/AutoDiff"

int main (int argc, char const *argv[])
{
  typedef Eigen::AutoDiffScalar<Eigen::Vector3d> AD;
  
  // original expression: pow(1.0 + 0.5 * _gamma_m1 * (faceMach * faceMach), -_gamma / _gamma_m1);
  const AD faceMach(1.0);
  AD ppp = pow(1.0 + 0.5 * 1.2 * (faceMach * faceMach), 1.2);
  
  return 0;
}

Both clang++ and g++ (5.3.0) fail, g++ reports the following:

adtest.cpp:10:60: error: no matching function for call to 'pow(const Eigen::AutoDiffScalar<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<double>, const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, 3, 1> >, const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, 3, 1> > > >&>, double)'
   AD ppp = pow(1.0 + 0.5 * 1.2 * (faceMach * faceMach), 1.2);


After discarding the irrelevant overloads, the problem seems to be:


thirdparty/eigen-3.2.2/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h:593:1: note: candidate: template<class DerType> const Eigen::AutoDiffScalar<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<typename Eigen::internal::traits<T>::Scalar>, const Derived> > Eigen::pow(const Eigen::AutoDiffScalar<_DerType>&, typename Eigen::internal::traits<T>::Scalar)
 pow(const Eigen::AutoDiffScalar<DerType>& x, typename Eigen::internal::traits<DerType>::Scalar y)
 ^
thirdparty/eigen-3.2.2/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h:593:1: note:   template argument deduction/substitution failed:
thirdparty/eigen-3.2.2/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h: In substitution of 'template<class DerType> const Eigen::AutoDiffScalar<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<typename Eigen::internal::traits<T>::Scalar>, const Derived> > Eigen::pow(const Eigen::AutoDiffScalar<_DerType>&, typename Eigen::internal::traits<T>::Scalar) [with DerType = Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<double>, const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, 3, 1> >, const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, 3, 1> > > >&]':
adtest.cpp:10:60:   required from here
thirdparty/eigen-3.2.2/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h:593:1: error: invalid use of incomplete type 'struct Eigen::internal::traits<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<double>, const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, 3, 1> >, const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, 3, 1> > > >&>'
In file included from thirdparty/eigen-3.2.2/Eigen/Core:252:0,
                 from adtest.cpp:1:
thirdparty/eigen-3.2.2/Eigen/src/Core/util/ForwardDeclarations.h:17:29: note: declaration of 'struct Eigen::internal::traits<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<double>, const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, 3, 1> >, const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, 3, 1> > > >&>'
 template<typename T> struct traits;


The same expression seems to work Eigen::Array instead of the AD-type, so it seems to
be specific to AutoDiff and the expression template mechanism in general. I'm not sure what's
going wrong though to be honest, but it looks like t's the declaration of the 2nd argument to
pow() that's using the traits and thus failing.

It seems that for the non-unary methods that the remove_all is maybe missing?
Comment 1 Daniel Vollmer 2016-04-05 08:46:32 UTC
This seems to fix the problem for pow(). Others (atan2?) will probably have the same problem still:

diff --git a/thirdparty/eigen-3.2.2/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/thirdparty/eigen-3.2.2/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
index e30ad5b..52ceb14 100644
--- a/thirdparty/eigen-3.2.2/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
+++ b/thirdparty/eigen-3.2.2/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
@@ -589,12 +589,12 @@ EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log,
   return ReturnType(log(x.value()),x.derivatives() * (Scalar(1)/x.value()));)
 
 template<typename DerType>
-inline const Eigen::AutoDiffScalar<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<typename Eigen::internal::traits<DerType>::Scalar>, const DerType> >
-pow(const Eigen::AutoDiffScalar<DerType>& x, typename Eigen::internal::traits<DerType>::Scalar y)
+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> >
+pow(const Eigen::AutoDiffScalar<DerType>& x, typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar y)
 {
   using namespace Eigen;
-  typedef typename Eigen::internal::traits<DerType>::Scalar Scalar;
-  return AutoDiffScalar<CwiseUnaryOp<Eigen::internal::scalar_multiple_op<Scalar>, const DerType> >(
+  typedef typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar Scalar;
+  return AutoDiffScalar<CwiseUnaryOp<Eigen::internal::scalar_multiple_op<Scalar>, const typename Eigen::internal::remove_all<DerType>::type> >(
     std::pow(x.value(),y),
     x.derivatives() * (y * std::pow(x.value(),y-1)));
 }
Comment 2 Gael Guennebaud 2016-04-05 12:50:45 UTC
thank you for the report and patch.

https://bitbucket.org/eigen/eigen/commits/78884e16715f/
Comment 3 Daniel Vollmer 2016-07-25 12:41:44 UTC
Just as a note: These changes were not back-ported to 3.2 (and I intend to wait for the next beta / RC of 3.3 before testing our code with 3.3, as quite a few things seem to no longer work — but I'm not sure whether the problem is using an in-development snapshot of 3.3, AutoDiffScalar, or me using them incorrectly ;)).
Comment 4 Gael Guennebaud 2016-07-25 13:06:57 UTC
This would be too painful, but next 3.3 beta/RC is coming soon.

Note You need to log in before you can comment on or make changes to this bug.