The one thing you NEVER, EVER, EVER want to do is stuff the elements into a sparse array iteratively. NEVER DO THAT!!!!!!!!!!!!!!! Regardless, you are doing this the wrong way anyway.
If it is only roughly 50% non-zero, then you will not be saving memory. Sparse storage has overhead, so the overhead balances out what you think you are gaining. This is perhaps the most common error people make about sparse matrices. They only think their matrices are sparse. But a new user of sparse is almost always wrong in this respect. For example...
whos A As
Name Size Bytes Class Attributes
A 2000x2000 32000000 double
As 2000x2000 32000008 double sparse
Note that both matrices are lower triangular, and lie fully below the main diagonal. But the sparse one takes exactly the same amount of memory as the full one does!
The problem is, a sparse storage requires you to also store the location of the non-zero elements. As such, you are wasting your time with sparse. It will also take more time to do many computations, because again, there is overhead with sparse.
So a simple multiply takes roughly 7x as long! Sparse storage is designed for matrices that are FAR more sparse than you have. Don't waste your time with sparse for this problem.
In terms of writing code to create the matrix itself as a FULL matrix, you will want to create a matrix of locations of the non-zeros, in terms of row indices, column indices, and values. You should be able to do this efficiently in a vectorized way. NO LOOPS NEEDED.
Then build it using one call to accumarray. SKIP SPARSE STORAGE.
For example, how would I build a sparse block lower triangular matrix? I'll make it a small one, so you can see the result. And, of course, there are surely many ways we could do this. But here is my first crack at it.
ind = tril(toeplitz((0:N-1)',0:N-1),-1);
tp = zeros(2,2) + reshape(1:N-2,[1,1,N-2])
tp =
tp(:,:,1) =
1 1
1 1
tp(:,:,2) =
2 2
2 2
tp(:,:,3) =
3 3
3 3
tp(:,:,4) =
4 4
4 4
Those blocks could be anything you wanted, but I decided to make it like this, so you could understand the result.
[R2,C2] = find(ones(2,2));
rowindices = R2 - 2 + rowoffset*R';
columnindices = C2 - 2 + columnoffset*C';
A = accumarray([rowindices(:),columnindices(:)],values(:),[2*N,2*N])
A =
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 0 0 0 0 0 0
0 0 1 1 0 0 0 0 0 0 0 0
0 0 2 2 1 1 0 0 0 0 0 0
0 0 2 2 1 1 0 0 0 0 0 0
0 0 3 3 2 2 1 1 0 0 0 0
0 0 3 3 2 2 1 1 0 0 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
As you can see, the result has the desired pattern, with no loops required. It is efficiently done. And forget about sparse for this. really.