Eigen如何沿特定维度拼接矩阵?

53

我有两个特征矩阵,我想将它们连接起来,就像在 matlab 中一样 cat(0, A, B)

在 eigen 中是否有类似的功能?

谢谢。


那段 Matlab 代码无法运行。 - debo
3个回答

81
你可以使用逗号初始化语法来实现这个目的。
水平方向上:
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. 

3
Eigen如何确定是竖直连接还是水平连接矩阵?是基于输出矩阵的大小吗? - Sobi
20
没错,你猜对了。(这并不基于代码格式!) - ggael
暂时不支持稀疏矩阵。 - ggael
@ggael 我认为这种“猜测”并不是很直观。它不是很明确,而且还需要相当多的“信任”,以确保它真正做了“正确的事情”。处理这个问题更加明确不是更好吗?(可以像numpy的concatenate/hstack/vstack一样,或者用逗号初始化器,我不介意,尽管numpy的方式在许多矩阵库中都被使用)。 - Ela782
1
如果 A.rows() == A.cols()+B.cols(),即当矩阵可以水平或垂直堆叠时(如果允许转置),则矩阵不会被转置。因此,将 3 个 Vector3d 堆叠在一起将使它们垂直堆叠,因为向量是 Eigen 中的单列矩阵。将正方形数量的正方形矩阵堆叠的顺序与使用运算符 << 插入矩阵元素的顺序相同,即从上到下,从左到右。 - Gabriel Devillers
逗号初始化程序中没有隐式转置,如果大小不匹配或元素过多或过少,则会触发断言。hstack/vstack 涵盖的用法略有不同于逗号初始化程序,我认为这将是一个受欢迎的功能。如果我没记错的话,某个地方悬挂着一些概念验证代码... - ggael

8

我会使用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;

7

我有一个稍微不同的用例:将一个std::vector的Eigen矩阵垂直堆叠。以下是我实现的一个更通用的函数。如果这可以进一步改进,请告诉我:

// 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
感谢您提供的动态解决方案,因为矩阵数量事先未知。但是,请注意STL容器(即向量)和Eigen https://eigen.tuxfamily.org/dox/group__TopicStlContainers.html。 - DomTomCat
好的,感谢您提供的解决方案。这可以作为一个功能请求! - Samuel Rodríguez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接