From d1b54ecfa3cd9c57569ab245566a4f66cc4f363a Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 30 Nov 2011 19:24:43 +0100 Subject: [PATCH] add more support for uncompressed mode --- Eigen/src/SparseCore/SparseBlock.h | 14 +++++-- Eigen/src/SparseCore/SparseMatrix.h | 65 ++++++++++++++++++++++------- test/sparse.h | 10 +++-- 3 files changed, 66 insertions(+), 23 deletions(-) diff --git a/Eigen/src/SparseCore/SparseBlock.h b/Eigen/src/SparseCore/SparseBlock.h index 3119686c4..777fd1b76 100644 --- a/Eigen/src/SparseCore/SparseBlock.h +++ b/Eigen/src/SparseCore/SparseBlock.h @@ -237,15 +237,23 @@ class SparseInnerVectorSet, Size> Index nonZeros() const { - return std::size_t(m_matrix._outerIndexPtr()[m_outerStart+m_outerSize.value()]) - - std::size_t(m_matrix._outerIndexPtr()[m_outerStart]); + if(m_matrix.compressed()) + return std::size_t(m_matrix._outerIndexPtr()[m_outerStart+m_outerSize.value()]) + - std::size_t(m_matrix._outerIndexPtr()[m_outerStart]); + else if(m_outerSize.value()==0) + return 0; + else + return Map >(m_matrix._innerNonZeroPtr(), m_outerSize.value()).sum(); } const Scalar& lastCoeff() const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet); eigen_assert(nonZeros()>0); - return m_matrix._valuePtr()[m_matrix._outerIndexPtr()[m_outerStart+1]-1]; + if(m_matrix.compressed()) + return m_matrix._valuePtr()[m_matrix._outerIndexPtr()[m_outerStart+1]-1]; + else + return m_matrix._valuePtr()[m_matrix._outerIndexPtr()[m_outerStart]+m_matrix._innerNonZeroPtr()[m_outerStart]-1]; } // template diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h index 21a671ca5..87a7066b3 100644 --- a/Eigen/src/SparseCore/SparseMatrix.h +++ b/Eigen/src/SparseCore/SparseMatrix.h @@ -138,6 +138,15 @@ class SparseMatrix * \returns a non-const pointer to the array of the starting positions of the inner vectors */ inline Index* _outerIndexPtr() { return m_outerIndex; } + /** \internal + * \returns a const pointer to the array of the number of non zeros of the inner vectors + * \warning it returns 0 in compressed mode */ + inline const Index* _innerNonZeroPtr() const { return m_innerNonZeros; } + /** \internal + * \returns a non-const pointer to the array of the number of non zeros of the inner vectors + * \warning it returns 0 in compressed mode */ + inline Index* _innerNonZeroPtr() { return m_innerNonZeros; } + inline Storage& data() { return m_data; } inline const Storage& data() const { return m_data; } @@ -357,7 +366,10 @@ class SparseMatrix return insertUncompressed(row,col); } - + EIGEN_DONT_INLINE Scalar& insertByOuterInner(Index j, Index i) + { + return insert(IsRowMajor ? j : i, IsRowMajor ? i : j); + } /** Must be called after inserting a set of non zero entries. @@ -527,12 +539,7 @@ class SparseMatrix } else { - resize(other.rows(), other.cols()); - if(m_innerNonZeros) - { - delete[] m_innerNonZeros; - m_innerNonZeros = 0; - } + initAssignment(other); if(other.compressed()) { memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(Index)); @@ -549,20 +556,30 @@ class SparseMatrix #ifndef EIGEN_PARSED_BY_DOXYGEN template inline SparseMatrix& operator=(const SparseSparseProduct& product) - { return Base::operator=(product); } + { + initAssignment(product); + return Base::operator=(product); + } template inline SparseMatrix& operator=(const ReturnByValue& other) - { return Base::operator=(other.derived()); } + { + initAssignment(other.derived()); + return Base::operator=(other.derived()); + } template inline SparseMatrix& operator=(const EigenBase& other) - { return Base::operator=(other.derived()); } + { + initAssignment(other.derived()); + return Base::operator=(other.derived()); + } #endif template EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase& other) { + initAssignment(other.derived()); const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); if (needToTranspose) { @@ -574,7 +591,6 @@ class SparseMatrix typedef typename internal::remove_all::type _OtherCopy; OtherCopy otherCopy(other.derived()); - resize(other.rows(), other.cols()); Eigen::Map > (m_outerIndex,outerSize()).setZero(); // pass 1 // FIXME the above copy could be merged with that pass @@ -610,7 +626,7 @@ class SparseMatrix else { // there is no special optimization - return SparseMatrixBase::operator=(other.derived()); + return Base::operator=(other.derived()); } } @@ -640,6 +656,7 @@ class SparseMatrix inline ~SparseMatrix() { delete[] m_outerIndex; + delete[] m_innerNonZeros; } /** Overloaded for performance */ @@ -650,6 +667,18 @@ class SparseMatrix # endif protected: + + template + void initAssignment(const Other& other) + { + resize(other.rows(), other.cols()); + if(m_innerNonZeros) + { + delete[] m_innerNonZeros; + m_innerNonZeros = 0; + } + } + /** \internal * \sa insert(Index,Index) */ EIGEN_DONT_INLINE Scalar& insertCompressed(Index row, Index col) @@ -820,9 +849,13 @@ class SparseMatrix::InnerIterator { public: InnerIterator(const SparseMatrix& mat, Index outer) - : m_values(mat._valuePtr()), m_indices(mat._innerIndexPtr()), m_outer(outer), m_id(mat.m_outerIndex[outer]), - m_end(mat.m_outerIndex[outer+1]) - {} + : m_values(mat._valuePtr()), m_indices(mat._innerIndexPtr()), m_outer(outer), m_id(mat.m_outerIndex[outer]) + { + if(mat.compressed()) + m_end = mat.m_outerIndex[outer+1]; + else + m_end = m_id + mat.m_innerNonZeros[outer]; + } inline InnerIterator& operator++() { m_id++; return *this; } @@ -841,7 +874,7 @@ class SparseMatrix::InnerIterator const Index* m_indices; const Index m_outer; Index m_id; - const Index m_end; + Index m_end; }; #endif // EIGEN_SPARSEMATRIX_H diff --git a/test/sparse.h b/test/sparse.h index 4ca6b5aed..1ce1d2ac4 100644 --- a/test/sparse.h +++ b/test/sparse.h @@ -78,11 +78,12 @@ initSparse(double density, { enum { IsRowMajor = SparseMatrix::IsRowMajor }; sparseMat.setZero(); - sparseMat.reserve(int(refMat.rows()*refMat.cols()*density)); + //sparseMat.reserve(int(refMat.rows()*refMat.cols()*density)); + sparseMat.reserve(VectorXi::Constant(IsRowMajor ? refMat.rows() : refMat.cols(), (1.5*density)*(IsRowMajor?refMat.cols():refMat.rows()))); for(int j=0; jpush_back(Vector2i(ai,aj)); } @@ -115,7 +117,7 @@ initSparse(double density, refMat(ai,aj) = v; } } - sparseMat.finalize(); + //sparseMat.finalize(); } template void