Question

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.

Was it helpful?

Solution

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. 

OTHER TIPS

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;

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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top