web-dev-qa-db-ja.com

Eigen特定の次元に沿って行列を連結する方法は?

Matlab cat(0, A, B)のように、2つの固有行列があり、それらを連結したい

固有値に同等のものはありますか?

ありがとう。

36
Ran

そのために、コンマ初期化構文を使用できます。

水平方向:

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

垂直方向:

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

読みやすくするために、垂直連結を空白でフォーマットする場合があります。

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

私はわずかに異なるユースケースがありました:Eigen行列のstd :: vectorを垂直に積み重ねる。以下は、より一般的な目的の関数を実装した方法です。これをさらに改善できるかどうか教えてください:

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

this post (既存のマトリックスに連結する)と同様の方法で Eigenのブロックインデックス を使用します。

ブロックのインデックス付けは、受け入れられているアプローチの方向のあいまいさを回避し、かなりコンパクトな構文です。以下は、MATLABのC = cat(2, A, B)と同等です。

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