bug #1281: fix AutoDiffScalar's make_coherent for nested expression of constant ADs.
diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h index 2db9147..88edd6b 100755 --- a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h +++ b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
@@ -453,6 +453,24 @@ void operator+() const; }; +template<typename BinOp, typename A, typename B, typename RefType> +void make_coherent_expression(CwiseBinaryOp<BinOp,A,B> xpr, const RefType &ref) +{ + make_coherent(xpr.const_cast_derived().lhs(), ref); + make_coherent(xpr.const_cast_derived().rhs(), ref); +} + +template<typename UnaryOp, typename A, typename RefType> +void make_coherent_expression(const CwiseUnaryOp<UnaryOp,A> &xpr, const RefType &ref) +{ + make_coherent(xpr.nestedExpression().const_cast_derived(), ref); +} + +// needed for compilation only +template<typename UnaryOp, typename A, typename RefType> +void make_coherent_expression(const CwiseNullaryOp<UnaryOp,A> &, const RefType &) +{} + template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols, typename B> struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>, B> { typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A; @@ -462,6 +480,10 @@ a.resize(b.size()); a.setZero(); } + else if (B::SizeAtCompileTime==Dynamic && a.size()!=0 && b.size()==0) + { + make_coherent_expression(b,a); + } } }; @@ -474,13 +496,17 @@ b.resize(a.size()); b.setZero(); } + else if (A::SizeAtCompileTime==Dynamic && b.size()!=0 && a.size()==0) + { + make_coherent_expression(a,b); + } } }; template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols, typename B_Scalar, int B_Rows, int B_Cols, int B_Options, int B_MaxRows, int B_MaxCols> struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>, - Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > { + Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > { typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A; typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B; static void run(A& a, B& b) {
diff --git a/unsupported/test/autodiff.cpp b/unsupported/test/autodiff.cpp index bafea6a..2cea56b 100644 --- a/unsupported/test/autodiff.cpp +++ b/unsupported/test/autodiff.cpp
@@ -352,6 +352,21 @@ return v2(0).value(); } +// check with expressions on constants +double bug_1281() { + int n = 2; + typedef AutoDiffScalar<VectorXd> AD; + const AD c = 1.; + AD x0(2,n,0); + AD y1 = (AD(c)+AD(c))*x0; + y1 = x0 * (AD(c)+AD(c)); + AD y2 = (-AD(c))+x0; + y2 = x0+(-AD(c)); + AD y3 = (AD(c)*(-AD(c))+AD(c))*x0; + y3 = x0 * (AD(c)*(-AD(c))+AD(c)); + return (y1+y2+y3).value(); +} + #endif EIGEN_DECLARE_TEST(autodiff) @@ -367,5 +382,6 @@ CALL_SUBTEST_5( bug_1223() ); CALL_SUBTEST_5( bug_1260() ); CALL_SUBTEST_5( bug_1261() ); + CALL_SUBTEST_5( bug_1281() ); }