J'ai deux matrices propres et je voudrais les concaténer, comme dans matlab cat(0, A, B)
Y a-t-il quelque chose d'équivalent dans eigen?
Merci.
Vous pouvez utiliser la syntaxe d'initialisation par virgule pour cela.
Horizontalement:
MatrixXd C(A.rows(), A.cols()+B.cols());
C << A, B;
Verticalement:
// 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
Par souci de lisibilité, on peut formater des concaténations verticales avec des espaces:
D << A,
B; // <-- But this is for readability only.
J'ai eu un cas d'utilisation légèrement différent: Pour empiler verticalement un std :: vector de matrices Eigen. Voici comment j'ai implémenté une fonction qui a un but plus général. Faites-moi savoir si cela peut encore être amélioré:
// 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;
}
J'utiliserais l'indexation par blocs d'Eigen d'une manière similaire à cet article (qui concatène une matrice existante).
L'indexation de blocs évite l'ambiguïté du sens dans l'approche acceptée et constitue une syntaxe assez compacte. Ce qui suit est équivalent à C = cat(2, A, B)
dans MATLAB:
MatrixXd C(A.rows(), A.cols()+B.cols());
C.leftCols(A.cols()) = A;
C.rightCols(B.cols()) = B;