web-dev-qa-db-de.com

Eigen, wie man die Matrix entlang einer bestimmten Dimension verkettet?

Ich habe zwei Eigenmatrizen und möchte diese verketten, wie in matlab cat(0, A, B)

Gibt es etwas Äquivalentes in Eigen?

Vielen Dank.

30
Ran

Sie können dafür die Komma-Initialisierungssyntax verwenden.

Horizontal:

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

Vertikal:

// 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

Zur besseren Lesbarkeit können vertikale Verkettungen mit Leerzeichen formatiert werden: 

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

Ich hatte einen etwas anderen Anwendungsfall: Einen std :: Vektor von Eigenmatrizen vertikal stapeln. So habe ich eine allgemeinere Funktion implementiert. Lassen Sie mich wissen, ob dies noch verbessert werden kann:

// 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;
}
1
tangy

Ich würde Eigens Blockindizierung auf ähnliche Weise wie diesen Beitrag verwenden (der sich zu einer vorhandenen Matrix verkettet).

Die Blockindizierung vermeidet die Richtungsmehrdeutigkeit in dem akzeptierten Ansatz und ist eine ziemlich kompakte Syntax. Folgendes entspricht 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;
0
thclark