简体   繁体   中英

Eigen Library:: How do I create a block diagonal sparse matrix out of existing sparse matrices?

I have a bunch of (n*n) sized sparse matrices called M1, M2... , Mj.

I want to create a large block-diagonal sparse matrix that looks like this:

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

I tried the following:

    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();

This method is not working. The values in the smaller matrices aren't getting copied to the larger Block Matrix. The function:

    MatBLK.nonZeros() 

returns 0.

I am new to this library. Any help would be greatly appreciated.

Unfortunately it looks like you can't assign sparse matrices in that way due to how inefficient the resulting code would be. This forum post is almost 2 years old but it seems things are still the same ( https://forum.kde.org/viewtopic.php?f=74&t=112018 )

You have to assign entries one by one, either with direct assignment or triplets.

A.block(i,j,m,n) = B;

becomes

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)));
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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