Search code examples
matlabmatrixvectordiagonal

Creating a non-square diagonal matrix from a vector


I have a vector and I would like to have it repeated n-times forward and n-times backwards, but diagonally.

For example, I have the vector:
x= [0 0 1 1 0 0],

and would want a matrix of size 6x5 as follows:

1 0 0 0 0
1 1 0 0 0
0 1 1 0 0
0 0 1 1 0
0 0 0 1 1
0 0 0 0 1

This means that the vector [0 0 1 1 0 0] (transposed) is placed in the middle, and I would like a matrix such that when moving to the left, the elements are circularly shifted over to the top for each shift you make to the left. Similarly, when moving to the right, the elements are circularly shifted down to the bottom for each shift you make to the right. Therefore, the second column would be [0 1 1 0 0 0] where the elements are shifted to the left in a circular fashion once, then the first column would be [1 1 0 0 0 0] where we shift all elements to the left twice with respect to the middle and once with respect to the second column.

Similarly, the fourth column would be [0 0 0 1 1 0] meaning that with respect to the middle column, we shift all elements in a circular fashion to the right once, then the last column would be [0 0 0 0 1 1] where we shift all elements to the right twice with respect to the middle and once with respect to the fourth column.


Solution

  • If the vector always consists of a nonzero part in the middle, you can use convmtx (from the Signal Processing Toolbox) as follows:

    y = convmtx(nonzeros(x), numel(x)-1);
    

    Or, if you don't have the Signal Processing Toolbox, use conv2:

    y = conv2(eye(numel(x)-1), nonzeros(x)):
    

    For x = [0 0 1 1 0 0], either of the above produces:

    y =
         1     0     0     0     0
         1     1     0     0     0
         0     1     1     0     0
         0     0     1     1     0
         0     0     0     1     1
         0     0     0     0     1