diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h index b1dd7d727..504a51229 100644 --- a/Eigen/src/Core/Redux.h +++ b/Eigen/src/Core/Redux.h @@ -183,7 +183,7 @@ struct ei_redux_impl typedef typename Derived::Index Index; static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func) { - ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using a non initialized matrix"); + ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); Scalar res; res = mat.coeffByOuterInner(0, 0); for(Index i = 1; i < mat.innerSize(); ++i) @@ -210,6 +210,7 @@ struct ei_redux_impl static Scalar run(const Derived& mat, const Func& func) { const Index size = mat.size(); + ei_assert(size && "you are using an empty matrix"); const Index packetSize = ei_packet_traits::size; const Index alignedStart = ei_first_aligned(mat); enum { @@ -253,6 +254,7 @@ struct ei_redux_impl static Scalar run(const Derived& mat, const Func& func) { + ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); const Index innerSize = mat.innerSize(); const Index outerSize = mat.outerSize(); enum { @@ -294,6 +296,7 @@ struct ei_redux_impl0 && mat.cols()>0 && "you are using an empty matrix"); Scalar res = func.predux(ei_redux_vec_unroller::run(mat,func)); if (VectorizedSize != Size) res = func(res,ei_redux_novec_unroller::run(mat,func)); @@ -345,6 +348,8 @@ template EIGEN_STRONG_INLINE typename ei_traits::Scalar DenseBase::sum() const { + if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0)) + return Scalar(0); return this->redux(Eigen::ei_scalar_sum_op()); } @@ -370,6 +375,8 @@ template EIGEN_STRONG_INLINE typename ei_traits::Scalar DenseBase::prod() const { + if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0)) + return Scalar(1); return this->redux(Eigen::ei_scalar_product_op()); } diff --git a/test/array_for_matrix.cpp b/test/array_for_matrix.cpp index 01e31d05b..3699b861a 100644 --- a/test/array_for_matrix.cpp +++ b/test/array_for_matrix.cpp @@ -72,6 +72,10 @@ template void array_for_matrix(const MatrixType& m) VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1); m3 = m1; VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1); + + // empty objects + VERIFY_IS_APPROX(m1.block(0,0,0,cols).colwise().sum(), RowVectorType::Zero(cols)); + VERIFY_IS_APPROX(m1.block(0,0,rows,0).rowwise().prod(), ColVectorType::Ones(rows)); } template void comparisons(const MatrixType& m) diff --git a/test/redux.cpp b/test/redux.cpp index b28252903..9a1df71a8 100644 --- a/test/redux.cpp +++ b/test/redux.cpp @@ -64,6 +64,10 @@ template void matrixRedux(const MatrixType& m) VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).prod(), m1.block(r0,c0,r1,c1).eval().prod()); VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().minCoeff(), m1.block(r0,c0,r1,c1).real().eval().minCoeff()); VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().maxCoeff(), m1.block(r0,c0,r1,c1).real().eval().maxCoeff()); + + // test empty objects + VERIFY_IS_APPROX(m1.block(r0,c0,0,0).sum(), Scalar(0)); + VERIFY_IS_APPROX(m1.block(r0,c0,0,0).prod(), Scalar(1)); } template void vectorRedux(const VectorType& w) @@ -124,6 +128,13 @@ template void vectorRedux(const VectorType& w) VERIFY_IS_APPROX(minc, v.real().segment(i, size-2*i).minCoeff()); VERIFY_IS_APPROX(maxc, v.real().segment(i, size-2*i).maxCoeff()); } + + // test empty objects + VERIFY_IS_APPROX(v.head(0).sum(), Scalar(0)); + VERIFY_IS_APPROX(v.tail(0).prod(), Scalar(1)); + VERIFY_RAISES_ASSERT(v.head(0).mean()); + VERIFY_RAISES_ASSERT(v.head(0).minCoeff()); + VERIFY_RAISES_ASSERT(v.head(0).maxCoeff()); } void test_redux()