Eigen how to concatenate matrix along a specific d

2020-01-30 07:57发布

问题:

I have two eigen matrices and I would like to concatenate them, like in matlab cat(0, A, B)

Is there anything equivalent in eigen?

Thanks.

回答1:

You can use the comma initializer syntax for that.

Horizontally:

MatrixXd C(A.rows(), A.cols()+B.cols());
C << A, B;

Vertically:

// eigen uses provided dimensions in declaration to determine
// concatenation direction
MatrixXd D(A.rows()+B.rows(), A.cols()); // <-- D(A.rows() + B.rows(), ...)
D << A, B; // <-- syntax is the same for vertical and horizontal concatenation

For readability, one might format vertical concatenations with whitespace:

D << A,
     B; // <-- But this is for readability only. 


回答2:

I had a slightly different use case: To vertically stack a std::vector of Eigen matrices. Here is how I implemented a function which is more general purpose. Let me know if this can be further improved:

// matrix_eig = Eigen::MatrixXf in RowMajor format
matrix_eig VStack(const std::vector<matrix_eig> &mat_vec) {
  assert(!mat_vec.empty());
  long num_cols = mat_vec[0].cols();
  size_t num_rows = 0;
  for (size_t mat_idx = 0; mat_idx < mat_vec.size(); ++mat_idx) {
    assert(mat_vec[mat_idx].cols() == num_cols);
    num_rows += mat_vec[mat_idx].rows();
  }
  matrix_eig vstacked_mat(num_rows, num_cols);
  size_t row_offset = 0;
  for (size_t mat_idx = 0; mat_idx < mat_vec.size(); ++mat_idx) {
    long cur_rows = mat_vec[mat_idx].rows();
    vstacked_mat.middleRows(row_offset, cur_rows) = mat_vec[mat_idx];
    row_offset +=  cur_rows;
  }
  return vstacked_mat;
}


回答3:

I'd use Eigen's block indexing in a way similar to this post (which concatenates to an existing matrix).

The block indexing avoids the direction ambiguity in the accepted approach, and is pretty compact syntax. The following is equivalent to C = cat(2, A, B) in MATLAB:

MatrixXd C(A.rows(), A.cols()+B.cols());
C.leftCols(A.cols()) = A;
C.rightCols(B.cols()) = B;


标签: c++ eigen