How to create a block diagonal matrix from the slices of a 3D matrix

22 views (last 30 days)
I have a large 3D matrix (K) composed of 200 slices , and I want to create a block diagonal matrix from the slices of it without looping. For example
K(:,:,1) =[1 2;3 4]
K(:,:,2) =[5 6;7 8]
K(:,:,3) =[9 10;11 12]
.
.
.
K(:,:,200) =[1 10;13 15]
if we assume the number of slice is 3, the output should be
1 2 0 0 0 0
3 4 0 0 0 0
0 0 5 6 0 0
0 0 7 8 0 0
0 0 0 0 9 10
0 0 0 0 11 12
But how the block diagonal matrix created from all the 200 slices without looping?

Accepted Answer

Azzi Abdelmalek
Azzi Abdelmalek on 2 Oct 2014
k(:,:,1) =[1 2;3 4]
k(:,:,2) =[5 6;7 8]
k(:,:,3) =[9 10;11 12]
q=num2cell(k,[1,2])
blkdiag(q{:})
  4 Comments
Azzi Abdelmalek
Azzi Abdelmalek on 2 Oct 2014

هذه إحدى التقنيات تعلمتها في هذا المنتدى

Matt J
Matt J on 2 Oct 2014
Note that this still uses a for-loop inside num2cell.m, though how much that hurts you, I don't know.
Note also that my 2nd answer here was the same as this, except that it returns the result in sparse form, which is normally more desirable for block diagonal matrices with small blocks.

Sign in to comment.

More Answers (3)

Matt J
Matt J on 2 Oct 2014
Edited: Matt J on 2 Oct 2014
I doubt that avoiding loops leads to the fastest code, but the following does avoid them,
[m,n,p]=size(K);
BlockMatrix=kron(speye(p), ones(m,n));
BlockMatrix(logical(BlockMatrix))=K(:);

Matt J
Matt J on 2 Oct 2014
Edited: Matt J on 2 Oct 2014
This doesn't avoid a loop, even if it looks like it does, but it might be the fastest way.
Kcell = cellfun(@sparse, num2cell(K,[1,2]), 'uni',0 );
BlockMatrix=blkdiag(Kcell{:});

Azzi Abdelmalek
Azzi Abdelmalek on 2 Oct 2014
k(:,:,1) =[1 2;3 4]
k(:,:,2) =[5 6;7 8]
k(:,:,3) =[9 10;11 12]
out=[];
for ii=1:size(k,3)
out=blkdiag(out,k(:,:,ii))
end

Categories

Find more on Operating on Diagonal Matrices in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!