Vectorisation of code for insertion of 2x2 matrix along the diagonal of a large matrix

我与影子孤独终老i 提交于 2020-02-02 12:22:17

问题


I am trying to do an elementwise insertion of a small matrix (2x2) along the diagonal of a large matrix (10x10 say). Overlapping values are added, and the small matrix is only inserted where it can fit fully inside the large matrix.

I have achieved this using a for loop, but am curious whether the process can be vectorised.

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

Giving the desired matrix

 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

In the general case, the input will always be square, but can take any size. The step dimension will always be equal to 1.


回答1:


Just use 2D convolution (see conv2).

2×2 case, step 1 along each dimension

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

m×m case, step 1 along each dimension

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

m×n case, arbitrary steps along each dimension

In this case the steps need to be defined:

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

and it makes more sense to define a desired number of repetitions R, rather than the final size (N), because the latter may not be achievable with full repetitions of miniM:

R = 4; % desired number of repetitions

Then:

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

Example:

>> 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


来源:https://stackoverflow.com/questions/58484566/vectorisation-of-code-for-insertion-of-2x2-matrix-along-the-diagonal-of-a-large

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!