Sparse Block diagonal matrix

86 views (last 30 days)
David on 19 Aug 2012
Answered: Daniel Fortunato on 21 Apr 2022
I have an N by M matrix and I want to store its columns in block diagonal form. This matrix is enormous, so if I can directly store it as a sparse matrix that would be helpful.
To give more detail:
X = ones(30, 1000);
And I want this without having to type it out (because the matrix actually has 1 million columns).
sparse(blkdiag(X(:,1), X(:,2), X(:,3), .... , X(:,1000)).
By the way, my best attempt is this:
a = cell(M,1);
for i = 1:M
[a{i}]= deal(sparse(X(:,i)));
But I'm using a loop and am worried this is inefficient.

Accepted Answer

Oleg Komarov
Oleg Komarov on 19 Aug 2012
Edited: Oleg Komarov on 19 Aug 2012
The easy way:
X = num2cell(X,1);
Or, creating the sparse matrix directly:
[r,c] = size(X);
i = 1:numel(X);
j = repmat(1:c,r,1);
B = sparse(i',j(:),X(:));
The second method is not only ~30-40 times faster but avoids creating the intermediate blkdiag() double matrix, which can easily cause out of memory.
Honestly, I don't know if you have that kind of memory:
(30 * 1e6) rows * 1e6 cols * 8 bytes ~ 218.2 TB
Therefore, go for the second method.

More Answers (2)

Alec on 18 Jul 2014
Or, if you can, call `sparse` before `blkdiag`:
X = ones(30, 1000);
X = num2cell(sparse(X),1);
B = blkdiag(X{:});

Daniel Fortunato
Daniel Fortunato on 21 Apr 2022
You can also use MATLAB's internal sparse block-diagonal routine, which will create a sparse block-diagonal matrix even from dense blocks:
B = matlab.internal.math.blkdiag(X{:});


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!

Translated by