4

In one of the functions in the project I am working on, I need to find the remainder of each element of my eigen library matrix when divided by a given number. Here is the Matlab equivalent to what I want to do:

mod(X,num)

where X is the dividend matrix and num is the divisor.

What is the easiest way to achieve this?

pincir
  • 345
  • 1
  • 3
  • 7
  • I've used Armadillo in the past but I wanted to try out Eigen for this project. Is there no way this can be done in Eigen? – pincir Mar 04 '16 at 14:48
  • Not that I am aware of. You could write your own mod function using the other functions in eigen to do the needed operations to get the same effect of mod() – Jacobr365 Mar 04 '16 at 14:55
  • @Jacobr365: I cannot see such a method in arma's doc, nor arma's source code. – ggael Mar 04 '16 at 21:19
  • Arma doesn't have such a method. @ggael's solution works though. – pincir Mar 06 '16 at 19:48

2 Answers2

12

You can use a C++11 lambda with unaryExpr:

MatrixXi A(4,4), B;
A.setRandom();
B = A.unaryExpr([](const int x) { return x%2; });

or:

int l = 2;
B = A.unaryExpr([&](const int x) { return x%l; });
ggael
  • 28,425
  • 2
  • 65
  • 71
2

For completeness, another solution would be to:

  1. transform X to an eigen array (for coeffwise operations),
  2. Apply the modulo formula a%b = a - (b * int(a/b))

C++ code that return an eigen array:

auto mod_array = X.array() - (num * (X.array()/num));

C++ code to get a matrix:

auto mod_matrix = (X.array() - (num * (X.array()/num))).matrix();

Note that, parentheses are important especially in (X.array()/num) as eigen will optimize (num * X.array()/num) to X.array() which is not what we expect.

The first version with eigen array is faster than version with unaryExpr. The second version with matrix takes about the same time as version with unaryExpr.

If X contains float numbers, you will need to cast X.array() in (X.array()/num) to int

Mazyad
  • 65
  • 8