[eigen] Full Matrix Iterator? |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
Hello,
I'm new to Eigen, and all I need right now is some simple stuff to store sparse matrices, convert their formats and multiply them together.
I researching how to do this stuff in Eigen, I was somewhat surprised by the instructions on how to iterate over coefficients in a sparse matrix. Surprised, because this recipe does not fully hide implementation details from the user, and makes iterating over matrix elements a little difficult / non-standard:
------------------------------------------------------------
Iterating over the nonzero coefficients
Iterating over the coefficients of a sparse matrix can be done only in the same order than the storage order.
Here is an example:
SparseMatrixType mat(rows,cols);
for (int k=0; k\<m1.outerSize(); ++k)
for (SparseMatrixType::InnerIterator it(mat,k); it; ++it) {
it.value();
it.row(); // row index
it.col(); // col index (here it is equal to k)
it.index(); // inner index, here it is equal to it.row()
}
------------------------------------------------------------
Is there any reason NOT to write a "FullIterator" class, such as the one below? Ideally, it should be called SparseMatrix::FullIterator, but having it outside SparseMatrix for prototyping should work.
Other puzzling points about these iterators (which I have not tried to "fix" in FullIterator below) is that they work differently from STL iterators, for reasons that are opaque to me at this point. By that, I mean, normally one would use iterators as follows:
for (SparseMatrixType::FullIterator it = mat.begin(); it != mat.end(); ++it) {
it.value(); it.row(); it.col();
}
So why have the standard conventions for setting up an iterator, and testing for end, been changed?
Anyway.. please tell me if this FullIterator thing is something you want, I'd be happy to integrate it into Eigen and upload my changes to the repo.
Thanks!
-- Bob
template <class SparseMatrixT>
class FullIterator {
protected:
SparseMatrixT *_mat;
int _k;
SparseMatrixT::InnerIterator _it;
public:
FullIterator(SparseMatrixT const &mat) : _mat(&mat), _k(0), _it(*_mat, k) {}
inline FullIterator& operator++() {
++_it;
if (!_it()) {
++_k;
if (_k < _mat->outerSize()) {
_it = SparseMatrix::InnerIterator(*_mat, _k);
}
}
return *this;
}
inline operator bool() const { return _k < _mat->outerSize(); }
inline const Scalar& value() const { return it.value(); }
inline Scalar& valueRef() { return it.valueRef(); }
inline Index index() const { return it.index(); }
inline Index outer() const { return it.outer(); }
inline Index row() const { return it.row(); }
inline Index col() const { return it.col(); }
};