Foreach loops over Eigen matrices? - c++11

Is it possible to use the foreach syntax of C++11 with Eigen matrices? For instance, if I wanted to compute the sum of a matrix (I know there's a builtin function for this, I just wanted a simple example) I'd like to do something like
Matrix2d a;
a << 1, 2,
3, 4;
double sum = 0.0;
for(double d : a) {
sum += d;
}
However Eigen doesn't seem to allow it. Is there a more natural way to do a foreach loop over elements of an Eigen matrix?

Range-based for loops need the methods .begin() and .end() to be implemented on that type, which they are not for Eigen matrices. However, as a pointer is also a valid random access iterator in C++, the methods .data() and .data() + .size() can be used for the begin and end functions for any of the STL algorithms.

For your particular case, it's more useful to obtain start and end iterators yourself, and pass both iterators to a standard algorithm:
auto const sum = std::accumulate(a.data(), a.data()+a.size(), 0.0);
If you have another function that really needs range-based for, you need to provide implementations of begin() and end() in the same namespace as the type (for argument-dependent lookup). I'll use C++14 here, to save typing:
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(); }
}

STL style iterator support has been added to Eigen in version 3.4.
See https://eigen.tuxfamily.org/dox-devel/group__TutorialSTL.html
For OP's question, you can do the following:
Matrix2d A;
A << 1, 2,
3, 4;
double sum = 0.0;
for(auto x : A.reshaped())
sum += x;

A pointer to the data array of the matrix 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 the pointers to the first element and end of the array as a.data() and a.data()+a.size().
Also, we know that an std::vector can be initialized using iterators (or array pointers in our case).
Thus, we can obtain a vector of doubles that wraps the matrix elements with std::vector<double>(a.data(), a.data()+a.size()).
This vector can be used with the range-based for loop syntax that is included in your code snippet as:
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;
}

Related

Function taking std::initializer_list

I came across a function a colleague had written that accepted an initializer list of std::vectors. I have simplified the code for demonstration:
int sum(const std::initializer_list<std::vector<int>> list)
{
int tot = 0;
for (auto &v : list)
{
tot += v.size();
}
return tot;
}
Such a function would allow you call the function like this with the curly braces for the initializer list:
std::vector<int> v1(50, 1);
std::vector<int> v2(75, 2);
int sum1 = sum({ v1, v2 });
That looks neat but doesn't this involve copying the vectors to create the initializer list? Wouldn't it be more efficient to have a function that takes a vector or vectors? That would involve less copying since you can move the vectors. Something like this:
int sum(const std::vector<std::vector<int>> &list)
{
int tot = 0;
for (auto &v : list)
{
tot += v.size();
}
return tot;
}
std::vector<std::vector<int>> vlist;
vlist.reserve(2);
vlist.push_back(std::move(v1));
vlist.push_back(std::move(v2));
int tot = sum2(vlist);
Passing by initializer list could be useful for scalar types like int and float, but I think it should be avoided for types like std::vector to avoid unnecessary copying. Best to use std::initializer_list for constructors as it intended?
That looks neat but doesn't this involve copying the vectors to create the initializer list?
Yes, that is correct.
Wouldn't it be more efficient to have a function that takes a vector or vectors?
If you are willing to move the contents of v1 and v2 to a std::vector<std::vector<int>>, you could do the samething when using std::initializer_list too.
std::vector<int> v1(50, 1);
std::vector<int> v2(75, 2);
int sum1 = sum({ std::move(v1), std::move(v2) });
In other words, you can use either approach to get the same effect.

Eigen - return type of .cwiseProduct?

I am writing a function in RcppEigen for weighted covariances. In one of the steps I want to take column i and column j of a matrix, X, and compute the cwiseProduct, which should return some kind of vector. The output of cwiseProduct will go into an intermediate variable which can be reused many times. From the docs it seems cwiseProduct returns a CwiseBinaryOp, which itself takes two types. My cwiseProduct operates on two column vectors, so I thought the correct return type should be Eigen::CwiseBinaryOp<Eigen::ColXpr, Eigen::ColXpr>, but I get the error no member named ColXpr in namespace Eigen
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
Rcpp::List Crossprod_sparse(Eigen::MappedSparseMatrix<double> X, Eigen::Map<Eigen::MatrixXd> W) {
int K = W.cols();
int p = X.cols();
Rcpp::List crossprods(W.cols());
for (int i = 0; i < p; i++) {
for (int j = i; j < p; j++) {
Eigen::CwiseBinaryOp<Eigen::ColXpr, Eigen::ColXpr> prod = X.col(i).cwiseProduct(X.col(j));
for (int k = 0; k < K; k++) {
//double out = prod.dot(W.col(k));
}
}
}
return crossprods;
}
I have also tried saving into a SparseVector
Eigen::SparseVector<double> prod = X.col(i).cwiseProduct(X.col(j));
as well as computing, but not saving at all
X.col(i).cwiseProduct(X.col(j));
If I don't save the product at all, the functions returns very quickly, hinting that cwiseProduct is not an expensive function. When I save it into a SparseVector, the function is extremely slow, making me think that SparseVector is not the right return type and Eigen is doing extra work to get it into that type.
Recall that Eigen relies on expression templates, so if you don't assign an expression then this expression is essentially a no-op. In your case, assigning it to a SparseVector is the right thing to do. Regarding speed, make sure to compile with compiler optimizations ON (like -O3).
Nonetheless, I believe there is a faster way to write your overall computations. For instance, are you sure that all X.col(i).cwiseProduct(X.col(j)) are non empty? If not, then the second loop should be rewritten to iterate over the sparse set of overlapping columns only. Loops could also be interchanged to leverage efficient matrix products.

storing map<string, struct> into vector to sort

I have the following code that I am trying. I am trying to sort it by ascending or descending size, and from z-a (three different sorts). I can't figure out how to even store it in the vector let alone sort it. Thanks for the help!
struct countSize {
int count;
uintmax_t size;
void sortMap(map<string, countSize> &extCount)
{
// Copy
vector<string, countSize> v(extCount.begin(), extCount.end());
// Sort the vector according to either file size or desc alphabetically
//print
}
int main()
{
map<string, countSize> mp;
mp["hello"] = { 1, 200 };
mp["Ace"] = { 5, 600 };
mp["hi"] = { 3, 300 };
mp["br"] = { 2, 100 };
sortMap(mp);
}
If you iterate over a map, you get a stream of std::pair<const X, Y>. That's a bit awkward for storing in a vector, because of the const. One solution is to just drop the const:
using my_map = std::map<std::string, countSize>;
// Mutable element type.
using my_map_element = std::pair<typename my_map::key_type,
typename my_map::mapped_type>;
using my_element_list = std::vector<my_map_element>;
Then it's very straight-forward to build a vector and sort it. Here, we use a template for the comparison function which makes it a lot easier to use a lambda for the comparator:
template<typename Functor>
my_element_list sortMap(const my_map& the_map, Functor compare) {
my_element_list v(the_map.begin(), the_map.end());
std::sort(v.begin(), v.end(), compare);
return v;
}
Unlike your code, this returns the sorted list. The caller can print the list if desired. See, for example, the example live on Coliru.
That's not really ideal, though. If the individual elements of the map are at all complicated, it may well be more efficient to make a vector of pointers to the elements, rather than copies of the elements. Amongst other things, this does not require readjusting the element type, and that makes it possible to be agnostic about the base container type as well. However, you need to remember that the comparison functor will now receive pointers to the elements to be compared. See the modified example.

Specifying iterator value in stable_sort function

I am using the below code to sort rectangles.
In the stable_sort function, how can I specify the iterator values other than boundRect.begin and boundRect.end. I want to sort the elements between index 5 to 10. How can I specify these in the stable_sort function? Please guide me.
stable_sort( boundRect.begin(), boundRect.end(), compareX_rect );
bool compareX_rect(const Rect & a, const Rect &b) {
return a.x <= b.x;
}
Since stable_sort requires random access iterators, you can do simple addition on the iterators:
stable_sort(boundRect.begin()+5, boundRect.begin()+10, /* ... */
Unless you're dealing with an ancient (pre-C++11) compiler, you can use a lambda expression for the comparison as well:
stable_sort(boundRect.begin()+5, boundRect.begin()+10,
[](const Rect & a, const Rect &b) { return a.x < b.x; });
This not only shorter and easier to read, but will often be faster as well (not that it's likely to matter when you're only sorting 5 elements).

Number which occurs only once in the array [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Finding a single number in a list
Given an array of numbers, except for one number all the others, occur
twice. What should be the algorithm to find that number which occurs only once in the
array?
Example
a[1..n] = [1,2,3,4,3,1,2]
should return 4
Let the number which occurs only once in the array be x
x <- a[1]
for i <- 2 to n
x <- x ^ a[i]
return x
Since a ^ a = 0 and a ^ 0 = a
Numbers which occur in pair cancel out and the result gets stored in x
Working code in C++
#include <iostream>
template<typename T, size_t N>
size_t size(T(&a)[N])
{
return N;
}
int main()
{
int a [] = {1,2,3,4,3,1,2};
int x = a[0];
for (size_t i = 1; i< size(a) ; ++i)
{
x = x ^ a[i];
}
std::cout << x;
}
Create new int i = 0
XOR each item with i
After all iterations there will be expected number in i
If you have quantities which cannot be reasonably xored (Big Integers or numbers represented as Strings, for example), an alternate approach which is also O(n) time, (but O(n) space rather than O(1) space) would be to simply use a hash table. The algorithm looks like:
Create a hash table of the same size as the list
For every item in the list:
If item is a key in hash table
then remove item from hash table
else add item to hash table with nominal value
At the end, there should be exactly one item in the hash table
I would do, C or C++ code, but neither of them have hash tables built in. (Don't ask me why C++ doesn't have a hash table in the STL, but does have a hash map based on a red-black tree, because I have no idea what they were thinking.) And, unfortunately, I don't have a C# compiler handy to test for syntax errors, so I'm giving you Java code. It's pretty similar, though.
import java.util.Hashtable;
import java.util.List;
class FindUnique {
public static <T> T findUnique(List<T> list) {
Hashtable<T,Character> ht = new Hashtable<T,Character>(list.size());
for (T item : list) {
if (ht.containsKey(item)) {
ht.remove(item);
} else {
ht.put(item,'x');
}
}
return ht.keys().nextElement();
}
}
Well i only know of the Brute force algo and it is to traverse whole array and check
Code will be like (in C#):
k=0;
for(int i=0 ; i < array.Length ; i++)
{
k ^= array[i];
}
return k;
zerkms' answer in C++
int a[] = { 1,2,3,4,3,1,2 };
int i = std::accumulate(a, a + 7, 0, std::bit_xor<int>());
You could sort the array and then find the first element that doesn't have a pair. That would require several loops for sorting and a loop for finding the single element.
But a simplier method would be setting the double keys to zero or a value that is not possible in the current format. Depends on the programming language, as well, as you cannot change key types in c++ unlike c#.

Resources