Extract sparse block diagonal without loop
Show older comments
Hello, I'm interested in pulling the block diagonal out of a sparse matrix and putting each of those diagonal matrices into the depth index of a 3D matrix. I can do this in a loop easily, but would like to avoid the loop if possible.
The following is an example of what I'm trying to do completed in a loop:
A = [1 3 4 5 0 0 0 0;
6 7 8 9 0 0 0 0;
3 4 1 2 0 0 0 0;
0 0 0 0 9 9 8 7;
0 0 0 0 5 4 3 2;
0 0 0 0 1 9 7 7];
n = 2; % number of block matrices in diagonal
[R, C] = size(A);
r = R/n; % number of rows in each block matrix
c = C/n; % number of columns in each block matrix
B(r, c, n) = 0;
i = 1; j = 1; k = 1;
while i < R && j < C
B(:, :, k) = A(i:i+r-1, j:j+c-1);
i = i + r;
j = j + c;
k = k + 1;
end
Is there a way to vectorize this assignment and make it quicker/more efficient?
Thanks!
Answers (3)
Stephen
on 15 Apr 2014
Azzi Abdelmalek
on 15 Apr 2014
ii=A(A~=0);
B=reshape(ii,3,3,size(A,1)/3)
3 Comments
John D'Errico
on 15 Apr 2014
No. Sorry, but this answer presumes that the blocks are strictly non-zero. This will throw an error if any of those blocks have any zeros in them.
Stephen
on 15 Apr 2014
Brian Wessel
on 9 Jan 2020
Edited: Brian Wessel
on 9 Jan 2020
use kron to make the map of indices, then pull from your block diagonal matrix using the code above:
A = [1 3 4 5 0 0 0 0;
6 7 8 9 0 0 0 0;
3 4 1 2 0 0 0 0;
0 0 0 0 9 9 8 7;
0 0 0 0 5 4 3 2;
0 0 0 0 1 9 7 7];
blk_nrow = 3;
blk_ncol = 4;
nblks = size(A,1) / blk_nrow;
kmap = kron(eye(nblks), ones(blk_nrow,blk_ncol))
blk_list = A(kmap ~= 0);
B = reshape(blk_list,blk_nrow,blk_ncol,size(A,1)/blk_nrow)
Azzi Abdelmalek
on 15 Apr 2014
Edited: Azzi Abdelmalek
on 15 Apr 2014
r=4;
c=3;
n=100;
[nr,mc]=size(A);
jdx=repmat(1:mc,r,1);
idx=permute(reshape(repmat(1:nr,c,1),c,r,[]),[2 1 3]);
ii=sub2ind(size(A),idx(:),jdx(:));
B=reshape(A(ii),r,c,[]);
Or
[n1,m1]=size(A);
h=bsxfun(@times,ones(1,r*c),(0:n-1)')'*r;
g=bsxfun(@plus,(0:m1-1)*n1,(1:r)');
V=reshape(A(g(:)+h(:)),r,c,n);
1 Comment
Azzi Abdelmalek
on 15 Apr 2014
I think your for loop is faster
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!