Eigen extracting submatrix from vector of indices
Asked Answered
O

3

7

I have been googling for a while now, but cant find the answer to this simple question.

In matlab i can do this:

rows = [1 3 5 9];
A = rand(10);
B = A(rows, : );

How do i do this in eigen? It does not seem like it is possible. The closest thing i have found is

MatrixXd a(10,10);
a.row(1); 

,but I want to get multiple rows/cols. Another user has also asked the question here: How to extract a subvector (of a Eigen::Vector) from a vector of indices in Eigen? , but I think there must some built in way of doing this because it is a really common operation I think.

Thanks.

Otherworld answered 16/10, 2016 at 19:51 Comment(2)
For anyone who stumbles on to this page years later (like myself)... I just wanted to add to @chtz's answer that Gael responded to the feature request last year. The feature is currently available in Eigen's dev branch. See this link for documentation: eigen.tuxfamily.org/dox-devel/… - posted on behalf of stackoverflow.com/users/3077484/alice-schwarze request.Electroanalysis
Maybe not precisely what you're looking for, but the Eigen block operations are useful for getting subsets of Eigen matrices.Traditional
G
11

While this was not possible at the time this question was asked, it has since been added in the development branch!

It's very straight forward:

Eigen::MatrixXf matrix;
Eigen::VectorXi columns;
Eigen::MatrixXf extracted_cols = matrix(Eigen::all, columns);

So I'm guessing this will be in the 3.3.5 3.4 stable release. Until then the development branch is the way to go.

Gullett answered 1/5, 2018 at 11:31 Comment(0)
F
2

Unfortunately, this is still not directly supported even in Eigen 3.3. There has been this feature request for a while: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=329

Gael linked to an example implementation in one of the comments there: http://eigen.tuxfamily.org/dox-devel/TopicCustomizing_NullaryExpr.html#title1

Floccule answered 17/10, 2016 at 12:32 Comment(0)
M
-1

Ok, say for example you have a 3x3 matrix:

m = [3   -1   1; 2.5  1.5 6; 4    7   1]

and say you want to extract following rows from m matrix:

[0 2], // row 0 and row 2

essentially giving out following matrix:

new_extracted_matrix = [3 -1 1; 4  7 1]  // row 0 and row 2 of matrix m

Main thing here is, let's create a vector v having contents [0 2], means we would extract following row indices from matrix m. Here is what i did:

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
int main()
{
  Matrix3f m;
  m(0,0) = 3;
  m(0,1) = -1;
  m(0,2) = 1;  
  m(1,0) = 2.5;
  m(1,1) = m(1,0) + m(0,1);
  m(1,2) = 6;
  m(2,0) = 4;
  m(2,1) = 7;
  m(2,2) = 1;  
  std::cout << "Here is the matrix m:\n" << m << std::endl; // Creating a random 3x3 matrix
  VectorXf v(2);
  v(0) = 0; // Extracting row 0
  v(1) = 2; // Extracting row 2

  MatrixXf r(1,v.size());
  for (int i=0;i<v.size();i++)
  {
      r.col(i) << v(i); // Creating indice vector
  }
  cout << "The extracted row indicies of above matrix: " << endl << r << endl;

  MatrixXf N = MatrixXf::Zero(r.size(),m.cols());
  for (int z=0;z<r.size();z++)
  {
    N.row(z) = m.row(r(z));
  }

  cout << "Extracted rows of given matrix: " << endl << N << endl;
}

This would give us following output:

Here is the matrix m: [3 -1 1; 2.5 1.5 6; 4 7 1]

The extracted row indicies of above matrix: [0 2]

Extracted rows of given matrix: [3 -1 1; 4 7 1]

Maladjusted answered 2/7, 2017 at 2:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.