Eigen库:如何从已有的稀疏矩阵创建一个块对角稀疏矩阵?

3

我有一堆大小为(n*n)的稀疏矩阵,它们分别称为M1、M2... Mj。

我想要创建一个大的块对角稀疏矩阵,它看起来像这样:

    |M1 0  0 . . . |
    |0  M2 0 . . . |
    |.  .  . . . . |
    |.  .  . Mj-1 0|
    |0  0  0 ... Mj|

我尝试了以下操作:
    Eigen::SparseMatrix<double> MatBLK(j*n,j*n);
    MatBLK.reserve(Eigen::VectorXd::Constant(j*n,3); 
    //I know that there are at most 3 nonzero elements per row

    MatBLK.topLeftCorner(n,n) = M1.topLeftCorner(n,n);
    MatBLK.block(n,n,n,n) = M2.topLeftCorner(n,n);
    .
    .
    MatBLK(bottomRightCorner(n,n)) = Mj.topLeftCorner(n,n);
    MatBLK.makeCompressed();

这种方法不起作用。较小矩阵中的值未复制到较大的块矩阵中。该函数:

    MatBLK.nonZeros() 

返回0。

我是新手,对这个库不太熟悉。任何帮助将不胜感激。


它甚至无法编译通过。我认为一个稀疏的“块”不能在“=”的左侧。 - Avi Ginsburg
1个回答

4
很遗憾,由于结果代码效率低下的原因,似乎不能以那种方式分配稀疏矩阵。这个论坛帖子已经有近2年的历史了,但似乎情况仍然如此(https://forum.kde.org/viewtopic.php?f=74&t=112018)。
您必须逐个分配条目,可以使用直接赋值或三元组。
A.block(i,j,m,n) = B;

变成

for (int ii = i; ii < i+m; ++ii) {
  for (int jj = j; jj < j+n; ++jj) {
    // direct assignment 
    A.insert(ii, jj) = B(ii - i, jj - j);

    // triplets
    triplets.push_back(Triplet(ii, jj, B(ii-i,jj-j)));
  }
}

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