AspiringMat
AspiringMat

Reputation: 2279

Apply function to all elements in Eigen Matrix without loop

I have an Eigen::Matrix and I would like to generate a new matrix where all its elements are generated by the some function call to the elements of the matrix:

Matrix< Foo,2,2 > m = ...;
Matrix< int, 2, 2> new_m;

for each m[i][j]:
  new_m[i][j] = m[i][j].member_of_foo_returns_int()

I had a look on Eigen::unaryExpr but the elements changed and the return have to be the same. However, I have Foo objects in the first matrix, and an int returned in the new matrix. Is this possible without a vanilla loop?

Upvotes: 1

Views: 1211

Answers (1)

chtz
chtz

Reputation: 18827

You can pass a lambda expression to unaryExpr, like so:

Eigen::Matrix<int,2,2> new_m = m.unaryExpr(
    [](const Foo& x) {
        return x.member_of_foo_returns_int();
    });

If you can't use c++11, you need to write a small helper function:

int func_wrapper(const Foo& x) {
    return x.member_of_foo_returns_int();
}

and pass that using std::ptr_fun:

Eigen::Matrix<int,2,2> new_m = m.unaryExpr(std::ptr_fun(func_wrapper));

For calling member functions there is actually a nice helper function already implemented named std::mem_fun_ref (this takes a member function pointer and returns a functor object which is accepted by unaryExpr):

Eigen::Matrix<int,2,2> new_m = m.unaryExpr(
    std::mem_fun_ref(&Foo::member_of_foo_returns_int));

All these variants are type safe, i.e., trying to store the result in a non-int-Matrix will not compile.

Upvotes: 3

Related Questions