From 4854326ae88223f2e897c33beb2013d9b2351e18 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Tue, 29 Mar 2016 22:39:12 +0200 Subject: [PATCH] Fix usage of nesting type in blas_traits. In practice, this fixes compilation of expressions such as A*(A*A)^T where a product is hidden behind an expression supported by blas-traits. --- Eigen/src/Core/util/BlasUtil.h | 36 +++++++++++++++++++--------------- test/product.h | 8 ++++++++ 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/Eigen/src/Core/util/BlasUtil.h b/Eigen/src/Core/util/BlasUtil.h index a28f16fa0..9d03af319 100644 --- a/Eigen/src/Core/util/BlasUtil.h +++ b/Eigen/src/Core/util/BlasUtil.h @@ -171,12 +171,13 @@ template struct blas_traits }; // pop conjugate -template -struct blas_traits, NestedXpr> > - : blas_traits +template +struct blas_traits, Xpr> > + : blas_traits::type> { + typedef typename internal::remove_all::type NestedXpr; typedef blas_traits Base; - typedef CwiseUnaryOp, NestedXpr> XprType; + typedef CwiseUnaryOp, Xpr> XprType; typedef typename Base::ExtractType ExtractType; enum { @@ -188,12 +189,13 @@ struct blas_traits, NestedXpr> > }; // pop scalar multiple -template -struct blas_traits, NestedXpr> > - : blas_traits +template +struct blas_traits, Xpr> > + : blas_traits::type> { + typedef typename internal::remove_all::type NestedXpr; typedef blas_traits Base; - typedef CwiseUnaryOp, NestedXpr> XprType; + typedef CwiseUnaryOp, Xpr> XprType; typedef typename Base::ExtractType ExtractType; static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } static inline Scalar extractScalarFactor(const XprType& x) @@ -201,12 +203,13 @@ struct blas_traits, NestedXpr> > }; // pop opposite -template -struct blas_traits, NestedXpr> > - : blas_traits +template +struct blas_traits, Xpr> > + : blas_traits::type> { + typedef typename internal::remove_all::type NestedXpr; typedef blas_traits Base; - typedef CwiseUnaryOp, NestedXpr> XprType; + typedef CwiseUnaryOp, Xpr> XprType; typedef typename Base::ExtractType ExtractType; static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } static inline Scalar extractScalarFactor(const XprType& x) @@ -214,13 +217,14 @@ struct blas_traits, NestedXpr> > }; // pop/push transpose -template -struct blas_traits > - : blas_traits +template +struct blas_traits > + : blas_traits::type> { + typedef typename internal::remove_all::type NestedXpr; typedef typename NestedXpr::Scalar Scalar; typedef blas_traits Base; - typedef Transpose XprType; + typedef Transpose XprType; typedef Transpose ExtractType; // const to get rid of a compile error; anyway blas traits are only used on the RHS typedef Transpose _ExtractType; typedef typename conditional void product(const MatrixType& m) // CwiseUnaryOp VERIFY_IS_APPROX(x = Scalar(1.)*(A*x), A*z); } + + // regression for blas_trais + { + VERIFY_IS_APPROX(square * (square*square).transpose(), square * square.transpose() * square.transpose()); + VERIFY_IS_APPROX(square * (-(square*square)), -square * square * square); + VERIFY_IS_APPROX(square * (s1*(square*square)), s1 * square * square * square); + VERIFY_IS_APPROX(square * (square*square).conjugate(), square * square.conjugate() * square.conjugate()); + } }