From e7c48fac9b0fed8bf262e44feccb63671362c845 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Fri, 23 Jan 2009 13:59:32 +0000 Subject: [PATCH] sparse module: makes -= and += operator working Question 1: why are *=scalar and /=scalar working right away ? Same weirdness in DynamicSparseMatrix where operators += and -= work wihout having to redefine them ??? --- Eigen/src/Sparse/DynamicSparseMatrix.h | 3 +++ Eigen/src/Sparse/SparseCwiseBinaryOp.h | 6 +++--- Eigen/src/Sparse/SparseMatrix.h | 6 ++++++ Eigen/src/Sparse/SparseVector.h | 30 ++++++++++++++++++++++++++ test/sparse_basic.cpp | 5 ++++- test/sparse_vector.cpp | 3 +++ 6 files changed, 49 insertions(+), 4 deletions(-) diff --git a/Eigen/src/Sparse/DynamicSparseMatrix.h b/Eigen/src/Sparse/DynamicSparseMatrix.h index 1cd302f3f..d59b81458 100644 --- a/Eigen/src/Sparse/DynamicSparseMatrix.h +++ b/Eigen/src/Sparse/DynamicSparseMatrix.h @@ -63,6 +63,9 @@ class DynamicSparseMatrix { public: EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(DynamicSparseMatrix) + // FIXME: why are these operator already alvailable ??? + // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, +=) + // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, -=) typedef MappedSparseMatrix Map; protected: diff --git a/Eigen/src/Sparse/SparseCwiseBinaryOp.h b/Eigen/src/Sparse/SparseCwiseBinaryOp.h index 9007c6bf7..87fd429be 100644 --- a/Eigen/src/Sparse/SparseCwiseBinaryOp.h +++ b/Eigen/src/Sparse/SparseCwiseBinaryOp.h @@ -344,7 +344,7 @@ template EIGEN_STRONG_INLINE Derived & SparseMatrixBase::operator-=(const SparseMatrixBase &other) { - return *this = *this - other; + return *this = derived() - other.derived(); } template @@ -360,7 +360,7 @@ template EIGEN_STRONG_INLINE Derived & SparseMatrixBase::operator+=(const SparseMatrixBase& other) { - return *this = *this + other; + return *this = derived() + other.derived(); } template @@ -399,7 +399,7 @@ template template inline ExpressionType& SparseCwise::operator*=(const SparseMatrixBase &other) { - return m_matrix.const_cast_derived() = *this * other; + return m_matrix.const_cast_derived() = _expression() * other.derived(); } // template diff --git a/Eigen/src/Sparse/SparseMatrix.h b/Eigen/src/Sparse/SparseMatrix.h index 5e8ca8489..b2665cfe6 100644 --- a/Eigen/src/Sparse/SparseMatrix.h +++ b/Eigen/src/Sparse/SparseMatrix.h @@ -57,6 +57,12 @@ class SparseMatrix { public: EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseMatrix) + EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, +=) + EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, -=) + // FIXME: why are these operator already alvailable ??? + // EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(SparseMatrix, *=) + // EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(SparseMatrix, /=) + typedef MappedSparseMatrix Map; protected: diff --git a/Eigen/src/Sparse/SparseVector.h b/Eigen/src/Sparse/SparseVector.h index 9af565351..457984cad 100644 --- a/Eigen/src/Sparse/SparseVector.h +++ b/Eigen/src/Sparse/SparseVector.h @@ -57,6 +57,8 @@ class SparseVector { public: EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseVector) + EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=) + EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=) protected: public: @@ -117,14 +119,32 @@ class SparseVector /** */ inline void reserve(int reserveSize) { m_data.reserve(reserveSize); } + + inline void startFill(int reserve) + { + setZero(); + m_data.reserve(reserve); + } /** */ + inline Scalar& fill(int r, int c) + { + ei_assert(r==0 || c==0); + return fill(IsColVector ? r : c); + } + inline Scalar& fill(int i) { m_data.append(0, i); return m_data.value(m_data.size()-1); } + + inline Scalar& fillrand(int r, int c) + { + ei_assert(r==0 || c==0); + return fillrand(IsColVector ? r : c); + } /** Like fill() but with random coordinates. */ @@ -145,10 +165,18 @@ class SparseVector return m_data.value(id+1); } + inline void endFill() {} + void prune(Scalar reference, RealScalar epsilon = precision()) { m_data.prune(reference,epsilon); } + + void resize(int rows, int cols) + { + ei_assert(rows==1 || cols==1); + resize(IsColVector ? rows : cols); + } void resize(int newSize) { @@ -161,6 +189,8 @@ class SparseVector inline SparseVector() : m_size(0) { resize(0); } inline SparseVector(int size) : m_size(0) { resize(size); } + + inline SparseVector(int rows, int cols) : m_size(0) { resize(rows,cols); } template inline SparseVector(const MatrixBase& other) diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp index 93065bbde..439458128 100644 --- a/test/sparse_basic.cpp +++ b/test/sparse_basic.cpp @@ -235,7 +235,10 @@ template void sparse_basic(const SparseMatrixType& re VERIFY_IS_APPROX(m1*=s1, refM1*=s1); VERIFY_IS_APPROX(m1/=s1, refM1/=s1); - + + VERIFY_IS_APPROX(m1+=m2, refM1+=refM2); + VERIFY_IS_APPROX(m1-=m2, refM1-=refM2); + refM4.setRandom(); // sparse cwise* dense VERIFY_IS_APPROX(m3.cwise()*refM4, refM3.cwise()*refM4); diff --git a/test/sparse_vector.cpp b/test/sparse_vector.cpp index 64f52cbe9..8207e522a 100644 --- a/test/sparse_vector.cpp +++ b/test/sparse_vector.cpp @@ -79,6 +79,9 @@ template void sparse_vector(int rows, int cols) VERIFY_IS_APPROX(v1*=s1, refV1*=s1); VERIFY_IS_APPROX(v1/=s1, refV1/=s1); + + VERIFY_IS_APPROX(v1+=v2, refV1+=refV2); + VERIFY_IS_APPROX(v1-=v2, refV1-=refV2); VERIFY_IS_APPROX(v1.dot(v2), refV1.dot(refV2));