Search code examples
eigen3

Build a new matrix made of some source matrix rows given a row index vector


I want to build a new matrix made of some source matrix rows given a vector of non consecutive indexes.

Namely, I'd like a row() function which take a list of indexes and returns the list of rows stored in a new matrix :

  VectorXi v = VectorXi::LinSpaced( 4, 10, 13);
  MatrixXi m = v.rowwise().replicate( 4 );
  VectorXi r1 ( ( VectorXi(3) <<  0,  3, 1 ).finished() );

  // Here is some pseudo code to create the desired matrix N :
  MatrixXi N = m.row(r1);

  cout << "m = " << m << endl;
  cout << "r1 = " << r1 << endl;
  cout << "N = " << N << endl;

Desired output :

m = 

10 10 10 10
11 11 11 11
12 12 12 12
13 13 13 13

r1 =
0
3
1

N =
10 10 10 10
13 13 13 13
11 11 11 11

Thanks a lot for helping.

Sylvain


Solution

  • With the development branch and (at least) C++11 enabled, you can write:

    Eigen::MatrixXi N = m(r1,Eigen::all);
    

    This is similar to the Matlab syntax:

    N = m(r1, :);
    

    You can also pass {x,...}-lists directly, or anything that behaves like an std::vector<int> (must provide a size() function and an operator[] and return an integral type), e.g.:

    std::vector<int> c2{{3,0}};
    std::cout << "m({2,1},c2) = \n" << m({2,1}, c2) << '\n';
    

    These expressions are writable (assuming m itself is writable):

    m({2,1}, c2) = Eigen::Matrix2i{{1,2},{3,4}};
    std::cout << m << '\n';
    

    Godbolt demo: https://godbolt.org/z/cjacOY