I finally wrote a sane, easy-to-use iterator for Eigen::SparseMatrix. See below... Although I haven't tried it, I believe this iterator is compatible with Eigen::SparseMatrix::setFromTriplets(). #define ARGS _Scalar,_Options,_StorageIndex template<class _Scalar, int _Options, class _StorageIndex> class EigenSparseMatrixIterator : public ibmisc::forward_iterator< EigenSparseMatrixIterator<ARGS>, EigenSparseMatrixIterator<ARGS>> { typedef EigenSparseMatrixIterator<ARGS> IteratorT; public: typedef _StorageIndex index_type; typedef _Scalar val_type; static const int RANK = 2; Eigen::SparseMatrix<ARGS> const &M; int k; typename Eigen::SparseMatrix<ARGS>::InnerIterator ii; EigenSparseMatrixIterator(Eigen::SparseMatrix<ARGS> const &_M, int _k) : M(_M), k(_k), ii(typename Eigen::SparseMatrix<ARGS>::InnerIterator(M,k)) {} // --------------------------------------------------------- // http://www.cplusplus.com/reference/iterator/ IteratorT &operator++() { // Prefix ++ ++ii; if (!ii) { ++k; ii.~InnerIterator(); new (&ii) typename Eigen::SparseMatrix<ARGS>::InnerIterator(M,k); } return *this; } bool operator==(IteratorT const &other) const { return (k == other->k) && (ii == other->ii); } // bool operator==(IteratorT const other) const // { return (k == other->k) && (ii == other->ii); } IteratorT &operator*() { return *this; } IteratorT const &operator*() const { return *this; } // IteratorT *operator->() // { return this; } // ---------- What you get once you dereference _Scalar const &value() { return ii.value(); } _StorageIndex row() { return ii.row(); } _StorageIndex col() { return ii.col(); } _StorageIndex index(int ix) { return ix == 0 ? row() : col(); } std::array<_StorageIndex,2> index() { return {row(), col()}; } }; // ----------------------------------- template<class _Scalar, int _Options, class _StorageIndex> EigenSparseMatrixIterator<ARGS> begin(Eigen::SparseMatrix<ARGS> const &M) { return EigenSparseMatrixIterator<ARGS>(M,0); } template<class _Scalar, int _Options, class _StorageIndex> EigenSparseMatrixIterator<ARGS> end(Eigen::SparseMatrix<ARGS> const &M) { return EigenSparseMatrixIterator<ARGS>(M,M.outerSize()); } #undef ARGS
Here is ibmisc::forward_iterator, used above. template<class ValueT, class DerivedT> class forward_iterator : public std::iterator<std::forward_iterator_tag, ValueT> { DerivedT *derived() { return static_cast<DerivedT *>(this); } DerivedT const *derived() const { return static_cast<DerivedT const *>(this); } public: ValueT *operator->() { return &derived()->operator*(); } ValueT const *operator->() const { return &derived()->operator*(); } DerivedT operator++(int) { DerivedT clone(derived()); derived()->operator+=(1); return clone; } bool operator!=(const DerivedT& rhs) const {return !derived()->operator==(rhs); } };
-- GitLab Migration Automatic Message -- This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/1374.