bug #942: fix dangling references in evaluator of diagonal * sparse products.

This commit is contained in:
Gael Guennebaud 2015-04-18 22:43:27 +02:00
parent 3b429b71e6
commit 5a3c48e3c6
2 changed files with 29 additions and 1 deletions

View File

@ -107,7 +107,9 @@ struct sparse_diagonal_product_evaluator<SparseXprType, DiagCoeffType, SDP_AsCwi
{ {
public: public:
InnerIterator(const sparse_diagonal_product_evaluator &xprEval, Index outer) InnerIterator(const sparse_diagonal_product_evaluator &xprEval, Index outer)
: m_cwiseEval(xprEval.m_sparseXprNested.innerVector(outer).cwiseProduct(xprEval.m_diagCoeffNested)), : m_innerVectorXpr(xprEval.m_sparseXprNested.innerVector(outer)),
m_cwiseXpr(m_innerVectorXpr.cwiseProduct(xprEval.m_diagCoeffNested)),
m_cwiseEval(m_cwiseXpr),
m_cwiseIter(m_cwiseEval, 0), m_cwiseIter(m_cwiseEval, 0),
m_outer(outer) m_outer(outer)
{} {}
@ -123,6 +125,8 @@ struct sparse_diagonal_product_evaluator<SparseXprType, DiagCoeffType, SDP_AsCwi
inline operator bool() const { return m_cwiseIter; } inline operator bool() const { return m_cwiseIter; }
protected: protected:
const typename SparseXprType::ConstInnerVectorReturnType m_innerVectorXpr;
const CwiseProductType m_cwiseXpr;
CwiseProductEval m_cwiseEval; CwiseProductEval m_cwiseEval;
CwiseProductIterator m_cwiseIter; CwiseProductIterator m_cwiseIter;
Index m_outer; Index m_outer;

View File

@ -278,11 +278,35 @@ template<typename SparseMatrixType, typename DenseMatrixType> void sparse_produc
VERIFY_IS_APPROX( m4(0,0), 0.0 ); VERIFY_IS_APPROX( m4(0,0), 0.0 );
} }
template<typename Scalar>
void bug_942()
{
typedef Matrix<Scalar, Dynamic, 1> Vector;
typedef SparseMatrix<Scalar, ColMajor> ColSpMat;
typedef SparseMatrix<Scalar, RowMajor> RowSpMat;
ColSpMat cmA(1,1);
cmA.insert(0,0) = 1;
RowSpMat rmA(1,1);
rmA.insert(0,0) = 1;
Vector d(1);
d[0] = 2;
double res = 2;
VERIFY_IS_APPROX( ( cmA*d.asDiagonal() ).eval().coeff(0,0), res );
VERIFY_IS_APPROX( ( d.asDiagonal()*rmA ).eval().coeff(0,0), res );
VERIFY_IS_APPROX( ( rmA*d.asDiagonal() ).eval().coeff(0,0), res );
VERIFY_IS_APPROX( ( d.asDiagonal()*cmA ).eval().coeff(0,0), res );
}
void test_sparse_product() void test_sparse_product()
{ {
for(int i = 0; i < g_repeat; i++) { for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( (sparse_product<SparseMatrix<double,ColMajor> >()) ); CALL_SUBTEST_1( (sparse_product<SparseMatrix<double,ColMajor> >()) );
CALL_SUBTEST_1( (sparse_product<SparseMatrix<double,RowMajor> >()) ); CALL_SUBTEST_1( (sparse_product<SparseMatrix<double,RowMajor> >()) );
CALL_SUBTEST_1( (bug_942<double>()) );
CALL_SUBTEST_2( (sparse_product<SparseMatrix<std::complex<double>, ColMajor > >()) ); CALL_SUBTEST_2( (sparse_product<SparseMatrix<std::complex<double>, ColMajor > >()) );
CALL_SUBTEST_2( (sparse_product<SparseMatrix<std::complex<double>, RowMajor > >()) ); CALL_SUBTEST_2( (sparse_product<SparseMatrix<std::complex<double>, RowMajor > >()) );
CALL_SUBTEST_3( (sparse_product<SparseMatrix<float,ColMajor,long int> >()) ); CALL_SUBTEST_3( (sparse_product<SparseMatrix<float,ColMajor,long int> >()) );