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.
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;
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.
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;
}