From e3929485486ad4450dd93d24fa2af9dd72aa368e Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 10 Jun 2013 00:06:40 +0200 Subject: [PATCH] Fix bug #607: handle implicit transposition from sparse vector to dense vector --- Eigen/src/Core/Assign.h | 10 ++++++---- Eigen/src/SparseCore/SparseMatrixBase.h | 26 ++++++++++++------------- test/sparse_vector.cpp | 5 +++++ 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h index 288f8ec53..6400f5ae7 100644 --- a/Eigen/src/Core/Assign.h +++ b/Eigen/src/Core/Assign.h @@ -520,18 +520,22 @@ struct assign_selector; template struct assign_selector { static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); } + static EIGEN_STRONG_INLINE Derived& evalTo(Derived& dst, const OtherDerived& other) { other.evalTo(dst); return dst; } }; template struct assign_selector { static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); } + static EIGEN_STRONG_INLINE Derived& evalTo(Derived& dst, const OtherDerived& other) { other.evalTo(dst); return dst; } }; template struct assign_selector { static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); } + static EIGEN_STRONG_INLINE Derived& evalTo(Derived& dst, const OtherDerived& other) { Transpose dstTrans(dst); other.evalTo(dstTrans); return dst; } }; template struct assign_selector { static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); } + static EIGEN_STRONG_INLINE Derived& evalTo(Derived& dst, const OtherDerived& other) { Transpose dstTrans(dst); other.evalTo(dstTrans); return dst; } }; } // end namespace internal @@ -566,16 +570,14 @@ template template EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const EigenBase& other) { - other.derived().evalTo(derived()); - return derived(); + return internal::assign_selector::evalTo(derived(), other.derived()); } template template EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const ReturnByValue& other) { - other.evalTo(derived()); - return derived(); + return internal::assign_selector::evalTo(derived(), other.derived()); } } // end namespace Eigen diff --git a/Eigen/src/SparseCore/SparseMatrixBase.h b/Eigen/src/SparseCore/SparseMatrixBase.h index 590339663..6c73b7172 100644 --- a/Eigen/src/SparseCore/SparseMatrixBase.h +++ b/Eigen/src/SparseCore/SparseMatrixBase.h @@ -403,20 +403,20 @@ template class SparseMatrixBase : public EigenBase Block innerVectors(Index outerStart, Index outerSize); const Block innerVectors(Index outerStart, Index outerSize) const; - /** \internal use operator= */ - template - void evalTo(MatrixBase& dst) const - { - dst.setZero(); - for (Index j=0; j + void evalTo(MatrixBase& dst) const + { + dst.setZero(); + for (Index j=0; j toDense() const - { - return derived(); - } + Matrix toDense() const + { + return derived(); + } template bool isApprox(const SparseMatrixBase& other, diff --git a/test/sparse_vector.cpp b/test/sparse_vector.cpp index d16d42f59..ec5877b6a 100644 --- a/test/sparse_vector.cpp +++ b/test/sparse_vector.cpp @@ -90,6 +90,11 @@ template void sparse_vector(int rows, int cols) VERIFY_IS_APPROX((mv1=v1),v1); VERIFY_IS_APPROX(mv1,(v1=mv1)); VERIFY_IS_APPROX(mv1,(v1=mv1.transpose())); + + // check copy to dense vector with transpose + refV3.resize(0); + VERIFY_IS_APPROX(refV3 = v1.transpose(),v1.toDense()); + VERIFY_IS_APPROX(DenseVector(v1),v1.toDense()); }