MATLAB: Creation of a block-diagonal sparse matrix

block diagonalsparse

I would like to create a block-diagonal matrix with the following properties:
  • The matrix must consist of submatrices A1, A2, … on the diagonal and zeroes elsewhere.
  • Each submatrix will be square, but dimensions vary.
  • Each n-by-n submatrix takes the following shape:
eye(n) - ones(1/n)
  • Since there are many such submatrices, the overall matrix must be sparse.
What I have is a vector which holds the dimensions of each submatrix. So, if the vector is, say, b=[1,5,3,…], then the first submatrix A1 would have to be 1-by-1, A2 is 5-by-5, A3 is 3-by-3, and so on. How do I go from there to the creation of my matrix?
Two answers were given on a related quation. The first, based upon blkdiag, won't work, because it would involve temporarily creating the full matrix, and I run out of memory. The second seems preferable, but I can't wrap my head around how to adopt it to my setting.

Best Answer

The first, based upon blkdiag, won't work, because it would involve temporarily creating the full matrix, and I run out of memory.
BLKDIAG will give you a sparse result if you first convert its inputs to sparse type, like below,
>> A=sparse(ones(3)); B=sparse(ones(2)); C=blkdiag(A,B)
C =
(1,1) 1
(2,1) 1
(3,1) 1
(1,2) 1
(2,2) 1
(3,2) 1
(1,3) 1
(2,3) 1
(3,3) 1
(4,4) 1
(5,4) 1
(4,5) 1
(5,5) 1
>> full(C)
ans =
1 1 1 0 0
1 1 1 0 0
1 1 1 0 0
0 0 0 1 1
0 0 0 1 1