Foreach loops over your own matrices?

Is it possible to use foreach C ++ 11 syntax with native matrices? For example, if I wanted to calculate the sum of the matrix (I know there is a built-in function for this, I just wanted a simple example), I would like to do something like

Matrix2d a; a << 1, 2, 3, 4; double sum = 0.0; for(double d : a) { sum += d; } 

However, Eigen does not seem to allow this. Is there a more natural way to make a foreach loop over elements of my own matrix?

+6
source share
3 answers

For range-based loops, you need .begin() and .end() methods for this type, which they are not for native matrices. However, since the pointer is also a valid random access iterator in C ++, the .data() and .data() + .size() can be used for start and end functions for any of the STL algorithms.

+3
source

For your specific case, it is more useful to get the start and end iterators yourself and pass both iterators to the standard algorithm:

 auto const sum = std::accumulate(a.data(), a.data()+a.size(), 0.0); 

If you have another function that really needs a range based on for , you need to provide implementations of begin() and end() in the same type namespace (for an argument depending on the search). I will use C ++ 14 here to save input:

 namespace Eigen { auto begin(Matrix2d& m) { return m.data(); } auto end(Matrix2d& m) { return m.data()+m.size(); } auto begin(Matrix2d const& m) { return m.data(); } auto end(Matrix2d const& m) { return m.data()+m.size(); } } 
+1
source

A pointer to a matrix data array can be obtained using the member function .data() .

The size of the data array can also be obtained using the member function .size() .

Using these two, we now have pointers to the first element and the end of the array as a.data() and a.data()+a.size() .

In addition, we know that std::vector can be initialized using iterators (or array pointers in our case).

Thus, we can get a double vector that wraps matrix elements with std::vector<double>(a.data(), a.data()+a.size()) .

This vector can be used with loop syntax for a loop that is included in your code snippet, like:

  Matrix2d a; a << 1, 2, 3, 4; double sum = 0.0; for(double d : std::vector<double>(a.data(), a.data()+a.size())) { sum += d; } 
-1
source

Source: https://habr.com/ru/post/1207268/


All Articles