aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Eugene Zhulenev <ezhulenev@google.com>2018-10-10 13:23:52 -0700
committerGravatar Eugene Zhulenev <ezhulenev@google.com>2018-10-10 13:23:52 -0700
commit8e6dc2c81d478ae1c1699ec69eb02cc42a84ffbf (patch)
tree42e7035b63d617756306065d36e32ca0e46891a1
parentf3130ee1bab17d7d031d08d031d078707a67e3d1 (diff)
Fix bug in partial reduction of expressions requiring evaluation
-rw-r--r--Eigen/src/Core/PartialReduxEvaluator.h3
-rw-r--r--test/redux.cpp9
2 files changed, 8 insertions, 4 deletions
diff --git a/Eigen/src/Core/PartialReduxEvaluator.h b/Eigen/src/Core/PartialReduxEvaluator.h
index 0bf8a50e0..d9c0f1224 100644
--- a/Eigen/src/Core/PartialReduxEvaluator.h
+++ b/Eigen/src/Core/PartialReduxEvaluator.h
@@ -134,7 +134,6 @@ struct evaluator<PartialReduxExpr<ArgType, MemberOp, Direction> >
{
typedef PartialReduxExpr<ArgType, MemberOp, Direction> XprType;
typedef typename internal::nested_eval<ArgType,1>::type ArgTypeNested;
- typedef typename internal::remove_all<ArgTypeNested>::type ArgTypeNestedCleaned;
typedef typename ArgType::Scalar InputScalar;
typedef typename XprType::Scalar Scalar;
enum {
@@ -194,7 +193,7 @@ struct evaluator<PartialReduxExpr<ArgType, MemberOp, Direction> >
PacketType packet(Index idx) const
{
enum { PacketSize = internal::unpacket_traits<PacketType>::size };
- typedef Block<const ArgType,
+ typedef Block<typename internal::add_const_on_value_type<ArgTypeNested>::type,
Direction==Vertical ? int(ArgType::RowsAtCompileTime) : int(PacketSize),
Direction==Vertical ? int(PacketSize) : int(ArgType::ColsAtCompileTime),
true /* InnerPanel */> PanelType;
diff --git a/test/redux.cpp b/test/redux.cpp
index 9e3ed4546..fdbab7714 100644
--- a/test/redux.cpp
+++ b/test/redux.cpp
@@ -28,6 +28,9 @@ template<typename MatrixType> void matrixRedux(const MatrixType& m)
// failures if we underflow into denormals. Thus, we scale so that entries are close to 1.
MatrixType m1_for_prod = MatrixType::Ones(rows, cols) + RealScalar(0.2) * m1;
+ Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> m2(rows,rows);
+ m2.setRandom();
+
VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows, cols).sum(), Scalar(1));
VERIFY_IS_APPROX(MatrixType::Ones(rows, cols).sum(), Scalar(float(rows*cols))); // the float() here to shut up excessive MSVC warning about int->complex conversion being lossy
Scalar s(0), p(1), minc(numext::real(m1.coeff(0))), maxc(numext::real(m1.coeff(0)));
@@ -46,6 +49,10 @@ template<typename MatrixType> void matrixRedux(const MatrixType& m)
VERIFY_IS_APPROX(m1_for_prod.prod(), p);
VERIFY_IS_APPROX(m1.real().minCoeff(), numext::real(minc));
VERIFY_IS_APPROX(m1.real().maxCoeff(), numext::real(maxc));
+
+ // test that partial reduction works if nested expressions is forced to evaluate early
+ VERIFY_IS_APPROX((m1.matrix() * m1.matrix().transpose()) .cwiseProduct(m2.matrix()).rowwise().sum().sum(),
+ (m1.matrix() * m1.matrix().transpose()).eval().cwiseProduct(m2.matrix()).rowwise().sum().sum());
// test slice vectorization assuming assign is ok
Index r0 = internal::random<Index>(0,rows-1);
@@ -72,8 +79,6 @@ template<typename MatrixType> void matrixRedux(const MatrixType& m)
// test nesting complex expression
VERIFY_EVALUATION_COUNT( (m1.matrix()*m1.matrix().transpose()).sum(), (MatrixType::IsVectorAtCompileTime && MatrixType::SizeAtCompileTime!=1 ? 0 : 1) );
- Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> m2(rows,rows);
- m2.setRandom();
VERIFY_EVALUATION_COUNT( ((m1.matrix()*m1.matrix().transpose())+m2).sum(),(MatrixType::IsVectorAtCompileTime && MatrixType::SizeAtCompileTime!=1 ? 0 : 1));
}