Векторизация кода для вставки матрицы 2х2 по диагонали большой матрицы - PullRequest
2 голосов
/ 21 октября 2019

Я пытаюсь сделать поэлементную вставку маленькой матрицы (2x2) по диагонали большой матрицы (скажем, 10x10). Добавляются перекрывающиеся значения, а малая матрица вставляется только в том случае, если она полностью помещается внутри большой матрицы.

Я добился этого с помощью цикла for, но мне любопытно, можно ли векторизовать этот процесс.

function M = TestDiagonal()

N     = 10;
miniM = [1, -1; -1, 1];
M     = zeros(N);

for i = 1:N-1
    M(i:i+1,i:i+1) = M(i:i+1,i:i+1) + miniM;
end

end

Предоставление нужной матрицы

 1    -1     0     0     0     0     0     0     0     0
-1     2    -1     0     0     0     0     0     0     0
 0    -1     2    -1     0     0     0     0     0     0
 0     0    -1     2    -1     0     0     0     0     0
 0     0     0    -1     2    -1     0     0     0     0
 0     0     0     0    -1     2    -1     0     0     0
 0     0     0     0     0    -1     2    -1     0     0
 0     0     0     0     0     0    -1     2    -1     0
 0     0     0     0     0     0     0    -1     2    -1
 0     0     0     0     0     0     0     0    -1     1

В общемВ этом случае вход всегда будет квадратным, но может иметь любой размер. Размер шага всегда будет равен 1.

1 Ответ

3 голосов
/ 21 октября 2019

Просто используйте двумерную свертку (см. conv2).

2 × 2, шаг 1 по каждому измерению

M = conv2(eye(N-1), miniM);

m × *Случай 1010 *, шаг 1 по каждому измерению

M = conv2(eye(N-size(miniM-1)+1), miniM);

m × n случай, произвольные шаги по каждому измерению

В этом случае необходимо определить шаги:

step = [2 1]; % desired step along each dimension

и имеет больше смысла определять желаемое количество повторений R, а не конечный размер (N), потому что последнее может быть недостижимо при полных повторениях miniM:

R = 4; % desired number of repetitions

Тогда:

M = conv2(full(sparse(1:step(1):step(1)*R, 1:step(2):step(2)*R, 1)), miniM);

Пример:

>> miniM = [10 20 30; 40 50 60];
>> R = 4;
>> step = [1 2];
>> M = conv2(full(sparse(1:step(1):step(1)*R, 1:step(2):step(2)*R, 1)), miniM)
M =
    10    20    30     0     0     0     0     0     0
    40    50    70    20    30     0     0     0     0
     0     0    40    50    70    20    30     0     0
     0     0     0     0    40    50    70    20    30
     0     0     0     0     0     0    40    50    60
...