fix sparse vector assignment from a sparse matrix

(transplanted from 98ce4455ddad01ef028b65f96e232d4b750647f0
)
This commit is contained in:
Gael Guennebaud 2013-03-06 11:58:22 +01:00
parent 2674a31421
commit e304a92f41
4 changed files with 52 additions and 3 deletions

View File

@ -230,7 +230,8 @@ class SparseVector
template<typename OtherDerived> template<typename OtherDerived>
inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other) inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
{ {
if (int(RowsAtCompileTime)!=int(OtherDerived::RowsAtCompileTime)) if ( (bool(OtherDerived::IsVectorAtCompileTime) && int(RowsAtCompileTime)!=int(OtherDerived::RowsAtCompileTime))
|| ((!bool(OtherDerived::IsVectorAtCompileTime)) && ( bool(IsColVector) ? other.cols()>1 : other.rows()>1 )))
return assign(other.transpose()); return assign(other.transpose());
else else
return assign(other); return assign(other);

View File

@ -178,5 +178,30 @@ initSparse(double density,
} }
} }
template<typename Scalar> void
initSparse(double density,
Matrix<Scalar,1,Dynamic>& refVec,
SparseVector<Scalar,RowMajor>& sparseVec,
std::vector<int>* zeroCoords = 0,
std::vector<int>* nonzeroCoords = 0)
{
sparseVec.reserve(int(refVec.size()*density));
sparseVec.setZero();
for(int i=0; i<refVec.size(); i++)
{
Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
if (v!=Scalar(0))
{
sparseVec.insertBack(i) = v;
if (nonzeroCoords)
nonzeroCoords->push_back(i);
}
else if (zeroCoords)
zeroCoords->push_back(i);
refVec[i] = v;
}
}
#include <unsupported/Eigen/SparseExtra> #include <unsupported/Eigen/SparseExtra>
#endif // EIGEN_TESTSPARSE_H #endif // EIGEN_TESTSPARSE_H

View File

@ -46,8 +46,10 @@ template<typename SparseMatrixType> void sparse_product()
double density = (std::max)(8./(rows*cols), 0.01); double density = (std::max)(8./(rows*cols), 0.01);
typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix; typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
typedef Matrix<Scalar,Dynamic,1> DenseVector; typedef Matrix<Scalar,Dynamic,1> DenseVector;
typedef Matrix<Scalar,1,Dynamic> RowDenseVector;
Scalar s1 = internal::random<Scalar>(); typedef SparseVector<Scalar,0,Index> ColSpVector;
typedef SparseVector<Scalar,RowMajor,Index> RowSpVector;Scalar s1 = internal::random<Scalar>();
Scalar s2 = internal::random<Scalar>(); Scalar s2 = internal::random<Scalar>();
// test matrix-matrix product // test matrix-matrix product
@ -117,6 +119,21 @@ template<typename SparseMatrixType> void sparse_product()
test_outer<SparseMatrixType,DenseMatrix>::run(m2,m4,refMat2,refMat4); test_outer<SparseMatrixType,DenseMatrix>::run(m2,m4,refMat2,refMat4);
VERIFY_IS_APPROX(m6=m6*m6, refMat6=refMat6*refMat6); VERIFY_IS_APPROX(m6=m6*m6, refMat6=refMat6*refMat6);
// sparse matrix * sparse vector
ColSpVector cv0(cols), cv1;
DenseVector dcv0(cols), dcv1;
initSparse(2*density,dcv0, cv0);
RowSpVector rv0(depth), rv1;
RowDenseVector drv0(depth), drv1(rv1);
initSparse(2*density,drv0, rv0);
VERIFY_IS_APPROX(cv1=rv0*m3, dcv1=drv0*refMat3);
VERIFY_IS_APPROX(rv1=rv0*m3, drv1=drv0*refMat3);
VERIFY_IS_APPROX(cv1=m3*cv0, dcv1=refMat3*dcv0);
VERIFY_IS_APPROX(cv1=m3t.adjoint()*cv0, dcv1=refMat3t.adjoint()*dcv0);
VERIFY_IS_APPROX(rv1=m3*cv0, drv1=refMat3*dcv0);
} }
// test matrix - diagonal product // test matrix - diagonal product

View File

@ -82,6 +82,12 @@ template<typename Scalar> void sparse_vector(int rows, int cols)
VERIFY_IS_APPROX((v1 = -v1), (refV1 = -refV1)); VERIFY_IS_APPROX((v1 = -v1), (refV1 = -refV1));
VERIFY_IS_APPROX((v1 = v1.transpose()), (refV1 = refV1.transpose().eval())); VERIFY_IS_APPROX((v1 = v1.transpose()), (refV1 = refV1.transpose().eval()));
VERIFY_IS_APPROX((v1 += -v1), (refV1 += -refV1)); VERIFY_IS_APPROX((v1 += -v1), (refV1 += -refV1));
// sparse matrix to sparse vector
SparseMatrixType mv1;
VERIFY_IS_APPROX((mv1=v1),v1);
VERIFY_IS_APPROX(mv1,(v1=mv1));
VERIFY_IS_APPROX(mv1,(v1=mv1.transpose()));
} }