Extract sparse block diagonal without loop

4 visualizzazioni (ultimi 30 giorni)
Stephen
Stephen il 15 Apr 2014
Modificato: Brian Wessel il 9 Gen 2020
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!

Risposte (3)

Stephen
Stephen il 15 Apr 2014
A slightly more simple (and convoluted) loop for doing the same thing:
ind = [1, 1]; % [i, j]
for k = 1:n
B(:, :, k) = A( ind(1):ind(1) + r - 1, ind(2):ind(2) + c - 1 );
ind = [ind(1) + r, ind(2) + c];
end
Help me dump this loop!

Azzi Abdelmalek
Azzi Abdelmalek il 15 Apr 2014
ii=A(A~=0);
B=reshape(ii,3,3,size(A,1)/3)
  3 Commenti
Stephen
Stephen il 15 Apr 2014
John, that's what I was thinking as well. Otherwise I believe it would work. Thanks for your input Azzi.
Brian Wessel
Brian Wessel il 9 Gen 2020
Modificato: Brian Wessel il 9 Gen 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)

Accedi per commentare.


Azzi Abdelmalek
Azzi Abdelmalek il 15 Apr 2014
Modificato: Azzi Abdelmalek il 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);

Categorie

Scopri di più su Creating and Concatenating Matrices in Help Center e File Exchange

Prodotti

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by