繁体   English   中英

级联稀疏矩阵本征

[英]Concatenate sparse matrix Eigen

我在Eigen中有两个稀疏矩阵,我想将它们垂直合并为一个。 例如,代码的目标是:

SparseMatrix<double> matrix1;
matrix1.resize(10, 10);
SparseMatrix<double> matrix2;
matrix2.resize(5, 10);

SparseMatrix<double> MATRIX_JOIN;
MATRIX_JOIN.resize(15, 10);
MATRIX_JOIN << matrix1, matrix2;

我在一个论坛上找到了一些解决方案,但是我无法实现它。

垂直连接矩阵的正确方法是什么?

编辑

我的实现:

SparseMatrix<double> L;
SparseMatrix<double> C;
// ... (Operations with the matrices)
SparseMatrix<double> EMATRIX;
EMATRIX.resize(L.rows() + C.rows(), L.cols());
EMATRIX.middleRows(0, L.rows()) = L;
EMATRIX.middleRows(L.rows(), C.rows()) = C;

我收到类型错误,根据编译器,右侧为Eigen :: Block,左侧为Eigen :: SparseMatrix

据我所知,目前尚无内置解决方案。 通过使用内部insertBack函数,您可以比解决方案更有效:

SparseMatrix<double> M(L.rows() + C.rows(), L.cols());
M.reserve(L.nonZeros() + C.nonZeros());
for(Index c=0; c<L.cols(); ++c)
{
    M.startVec(c); // Important: Must be called once for each column before inserting!
    for(SparseMatrix<double>::InnerIterator itL(L, c); itL; ++itL)
         M.insertBack(itL.row(), c) = itL.value();
    for(SparseMatrix<double>::InnerIterator itC(C, c); itC; ++itC)
         M.insertBack(itC.row()+L.rows(), c) = itC.value();
}
M.finalize();

我最终做了以下工作:

MATRIX_JOIN.resize(matrix1.rows() + matrix2.rows(), matrix1.cols() + matrix2.cols());
MATRIX_JOIN.setZero();

// Fill MATRIX_JOIN with triples from the other matrices
std::vector<Triplet<double> > tripletList;
for (int k = 0; k < matrix1.outerSize(); ++k)
{
    for (SparseMatrix<double>::InnerIterator it(matrix1, k); it; ++it)
    {
        tripletList.push_back(Triplet<double>(it.row(), it.col(), it.value()));
    }
}
for (int k = 0; k < matrix2.outerSize(); ++k)
{
    for (SparseMatrix<double>::InnerIterator it(matrix2, k); it; ++it)
    {
        tripletList.push_back(Triplet<double>(it.row(), it.col(), it.value()));
    }
}
FINALMATRIX.setFromTriplets(tripletList.begin(), tripletList.end());

通过调用tripleList.reserve(X)可以tripleList.reserve(X)速度,其中X是要插入的三元组的预期数量。

基于@Javier的答案。

  • 修复了输出矩阵中的列数(只是cols而不是cols+cols
  • 修复了下层upper.rows() + it.row()的三元组索引( upper.rows() + it.row()而不是it.row()

using sparse_matrix_type = Eigen::SparseMatrix<T>;
using triplet_type = Eigen::Triplet<T, size_t>;

static sparse_matrix_type sparse_vstack(sparse_matrix_type const& upper, sparse_matrix_type const& lower) {
  assert(upper.cols() == lower.cols() && "vstack with mismatching number of columns");

  std::vector<triplet_type> triplets;
  triplets.reserve(upper.nonZeros() + lower.nonZeros());

  for (int k = 0; k < upper.outerSize(); ++k) {
    for (sparse_matrix_type::InnerIterator it(upper, k); it; ++it) {
      triplets.emplace_back(it.row(), it.col(), it.value());
    }
  }

  for (int k = 0; k < lower.outerSize(); ++k) {
    for (sparse_matrix_type::InnerIterator it(lower, k); it; ++it) {
      triplets.emplace_back(upper.rows() + it.row(), it.col(), it.value());
    }
  }

  sparse_matrix_type result(lower.rows() + upper.rows(), upper.cols());
  result.setFromTriplets(triplets.begin(), triplets.end());
  return result;
}

不幸的是,由于静态断言错误THIS_SPARSE_BLOCK_SUBEXPRESSION_IS_READ_ONLY我无法使用@chtz的示例与Eigen 3.3.4一起工作。 Eigen似乎已明确禁止使用它(请参阅https://eigen.tuxfamily.org/dox/SparseBlock_8h_source.html )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM