Матрица сдвига матрицы Matlab

Есть ли встроенная команда для создания сдвинутой матрицы идентичности в 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, 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]

комбинация circshift и eye хороша, однако для ее исправления требуется другая команда. Любой более простой способ? (всего один простой синтаксис)

Ответ 1

Попробуйте использовать diag вызов в сочетании с ones. Для вашего случая у вас есть десятичная матрица 10 x 10 и вы хотите сдвинуть диагональ вправо на 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

Вышеприведенный код работает, сначала объявляя вектор-столбец всех 1s, но нам понадобится n-abs(shift) из них, поскольку перемещение вправо означает, что нам потребуется меньше 1s для заполнения вещей (подробнее об этом позже). n-abs(shift) также соответствует общему количеству строк/столбцов вашей матрицы и вычитанию столько раз, сколько вы смещаете вправо. Затем вы можете использовать diag, где первый параметр представляет собой вектор-столбец, который создает матрицу нуль и помещает вектор-столбец в виде коэффициентов вдоль диагонали этой матрицы. Второй параметр (shift в вашем случае) позволяет offset разместить этот столбец. Указание положительного значения означает перемещение диагоналей вправо, и в нашем случае мы перемещаем это направо на shift, и, следовательно, результат нашего вывода. Поскольку вы по существу усекаете вектор для каждой позиции вправо, вы двигаетесь, вам нужно будет уменьшить количество единиц в вашем векторе.

До сих пор я не объяснял, почему вызов abs для shift требуется в последней строке кода. Причина, по которой требуется вызов abs, - это размещение негативных сдвигов. Если бы мы не имели вызов abs в третьей строке кода, n-shift по существу был бы добавив больше 1s к вектору и таким образом расширил нашу матрицу за пределами n x n. Поскольку перемещение диагоналей влево также уменьшает количество видимых в результате 1s, то почему вызов abs требуется, но вы заметите, что константа shift остается нетронутой во втором параметре diag.

Здесь демонстрация с отрицательным сдвигом, shift = -1 и по-прежнему поддерживающая размер 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

Ответ 2

Вы можете получить желаемый результат с помощью одного вызова bsxfun -

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

Поскольку вы в основном создаете разреженную матрицу, вы также можете использовать sparse -

n = 10
shift = 1
A = full(sparse(1:n-shift,1+shift:n,1,n,n))

Ответ 3

поздно в этой игре, но не будем забывать простейшее решение, используя линейную индексацию:

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

очевидно, что просто решает случай сдвига = 1, но вы получаете точку...

Ответ 4

Вы можете использовать circshift и исправить матрицу, прежде чем передавать ее функции:

>> 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 будет 0 для fist shift количества мест и 1 для остальных.

Ответ 5

Вот еще одна альтернатива: (немного похожа на bsxfun Подход Divakar)

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

Это также может быть однострочный:

out = repmat((1:n).',1,n,1) == repmat(1-shift:n-shift,n,1,1)

Ответ 6

Вот еще один (также работает с отрицательными сдвигами)

rot90(blkdiag(zeros(abs(shift)),rot90(eye(n))),sign(shift))