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
Here is another one (also works with negative shifts)
rot90(blkdiag(zeros(abs(shift)),rot90(eye(n))),sign(shift))
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))
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)
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
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...
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.