Matlab identity shift matrix

前端 未结 6 1211
长发绾君心
长发绾君心 2020-12-17 18:38

Is there any inline command to generate shifted identity matrix in MATLAB?

A=[ ...
0, 1, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 1, 0, 0         


        
相关标签:
6条回答
  • 2020-12-17 19:25

    Here is another one (also works with negative shifts)

    rot90(blkdiag(zeros(abs(shift)),rot90(eye(n))),sign(shift))
    
    0 讨论(0)
  • 2020-12-17 19:26

    You can get the desired output with a single call to bsxfun -

    n = 10
    shift = 1
    A = bsxfun(@eq,[1:n].',1-shift:n-shift)
    

    Since you are basically creating a sparse matrix, alternatively you can use sparse -

    n = 10
    shift = 1
    A = full(sparse(1:n-shift,1+shift:n,1,n,n))
    
    0 讨论(0)
  • 2020-12-17 19:27

    Here is Another Alternative: (little similar to bsxfun Approach by Divakar)

    n=10;
    shift = 1;
    c = repmat(1-shift:n-shift,n,1,1);
    r = repmat((1:n).',1,n,1);
    out = r == c
    

    This could also be a one-liner:

    out = repmat((1:n).',1,n,1) == repmat(1-shift:n-shift,n,1,1)
    
    0 讨论(0)
  • 2020-12-17 19:30

    Try using a diag call in combination with ones. For your case, you have a 10 x 10 identity matrix and want to shift the diagonal to the right by 1.

    >> n = 10;
    >> shift = 1;
    >> A = diag(ones(n-abs(shift),1),shift)
    
    A = 
    
       0     1     0     0     0     0     0     0     0     0
       0     0     1     0     0     0     0     0     0     0
       0     0     0     1     0     0     0     0     0     0
       0     0     0     0     1     0     0     0     0     0
       0     0     0     0     0     1     0     0     0     0
       0     0     0     0     0     0     1     0     0     0
       0     0     0     0     0     0     0     1     0     0
       0     0     0     0     0     0     0     0     1     0
       0     0     0     0     0     0     0     0     0     1
       0     0     0     0     0     0     0     0     0     0
    

    The above code works by first declaring a column vector of all 1s, but we would need n-abs(shift) of them as moving to the right would mean that we would require less 1s to fill things up (more on this later). n-abs(shift) also corresponds to the total number of rows/columns of your matrix and subtracting out as many times you are shifting towards the right. Next, you can use diag where the first parameter is a column vector which creates a zero matrix and places the column vector as coefficients along the diagonal of this matrix. The second parameter (shift in your case) allows you to offset where to place this column. Specifying a positive value means to move the diagonals towards the right, and in our case we are moving this to the right by shift, and hence our output results. As you are essentially truncating the vector for each position towards the right you are moving, you would need to decrease the number of 1s in your vector by this much.

    Up to now, I haven't explained why the abs call to shift is required in the last line of code. The reason why the abs call is required is to accommodate for negative shifts. If we didn't have the abs call in the third line of code, n-shift would essentially be adding more 1s to the vector and would thus expand our matrix beyond n x n. Because moving the diagonals to the left also decreases the amount of 1s seen in the result, that's why the abs call is required but you'll notice that the shift constant is left untouched in the second parameter of diag.

    Here's a demonstration with a negative shift, shift = -1, and still maintaining the size to be 10 x 10:

    A =
    
         0     0     0     0     0     0     0     0     0     0
         1     0     0     0     0     0     0     0     0     0
         0     1     0     0     0     0     0     0     0     0
         0     0     1     0     0     0     0     0     0     0
         0     0     0     1     0     0     0     0     0     0
         0     0     0     0     1     0     0     0     0     0
         0     0     0     0     0     1     0     0     0     0
         0     0     0     0     0     0     1     0     0     0
         0     0     0     0     0     0     0     1     0     0
         0     0     0     0     0     0     0     0     1     0
    
    0 讨论(0)
  • 2020-12-17 19:30

    way late in this game but let us not forget the simplest solution using linear indexing:

    n=10; a=zeros(n);
    a(n+1:n+1:end)=1
    

    obviously, that just solves the shift=1 case, but you get the point...

    0 讨论(0)
  • 2020-12-17 19:30

    You can use circshift and fix the matrix before passing it to the function:

    >> shift = 1;
    >> N=10;
    >> A=circshift(diag(1:N>shift),-shift)
    A =
         0     1     0     0     0     0     0     0     0     0
         0     0     1     0     0     0     0     0     0     0
         0     0     0     1     0     0     0     0     0     0
         0     0     0     0     1     0     0     0     0     0
         0     0     0     0     0     1     0     0     0     0
         0     0     0     0     0     0     1     0     0     0
         0     0     0     0     0     0     0     1     0     0
         0     0     0     0     0     0     0     0     1     0
         0     0     0     0     0     0     0     0     0     1
         0     0     0     0     0     0     0     0     0     0
    

    1:N>shift will be 0 for fist shift number of places and 1 for the remaining.

    0 讨论(0)
提交回复
热议问题