Bugzilla – Attachment 362 Details for
Bug 557
InnerIterator cannot be assigned, copy- or default-constructed
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Forgot Password
Login:
[x]
This bugzilla service is closed. All entries have been migrated to
https://gitlab.com/libeigen/eigen
[patch]
A possible patch
InnerIteratorCopy (text/plain), 37.71 KB, created by
Gael Guennebaud
on 2013-06-28 23:25:20 UTC
(
hide
)
Description:
A possible patch
Filename:
MIME Type:
Creator:
Gael Guennebaud
Created:
2013-06-28 23:25:20 UTC
Size:
37.71 KB
patch
obsolete
># HG changeset patch ># Parent 743776e6544255dcde77e8c461ce98df6b922d0f >diff --git a/Eigen/src/Core/CoreIterators.h b/Eigen/src/Core/CoreIterators.h >--- a/Eigen/src/Core/CoreIterators.h >+++ b/Eigen/src/Core/CoreIterators.h >@@ -26,36 +26,39 @@ namespace Eigen { > template<typename Derived> class DenseBase<Derived>::InnerIterator > { > protected: > typedef typename Derived::Scalar Scalar; > typedef typename Derived::Index Index; > > enum { IsRowMajor = (Derived::Flags&RowMajorBit)==RowMajorBit }; > public: >+ InnerIterator() >+ : m_expression(0),m_inner(0),m_outer(0),m_end(0) >+ {} > EIGEN_STRONG_INLINE InnerIterator(const Derived& expr, Index outer) >- : m_expression(expr), m_inner(0), m_outer(outer), m_end(expr.innerSize()) >+ : m_expression(&expr), m_inner(0), m_outer(outer), m_end(expr.innerSize()) > {} > > EIGEN_STRONG_INLINE Scalar value() const > { >- return (IsRowMajor) ? m_expression.coeff(m_outer, m_inner) >- : m_expression.coeff(m_inner, m_outer); >+ return (IsRowMajor) ? m_expression->coeff(m_outer, m_inner) >+ : m_expression->coeff(m_inner, m_outer); > } > > EIGEN_STRONG_INLINE InnerIterator& operator++() { m_inner++; return *this; } > > EIGEN_STRONG_INLINE Index index() const { return m_inner; } > inline Index row() const { return IsRowMajor ? m_outer : index(); } > inline Index col() const { return IsRowMajor ? index() : m_outer; } > > EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; } > > protected: >- const Derived& m_expression; >+ const Derived* m_expression; > Index m_inner; >- const Index m_outer; >- const Index m_end; >+ Index m_outer; >+ Index m_end; > }; > > } // end namespace Eigen > > #endif // EIGEN_COREITERATORS_H >diff --git a/Eigen/src/SparseCore/MappedSparseMatrix.h b/Eigen/src/SparseCore/MappedSparseMatrix.h >--- a/Eigen/src/SparseCore/MappedSparseMatrix.h >+++ b/Eigen/src/SparseCore/MappedSparseMatrix.h >@@ -111,69 +111,93 @@ class MappedSparseMatrix > /** Empty destructor */ > inline ~MappedSparseMatrix() {} > }; > > template<typename Scalar, int _Flags, typename _Index> > class MappedSparseMatrix<Scalar,_Flags,_Index>::InnerIterator > { > public: >+ InnerIterator() >+ : m_matrix(0), >+ m_outer(-1), >+ m_id(0), >+ m_start(0), >+ m_end(0) >+ { } >+ > InnerIterator(const MappedSparseMatrix& mat, Index outer) >- : m_matrix(mat), >+ : m_matrix(&mat), > m_outer(outer), > m_id(mat.outerIndexPtr()[outer]), > m_start(m_id), > m_end(mat.outerIndexPtr()[outer+1]) > {} > > inline InnerIterator& operator++() { m_id++; return *this; } > >- inline Scalar value() const { return m_matrix.valuePtr()[m_id]; } >- inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.valuePtr()[m_id]); } >+ inline Scalar value() const { return m_matrix->valuePtr()[m_id]; } >+ inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix->valuePtr()[m_id]); } >+ >+ // Unlike the pos() function in SparseMatrix::InnerIterator, >+ // this is rather an offset than a position >+ inline Index pos() const {return (m_id - m_start); } >+ inline InnerIterator& operator+=(Index offset) {m_id += offset; return *this; } > >- inline Index index() const { return m_matrix.innerIndexPtr()[m_id]; } >+ inline Index index() const { return m_matrix->innerIndexPtr()[m_id]; } > inline Index row() const { return IsRowMajor ? m_outer : index(); } > inline Index col() const { return IsRowMajor ? index() : m_outer; } > > inline operator bool() const { return (m_id < m_end) && (m_id>=m_start); } > > protected: >- const MappedSparseMatrix& m_matrix; >- const Index m_outer; >+ const MappedSparseMatrix *m_matrix; >+ Index m_outer; > Index m_id; >- const Index m_start; >- const Index m_end; >+ Index m_start; >+ Index m_end; > }; > > template<typename Scalar, int _Flags, typename _Index> > class MappedSparseMatrix<Scalar,_Flags,_Index>::ReverseInnerIterator > { > public: >+ ReverseInnerIterator() >+ : m_matrix(0), >+ m_outer(-1), >+ m_id(0), >+ m_start(0), >+ m_end(0) >+ { } >+ > ReverseInnerIterator(const MappedSparseMatrix& mat, Index outer) >- : m_matrix(mat), >+ : m_matrix(&mat), > m_outer(outer), > m_id(mat.outerIndexPtr()[outer+1]), > m_start(mat.outerIndexPtr()[outer]), > m_end(m_id) > {} > > inline ReverseInnerIterator& operator--() { m_id--; return *this; } > >- inline Scalar value() const { return m_matrix.valuePtr()[m_id-1]; } >- inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.valuePtr()[m_id-1]); } >+ inline Scalar value() const { return m_matrix->valuePtr()[m_id-1]; } >+ inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix->valuePtr()[m_id-1]); } > >- inline Index index() const { return m_matrix.innerIndexPtr()[m_id-1]; } >+ inline Index pos() const {return (m_end - m_id); } >+ inline ReverseInnerIterator& operator-=(Index offset) {m_id -= offset; return *this; } >+ >+ inline Index index() const { return m_matrix->innerIndexPtr()[m_id-1]; } > inline Index row() const { return IsRowMajor ? m_outer : index(); } > inline Index col() const { return IsRowMajor ? index() : m_outer; } > > inline operator bool() const { return (m_id <= m_end) && (m_id>m_start); } > > protected: >- const MappedSparseMatrix& m_matrix; >- const Index m_outer; >+ const MappedSparseMatrix* m_matrix; >+ Index m_outer; > Index m_id; >- const Index m_start; >- const Index m_end; >+ Index m_start; >+ Index m_end; > }; > > } // end namespace Eigen > > #endif // EIGEN_MAPPED_SPARSEMATRIX_H >diff --git a/Eigen/src/SparseCore/SparseBlock.h b/Eigen/src/SparseCore/SparseBlock.h >--- a/Eigen/src/SparseCore/SparseBlock.h >+++ b/Eigen/src/SparseCore/SparseBlock.h >@@ -23,27 +23,33 @@ public: > protected: > enum { OuterSize = IsRowMajor ? BlockRows : BlockCols }; > public: > EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType) > > class InnerIterator: public XprType::InnerIterator > { > public: >+ inline InnerIterator() >+ : XprType::InnerIterator(), m_outer(-1) >+ {} > inline InnerIterator(const BlockType& xpr, Index outer) > : XprType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) > {} > inline Index row() const { return IsRowMajor ? m_outer : this->index(); } > inline Index col() const { return IsRowMajor ? this->index() : m_outer; } > protected: > Index m_outer; > }; > class ReverseInnerIterator: public XprType::ReverseInnerIterator > { > public: >+ inline ReverseInnerIterator() >+ : XprType::ReverseInnerIterator(), m_outer(-1) >+ {} > inline ReverseInnerIterator(const BlockType& xpr, Index outer) > : XprType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) > {} > inline Index row() const { return IsRowMajor ? m_outer : this->index(); } > inline Index col() const { return IsRowMajor ? this->index() : m_outer; } > protected: > Index m_outer; > }; >@@ -83,27 +89,33 @@ public: > EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType) > protected: > enum { OuterSize = IsRowMajor ? BlockRows : BlockCols }; > public: > > class InnerIterator: public SparseMatrixType::InnerIterator > { > public: >+ inline InnerIterator() >+ : SparseMatrixType::InnerIterator(),m_outer(-1) >+ {} > inline InnerIterator(const BlockType& xpr, Index outer) > : SparseMatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) > {} > inline Index row() const { return IsRowMajor ? m_outer : this->index(); } > inline Index col() const { return IsRowMajor ? this->index() : m_outer; } > protected: > Index m_outer; > }; > class ReverseInnerIterator: public SparseMatrixType::ReverseInnerIterator > { > public: >+ inline ReverseInnerIterator() >+ : SparseMatrixType::ReverseInnerIterator(),m_outer(-1) >+ {} > inline ReverseInnerIterator(const BlockType& xpr, Index outer) > : SparseMatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) > {} > inline Index row() const { return IsRowMajor ? m_outer : this->index(); } > inline Index col() const { return IsRowMajor ? this->index() : m_outer; } > protected: > Index m_outer; > }; >@@ -338,56 +350,61 @@ public: > m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); > } > > inline const _MatrixTypeNested& nestedExpression() const { return m_matrix; } > > class InnerIterator : public _MatrixTypeNested::InnerIterator > { > typedef typename _MatrixTypeNested::InnerIterator Base; >- const BlockType& m_block; >+ const BlockType *m_block; > Index m_end; > public: > >+ InnerIterator() >+ : Base(), m_block(0),m_end(0) >+ {} > EIGEN_STRONG_INLINE InnerIterator(const BlockType& block, Index outer) > : Base(block.derived().nestedExpression(), outer + (IsRowMajor ? block.m_startRow.value() : block.m_startCol.value())), >- m_block(block), >+ m_block(&block), > m_end(IsRowMajor ? block.m_startCol.value()+block.m_blockCols.value() : block.m_startRow.value()+block.m_blockRows.value()) > { >- while( (Base::operator bool()) && (Base::index() < (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value())) ) >+ while( (Base::operator bool()) && (Base::index() < (IsRowMajor ? m_block->m_startCol.value() : m_block->m_startRow.value())) ) > Base::operator++(); > } > >- inline Index index() const { return Base::index() - (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value()); } >- inline Index outer() const { return Base::outer() - (IsRowMajor ? m_block.m_startRow.value() : m_block.m_startCol.value()); } >- inline Index row() const { return Base::row() - m_block.m_startRow.value(); } >- inline Index col() const { return Base::col() - m_block.m_startCol.value(); } >+ inline Index index() const { return Base::index() - (IsRowMajor ? m_block->m_startCol.value() : m_block->m_startRow.value()); } >+ inline Index outer() const { return Base::outer() - (IsRowMajor ? m_block->m_startRow.value() : m_block->m_startCol.value()); } >+ inline Index row() const { return Base::row() - m_block->m_startRow.value(); } >+ inline Index col() const { return Base::col() - m_block->m_startCol.value(); } > > inline operator bool() const { return Base::operator bool() && Base::index() < m_end; } > }; > class ReverseInnerIterator : public _MatrixTypeNested::ReverseInnerIterator > { > typedef typename _MatrixTypeNested::ReverseInnerIterator Base; >- const BlockType& m_block; >+ const BlockType* m_block; > Index m_begin; > public: >- >+ ReverseInnerIterator() >+ : m_block(0),m_begin(0) >+ {} > EIGEN_STRONG_INLINE ReverseInnerIterator(const BlockType& block, Index outer) > : Base(block.derived().nestedExpression(), outer + (IsRowMajor ? block.m_startRow.value() : block.m_startCol.value())), >- m_block(block), >+ m_block(*block), > m_begin(IsRowMajor ? block.m_startCol.value() : block.m_startRow.value()) > { >- while( (Base::operator bool()) && (Base::index() >= (IsRowMajor ? m_block.m_startCol.value()+block.m_blockCols.value() : m_block.m_startRow.value()+block.m_blockRows.value())) ) >+ while( (Base::operator bool()) && (Base::index() >= (IsRowMajor ? m_block->m_startCol.value()+block.m_blockCols.value() : m_block->m_startRow.value()+block.m_blockRows.value())) ) > Base::operator--(); > } > >- inline Index index() const { return Base::index() - (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value()); } >- inline Index outer() const { return Base::outer() - (IsRowMajor ? m_block.m_startRow.value() : m_block.m_startCol.value()); } >- inline Index row() const { return Base::row() - m_block.m_startRow.value(); } >- inline Index col() const { return Base::col() - m_block.m_startCol.value(); } >+ inline Index index() const { return Base::index() - (IsRowMajor ? m_block->m_startCol.value() : m_block->m_startRow.value()); } >+ inline Index outer() const { return Base::outer() - (IsRowMajor ? m_block->m_startRow.value() : m_block->m_startCol.value()); } >+ inline Index row() const { return Base::row() - m_block->m_startRow.value(); } >+ inline Index col() const { return Base::col() - m_block->m_startCol.value(); } > > inline operator bool() const { return Base::operator bool() && Base::index() >= m_begin; } > }; > protected: > friend class InnerIterator; > friend class ReverseInnerIterator; > > typename XprType::Nested m_matrix; >diff --git a/Eigen/src/SparseCore/SparseCwiseBinaryOp.h b/Eigen/src/SparseCore/SparseCwiseBinaryOp.h >--- a/Eigen/src/SparseCore/SparseCwiseBinaryOp.h >+++ b/Eigen/src/SparseCore/SparseCwiseBinaryOp.h >@@ -67,17 +67,18 @@ class CwiseBinaryOpImpl<BinaryOp, Lhs, R > template<typename BinaryOp, typename Lhs, typename Rhs> > class CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator > : public internal::sparse_cwise_binary_op_inner_iterator_selector<BinaryOp,Lhs,Rhs,typename CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator> > { > public: > typedef typename Lhs::Index Index; > typedef internal::sparse_cwise_binary_op_inner_iterator_selector< > BinaryOp,Lhs,Rhs, InnerIterator> Base; >- >+ >+ InnerIterator() : Base() {} > EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, typename CwiseBinaryOpImpl::Index outer) > : Base(binOp.derived(),outer) > {} > }; > > /*************************************************************************** > * Implementation of inner-iterators > ***************************************************************************/ >diff --git a/Eigen/src/SparseCore/SparseCwiseUnaryOp.h b/Eigen/src/SparseCore/SparseCwiseUnaryOp.h >--- a/Eigen/src/SparseCore/SparseCwiseUnaryOp.h >+++ b/Eigen/src/SparseCore/SparseCwiseUnaryOp.h >@@ -32,40 +32,40 @@ class CwiseUnaryOpImpl<UnaryOp,MatrixTyp > > template<typename UnaryOp, typename MatrixType> > class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::InnerIterator > : public CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeIterator > { > typedef typename CwiseUnaryOpImpl::Scalar Scalar; > typedef typename CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeIterator Base; > public: >- >+ InnerIterator() : Base() { } > EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer) > : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) > {} > > EIGEN_STRONG_INLINE InnerIterator& operator++() > { Base::operator++(); return *this; } > > EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); } > > protected: >- const UnaryOp m_functor; >+ UnaryOp m_functor; > private: > typename CwiseUnaryOpImpl::Scalar& valueRef(); > }; > > template<typename UnaryOp, typename MatrixType> > class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::ReverseInnerIterator > : public CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeReverseIterator > { > typedef typename CwiseUnaryOpImpl::Scalar Scalar; > typedef typename CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeReverseIterator Base; > public: >- >+ ReverseInnerIterator() : Base() { } > EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer) > : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) > {} > > EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() > { Base::operator--(); return *this; } > > EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); } >@@ -96,51 +96,51 @@ class CwiseUnaryViewImpl<ViewOp,MatrixTy > > template<typename ViewOp, typename MatrixType> > class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::InnerIterator > : public CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeIterator > { > typedef typename CwiseUnaryViewImpl::Scalar Scalar; > typedef typename CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeIterator Base; > public: >- >+ InnerIterator() : Base() { } > EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer) > : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) > {} > > EIGEN_STRONG_INLINE InnerIterator& operator++() > { Base::operator++(); return *this; } > > EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); } > EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); } > > protected: >- const ViewOp m_functor; >+ ViewOp m_functor; > }; > > template<typename ViewOp, typename MatrixType> > class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::ReverseInnerIterator > : public CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeReverseIterator > { > typedef typename CwiseUnaryViewImpl::Scalar Scalar; > typedef typename CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeReverseIterator Base; > public: >- >+ ReverseInnerIterator() : Base() { } > EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer) > : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) > {} > > EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() > { Base::operator--(); return *this; } > > EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); } > EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); } > > protected: >- const ViewOp m_functor; >+ ViewOp m_functor; > }; > > template<typename Derived> > EIGEN_STRONG_INLINE Derived& > SparseMatrixBase<Derived>::operator*=(const Scalar& other) > { > for (Index j=0; j<outerSize(); ++j) > for (typename Derived::InnerIterator i(derived(),j); i; ++i) >diff --git a/Eigen/src/SparseCore/SparseDenseProduct.h b/Eigen/src/SparseCore/SparseDenseProduct.h >--- a/Eigen/src/SparseCore/SparseDenseProduct.h >+++ b/Eigen/src/SparseCore/SparseDenseProduct.h >@@ -107,16 +107,19 @@ class SparseDenseOuterProduct > RhsNested m_rhs; > }; > > template<typename Lhs, typename Rhs, bool Transpose> > class SparseDenseOuterProduct<Lhs,Rhs,Transpose>::InnerIterator : public _LhsNested::InnerIterator > { > typedef typename _LhsNested::InnerIterator Base; > public: >+ InnerIterator() >+ : Base(),m_outer(-1),m_factor(0) >+ {} > EIGEN_STRONG_INLINE InnerIterator(const SparseDenseOuterProduct& prod, Index outer) > : Base(prod.lhs(), 0), m_outer(outer), m_factor(prod.rhs().coeff(outer)) > { > } > > inline Index outer() const { return m_outer; } > inline Index row() const { return Transpose ? Base::row() : m_outer; } > inline Index col() const { return Transpose ? m_outer : Base::row(); } >diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h >--- a/Eigen/src/SparseCore/SparseMatrix.h >+++ b/Eigen/src/SparseCore/SparseMatrix.h >@@ -860,78 +860,92 @@ private: > RealScalar epsilon; > }; > }; > > template<typename Scalar, int _Options, typename _Index> > class SparseMatrix<Scalar,_Options,_Index>::InnerIterator > { > public: >+ InnerIterator() >+ : m_values(0),m_indices(0),m_outer(-1),m_id(0),m_end(0) >+ { } >+ > InnerIterator(const SparseMatrix& mat, Index outer) >- : m_values(mat.valuePtr()), m_indices(mat.innerIndexPtr()), m_outer(outer), m_id(mat.m_outerIndex[outer]) >+ : m_values(mat.valuePtr()+mat.m_outerIndex[outer]), m_indices(mat.innerIndexPtr()+mat.m_outerIndex[outer]), m_outer(outer), m_id(0) > { > if(mat.isCompressed()) >- m_end = mat.m_outerIndex[outer+1]; >+ m_end = mat.m_outerIndex[outer+1]-mat.m_outerIndex[outer]; > else >- m_end = m_id + mat.m_innerNonZeros[outer]; >+ m_end = mat.m_innerNonZeros[outer]; > } > > inline InnerIterator& operator++() { m_id++; return *this; } >+ >+ inline InnerIterator& operator+=(Index offset) { m_id+=offset; return *this; } >+ inline Index pos() const { return m_id; } > > inline const Scalar& value() const { return m_values[m_id]; } > inline Scalar& valueRef() { return const_cast<Scalar&>(m_values[m_id]); } > > inline Index index() const { return m_indices[m_id]; } > inline Index outer() const { return m_outer; } > inline Index row() const { return IsRowMajor ? m_outer : index(); } > inline Index col() const { return IsRowMajor ? index() : m_outer; } > > inline operator bool() const { return (m_id < m_end); } > > protected: > const Scalar* m_values; > const Index* m_indices; >- const Index m_outer; >+ Index m_outer; > Index m_id; > Index m_end; > }; > >+ > template<typename Scalar, int _Options, typename _Index> > class SparseMatrix<Scalar,_Options,_Index>::ReverseInnerIterator > { > public: >+ ReverseInnerIterator() >+ : m_values(0),m_indices(0),m_outer(-1),m_id(0) >+ { } > ReverseInnerIterator(const SparseMatrix& mat, Index outer) >- : m_values(mat.valuePtr()), m_indices(mat.innerIndexPtr()), m_outer(outer), m_start(mat.m_outerIndex[outer]) >+ : m_values(mat.valuePtr()+mat.m_outerIndex[outer]), m_indices(mat.innerIndexPtr()+mat.m_outerIndex[outer]), m_outer(outer) > { > if(mat.isCompressed()) >- m_id = mat.m_outerIndex[outer+1]; >+ m_id = mat.m_outerIndex[outer+1] - mat.m_outerIndex[outer]; > else >- m_id = m_start + mat.m_innerNonZeros[outer]; >+ m_id = mat.m_innerNonZeros[outer]; >+ m_end = m_id; > } > > inline ReverseInnerIterator& operator--() { --m_id; return *this; } >- >+ >+ inline Index pos() const {return m_end - m_id; } >+ inline ReverseInnerIterator& operator-=(Index offset) { m_id -= offset; return *this; } >+ > inline const Scalar& value() const { return m_values[m_id-1]; } > inline Scalar& valueRef() { return const_cast<Scalar&>(m_values[m_id-1]); } > > inline Index index() const { return m_indices[m_id-1]; } > inline Index outer() const { return m_outer; } > inline Index row() const { return IsRowMajor ? m_outer : index(); } > inline Index col() const { return IsRowMajor ? index() : m_outer; } > >- inline operator bool() const { return (m_id > m_start); } >+ inline operator bool() const { return (m_id > 0); } > > protected: > const Scalar* m_values; > const Index* m_indices; > const Index m_outer; > Index m_id; >- const Index m_start; >+ Index m_end; > }; >- > namespace internal { > > template<typename InputIterator, typename SparseMatrixType> > void set_from_triplets(const InputIterator& begin, const InputIterator& end, SparseMatrixType& mat, int Options = 0) > { > EIGEN_UNUSED_VARIABLE(Options); > enum { IsRowMajor = SparseMatrixType::IsRowMajor }; > typedef typename SparseMatrixType::Scalar Scalar; >diff --git a/Eigen/src/SparseCore/SparseTranspose.h b/Eigen/src/SparseCore/SparseTranspose.h >--- a/Eigen/src/SparseCore/SparseTranspose.h >+++ b/Eigen/src/SparseCore/SparseTranspose.h >@@ -30,30 +30,31 @@ template<typename MatrixType> class Tran > // a typedef typename TransposeImpl<MatrixType,Sparse>::Index Index; > // does not fix the issue. > // An alternative is to define the nested class in the parent class itself. > template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::InnerIterator > : public _MatrixTypeNested::InnerIterator > { > typedef typename _MatrixTypeNested::InnerIterator Base; > public: >- >+ InnerIterator() : Base() { } >+ > EIGEN_STRONG_INLINE InnerIterator(const TransposeImpl& trans, typename TransposeImpl<MatrixType,Sparse>::Index outer) > : Base(trans.derived().nestedExpression(), outer) > {} > inline typename TransposeImpl<MatrixType,Sparse>::Index row() const { return Base::col(); } > inline typename TransposeImpl<MatrixType,Sparse>::Index col() const { return Base::row(); } > }; > > template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::ReverseInnerIterator > : public _MatrixTypeNested::ReverseInnerIterator > { > typedef typename _MatrixTypeNested::ReverseInnerIterator Base; > public: >- >+ ReverseInnerIterator() : Base() { } > EIGEN_STRONG_INLINE ReverseInnerIterator(const TransposeImpl& xpr, typename TransposeImpl<MatrixType,Sparse>::Index outer) > : Base(xpr.derived().nestedExpression(), outer) > {} > inline typename TransposeImpl<MatrixType,Sparse>::Index row() const { return Base::col(); } > inline typename TransposeImpl<MatrixType,Sparse>::Index col() const { return Base::row(); } > }; > > } // end namespace Eigen >diff --git a/Eigen/src/SparseCore/SparseVector.h b/Eigen/src/SparseCore/SparseVector.h >--- a/Eigen/src/SparseCore/SparseVector.h >+++ b/Eigen/src/SparseCore/SparseVector.h >@@ -333,74 +333,80 @@ protected: > Storage m_data; > Index m_size; > }; > > template<typename Scalar, int _Options, typename _Index> > class SparseVector<Scalar,_Options,_Index>::InnerIterator > { > public: >+ InnerIterator() >+ : m_data(0),m_id(0),m_end(0) >+ {} > InnerIterator(const SparseVector& vec, Index outer=0) >- : m_data(vec.m_data), m_id(0), m_end(static_cast<Index>(m_data.size())) >+ : m_data(*vec.m_data), m_id(0), m_end(static_cast<Index>(m_data.size())) > { > EIGEN_UNUSED_VARIABLE(outer); > eigen_assert(outer==0); > } > > InnerIterator(const internal::CompressedStorage<Scalar,Index>& data) >- : m_data(data), m_id(0), m_end(static_cast<Index>(m_data.size())) >+ : m_data(*data), m_id(0), m_end(static_cast<Index>(m_data.size())) > {} > > inline InnerIterator& operator++() { m_id++; return *this; } > >- inline Scalar value() const { return m_data.value(m_id); } >- inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id)); } >+ inline Scalar value() const { return m_data->value(m_id); } >+ inline Scalar& valueRef() { return const_cast<Scalar&>(m_data->value(m_id)); } > >- inline Index index() const { return m_data.index(m_id); } >+ inline Index index() const { return m_data->index(m_id); } > inline Index row() const { return IsColVector ? index() : 0; } > inline Index col() const { return IsColVector ? 0 : index(); } > > inline operator bool() const { return (m_id < m_end); } > > protected: >- const internal::CompressedStorage<Scalar,Index>& m_data; >+ const internal::CompressedStorage<Scalar,Index>* m_data; > Index m_id; >- const Index m_end; >+ Index m_end; > }; > > template<typename Scalar, int _Options, typename _Index> > class SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator > { > public: >+ ReverseInnerIterator() >+ : m_data(0),m_id(0),m_start(0) >+ {} > ReverseInnerIterator(const SparseVector& vec, Index outer=0) >- : m_data(vec.m_data), m_id(static_cast<Index>(m_data.size())), m_start(0) >+ : m_data(*vec.m_data), m_id(static_cast<Index>(m_data.size())), m_start(0) > { > EIGEN_UNUSED_VARIABLE(outer); > eigen_assert(outer==0); > } > > ReverseInnerIterator(const internal::CompressedStorage<Scalar,Index>& data) >- : m_data(data), m_id(static_cast<Index>(m_data.size())), m_start(0) >+ : m_data(*data), m_id(static_cast<Index>(m_data.size())), m_start(0) > {} > > inline ReverseInnerIterator& operator--() { m_id--; return *this; } > >- inline Scalar value() const { return m_data.value(m_id-1); } >- inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id-1)); } >+ inline Scalar value() const { return m_data->value(m_id-1); } >+ inline Scalar& valueRef() { return const_cast<Scalar&>(m_data->value(m_id-1)); } > >- inline Index index() const { return m_data.index(m_id-1); } >+ inline Index index() const { return m_data->index(m_id-1); } > inline Index row() const { return IsColVector ? index() : 0; } > inline Index col() const { return IsColVector ? 0 : index(); } > > inline operator bool() const { return (m_id > m_start); } > > protected: >- const internal::CompressedStorage<Scalar,Index>& m_data; >+ const internal::CompressedStorage<Scalar,Index>* m_data; > Index m_id; >- const Index m_start; >+ Index m_start; > }; > > template<typename Scalar, int _Options, typename _Index> > template<typename OtherDerived> > EIGEN_DONT_INLINE SparseVector<Scalar,_Options,_Index>& SparseVector<Scalar,_Options,_Index>::assign(const SparseMatrixBase<OtherDerived>& _other) > { > const OtherDerived& other(_other.derived()); > const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); >diff --git a/Eigen/src/SparseCore/SparseView.h b/Eigen/src/SparseCore/SparseView.h >--- a/Eigen/src/SparseCore/SparseView.h >+++ b/Eigen/src/SparseCore/SparseView.h >@@ -53,38 +53,40 @@ protected: > typename NumTraits<Scalar>::Real m_epsilon; > }; > > template<typename MatrixType> > class SparseView<MatrixType>::InnerIterator : public _MatrixTypeNested::InnerIterator > { > public: > typedef typename _MatrixTypeNested::InnerIterator IterBase; >+ InnerIterator() : IterBase(),m_view(0) >+ {} > InnerIterator(const SparseView& view, Index outer) : >- IterBase(view.m_matrix, outer), m_view(view) >+ IterBase(view.m_matrix, outer), m_view(&view) > { > incrementToNonZero(); > } > > EIGEN_STRONG_INLINE InnerIterator& operator++() > { > IterBase::operator++(); > incrementToNonZero(); > return *this; > } > > using IterBase::value; > > protected: >- const SparseView& m_view; >+ const SparseView* m_view; > > private: > void incrementToNonZero() > { >- while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.m_reference, m_view.m_epsilon)) >+ while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view->m_reference, m_view->m_epsilon)) > { > IterBase::operator++(); > } > } > }; > > template<typename Derived> > const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& m_reference, >diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt >--- a/test/CMakeLists.txt >+++ b/test/CMakeLists.txt >@@ -224,16 +224,17 @@ ei_add_test(prec_inverse_4x4) > ei_add_test(vectorwiseop) > ei_add_test(special_numbers) > > ei_add_test(simplicial_cholesky) > ei_add_test(conjugate_gradient) > ei_add_test(bicgstab) > ei_add_test(sparselu) > ei_add_test(sparseqr) >+ei_add_test(sparse_iterators) > > # ei_add_test(denseLM) > > if(QT4_FOUND) > ei_add_test(qtvector "" "${QT_QTCORE_LIBRARY}") > endif(QT4_FOUND) > > ei_add_test(eigen2support) >diff --git a/test/sparse_iterators.cpp b/test/sparse_iterators.cpp >new file mode 100644 >--- /dev/null >+++ b/test/sparse_iterators.cpp >@@ -0,0 +1,150 @@ >+// This file is part of Eigen, a lightweight C++ template library >+// for linear algebra. >+// >+// Copyright (C) 2013 Désiré Nuentsa <desire.nuentsa_wakam@inria.fr> >+// >+// This Source Code Form is subject to the terms of the Mozilla >+// Public License v. 2.0. If a copy of the MPL was not distributed >+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. >+ >+#include "sparse.h" >+template<typename SparseMatrixType, typename DenseMatrix> >+void kernel_sparse_iterator(const SparseMatrixType& mS, const DenseMatrix& refS) >+{ >+ typedef typename SparseMatrixType::Scalar Scalar; >+ typedef typename SparseMatrixType::Index Index; >+ typedef Matrix<Scalar,Dynamic,1> DenseVector; >+ Index size = mS.cols(); >+ >+ // Test the function pos() of SparseMatrixType::InnerIterator and ReverseInnerTerator >+ { >+ VectorXi forward_pos(size); // for the internal positions of iterator >+ VectorXi reverse_pos(size); // internal positions of reverse iterator >+ VectorXi forward_idx(size); // Row Index in each column where to stop iterating >+ VectorXi reverse_idx(size); // Row Index in each column where to stop reverse iterating >+ for (Index j = 0; j < size; j++) >+ { >+ forward_idx(j) = internal::random<int>(0, j); >+ reverse_idx(j) = internal::random<int>(j, size - 1); >+ } >+ >+ /* Browse the matrix mS until the selected row indexes or the diagonal element >+ * and save the positions of the iterators for each column >+ */ >+ forward_pos.setZero(); reverse_pos.setZero(); >+ for (Index j = 0; j < size; j++) >+ { >+ for (typename SparseMatrixType::InnerIterator it(mS,j); it; ++it) >+ { >+ if ( (it.index() == forward_idx(j)) || (it.index() == j)) >+ { >+ forward_pos(j) = it.pos(); >+ forward_idx(j) = it.index(); >+ break; >+ } >+ } >+ for (typename SparseMatrixType::ReverseInnerIterator r_it(mS, j); r_it; --r_it) >+ { >+ if ( (r_it.index() == reverse_idx(j)) || (r_it.index() == j)) >+ { >+ reverse_pos(j) = r_it.pos(); >+ reverse_idx(j) = r_it.index(); >+ break; >+ } >+ } >+ } >+ // Get the values of refS and mS in the saved positions >+ DenseVector refdS(size), refsS(size); >+ for(Index j = 0; j < size; ++j) refdS(j) = refS.coeffByOuterInner(j,forward_idx(j)); >+ //refS.coeffByOuterInner(j,forward_idx(j)) >+ for (Index j = 0; j < size; ++j) >+ { >+ typename SparseMatrixType::InnerIterator it(mS, j); >+ it += forward_pos(j); >+ refsS(j) = it.value(); >+ } >+ >+ VERIFY_IS_APPROX(refdS, refsS); >+ >+ for(Index j = 0; j < size; ++j) refdS(j) = refS.coeffByOuterInner(j,reverse_idx(j)); >+ for (Index j = 0; j < size; ++j) >+ { >+ typename SparseMatrixType::ReverseInnerIterator it(mS, j); >+ it -= reverse_pos(j); >+ refsS(j) = it.value(); >+ } >+ VERIFY_IS_APPROX(refdS, refsS); >+ } >+ >+ /* Test copy constructors >+ * for SparseMatrix::InnerIterator >+ * and SparseMatrix::ReverseInnerIterator >+ */ >+ { >+ Index c = internal::random<int>(0, size - 1); >+ Index r1 = internal::random<int>(0, c); >+ typename SparseMatrixType::InnerIterator it(mS, c); >+ //Iterate until mS(r,c) if it exists otherwise mS(c, c) >+ for (; it; ++it) >+ { >+ if ( (it.index() == r1) || (it.index() == c)) >+ { >+ r1 = it.index(); // Save the row index effectively found >+ break; >+ } >+ } >+ //Copy the constructor >+ typename SparseMatrixType::InnerIterator itc(it); >+ VERIFY_IS_EQUAL(itc.value(), refS.coeffByOuterInner(c, r1)); >+ //Same stuffs with ReverseInnerTerator >+ Index r2 = internal::random<int>(c, size - 1); >+ typename SparseMatrixType::ReverseInnerIterator r_it(mS, c); >+ for (; r_it; --r_it) >+ { >+ if ( (r_it.index() == r2) || (r_it.index() == c)) >+ { >+ r2 = r_it.index(); >+ break; >+ } >+ } >+ typename SparseMatrixType::ReverseInnerIterator r_itc(r_it); >+ VERIFY_IS_EQUAL(r_itc.value(), refS.coeffByOuterInner(c, r2)); >+ } >+} >+ >+ >+template <typename SparseMatrixType> >+void sparse_iterator() >+{ >+ typedef typename SparseMatrixType::Index Index; >+ typedef typename SparseMatrixType::Scalar Scalar; >+ typedef Matrix<Scalar,Dynamic, Dynamic, SparseMatrixType::Flags&RowMajor ? RowMajor : ColMajor > DenseMatrix; >+ >+ // Generate the matrices >+ Index n = 100; >+ const Index size = internal::random<int>(1,n); >+ DenseMatrix refS(size,size); >+ SparseMatrixType mS(size, size); >+ double density = (std::max)(8./(size*size), 0.1); >+ initSparse<Scalar>(density, refS, mS, ForceNonZeroDiag); >+ >+ // Test with the full matrix >+ kernel_sparse_iterator(mS, refS); >+ const Index r = internal::random<int>(0, n/2); >+ >+ // Test with the block matrices >+ // kernel_sparse_iterator(mS.topLeftCorner(r, r), refS.topLeftCorner(r,r)); >+ // kernel_sparse_iterator(mS.bottomRightCorner(r, r), refS.bottomRightCorner(r,r)); >+ // Test with the mapped sparse matrix ... applicable ?? >+} >+ >+void test_sparse_iterators() >+{ >+ for (int i = 0; i < g_repeat; i++) >+ { >+ CALL_SUBTEST_1( (sparse_iterator<SparseMatrix<double, ColMajor> >()) ); >+ CALL_SUBTEST_1( (sparse_iterator<SparseMatrix<double, RowMajor> >()) ); >+ CALL_SUBTEST_2( (sparse_iterator<SparseMatrix<std::complex<double>, ColMajor> >()) ); >+ CALL_SUBTEST_2( (sparse_iterator<SparseMatrix<std::complex<double>, RowMajor> >()) ); >+ } >+} >diff --git a/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h b/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h >--- a/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h >+++ b/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h >@@ -320,38 +320,44 @@ template<typename _Scalar, int _Options, > # endif > }; > > template<typename Scalar, int _Options, typename _Index> > class DynamicSparseMatrix<Scalar,_Options,_Index>::InnerIterator : public SparseVector<Scalar,_Options,_Index>::InnerIterator > { > typedef typename SparseVector<Scalar,_Options,_Index>::InnerIterator Base; > public: >+ InnerIterator() >+ : Base(),m_outer(-1) >+ {} > InnerIterator(const DynamicSparseMatrix& mat, Index outer) > : Base(mat.m_data[outer]), m_outer(outer) > {} > > inline Index row() const { return IsRowMajor ? m_outer : Base::index(); } > inline Index col() const { return IsRowMajor ? Base::index() : m_outer; } > > protected: >- const Index m_outer; >+ Index m_outer; > }; > > template<typename Scalar, int _Options, typename _Index> > class DynamicSparseMatrix<Scalar,_Options,_Index>::ReverseInnerIterator : public SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator > { > typedef typename SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator Base; > public: >+ ReverseInnerIterator() >+ : Base(),m_outer(-1) >+ {} > ReverseInnerIterator(const DynamicSparseMatrix& mat, Index outer) > : Base(mat.m_data[outer]), m_outer(outer) > {} > > inline Index row() const { return IsRowMajor ? m_outer : Base::index(); } > inline Index col() const { return IsRowMajor ? Base::index() : m_outer; } > > protected: >- const Index m_outer; >+ Index m_outer; > }; > > } // end namespace Eigen > > #endif // EIGEN_DYNAMIC_SPARSEMATRIX_H
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 557
:
315
| 362