# Create sparse matrix with zig-zag diagonal

4 views (last 30 days)
Florian on 3 Feb 2013
Is there a way to shift every column c by (c-1)*n rows down, where n is size(A,1) in the following example, without a loop and without excessive memory usage? So to get
A = [
a11 a12 a13 a14 ...
a21 a22 a23 a24 ...
... ... ... ... ...
]
B = [
a11 0 0 0 ...
a21 0 0 0 ...
... ... ... ... ...
0 a12 0 0 ...
0 a22 0 0 ...
... ... ... ... ...
0 0 a13 0 ...
0 0 a23 0 ...
... ... ... ... ...
0 0 0 a14 ...
0 0 0 a24 ...
... ... ... ... ...
]
I tried diag and sparse with no luck so far. I need Matrix A in an operation X=J\A afterwards. It is crucial that the zero elements do not consume memory as A can have up to 20e6 columns and probably 10 rows.

Cedric Wannaz on 3 Feb 2013
Edited: Cedric Wannaz on 3 Feb 2013
You could use sparse(), building appropriate vectors of indices and values, e.g.:
nCol = size(A, 2) ;
nRow = nCol * size(A, 1) ;
I = (1:nRow).' ;
J = reshape(repmat(1:nCol, size(A, 1), 1), [], 1) ;
B = sparse(I, J, A(:), nRow, nCol) ;
(that you can write in two lines actually, but I wanted to keep it clear)
Florian on 5 Feb 2013
Pretty cool, thank's a lot!

bym on 3 Feb 2013
s = spdiags(A',[0,-1],c*(n-1),c);
Florian on 3 Feb 2013
Unfortunately it didn't do the trick. Actually no specific value is assign to "c". In my question it was meant to be a variable to describe that the first column (c=1) should be moved (c-1)*n=0 rows down, the second column (c=2) should be moved by (c-2)*n=n rows down, the third column (c=3) should be moved (c-2)*n=2n rows down, etc.
From what I see, diags or spdiags places its elements only on true diagonals, shifted or not. In my case, however, the elements are not placed on a straight diagonal line but in a rather zig-zag way.