Reputation: 41
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.
Upvotes: 3
Views: 2789
Reputation: 3052
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)));
}
}
Upvotes: 4