mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-01-18 14:34:17 +08:00
fix sum()/prod() on empty matrix making sure this does not affect fixed sized object, extend related unit tests including partial reduction
This commit is contained in:
parent
6a370f50c7
commit
044424b0e2
@ -183,7 +183,7 @@ struct ei_redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>
|
||||
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<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
|
||||
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<Scalar>::size;
|
||||
const Index alignedStart = ei_first_aligned(mat);
|
||||
enum {
|
||||
@ -253,6 +254,7 @@ struct ei_redux_impl<Func, Derived, SliceVectorizedTraversal, NoUnrolling>
|
||||
|
||||
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_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling
|
||||
};
|
||||
EIGEN_STRONG_INLINE static Scalar run(const Derived& mat, const Func& func)
|
||||
{
|
||||
ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
|
||||
Scalar res = func.predux(ei_redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
|
||||
if (VectorizedSize != Size)
|
||||
res = func(res,ei_redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func));
|
||||
@ -345,6 +348,8 @@ template<typename Derived>
|
||||
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar
|
||||
DenseBase<Derived>::sum() const
|
||||
{
|
||||
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
|
||||
return Scalar(0);
|
||||
return this->redux(Eigen::ei_scalar_sum_op<Scalar>());
|
||||
}
|
||||
|
||||
@ -370,6 +375,8 @@ template<typename Derived>
|
||||
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar
|
||||
DenseBase<Derived>::prod() const
|
||||
{
|
||||
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
|
||||
return Scalar(1);
|
||||
return this->redux(Eigen::ei_scalar_product_op<Scalar>());
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,10 @@ template<typename MatrixType> 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<typename MatrixType> void comparisons(const MatrixType& m)
|
||||
|
@ -64,6 +64,10 @@ template<typename MatrixType> 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<typename VectorType> void vectorRedux(const VectorType& w)
|
||||
@ -124,6 +128,13 @@ template<typename VectorType> 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()
|
||||
|
Loading…
Reference in New Issue
Block a user