Sliding window summation of a matrix
Problem #1
The most Matlab-like way for doing this I can think of is two-dimensional convolution (conv2
) (as I now see was commented by @rahnema1):
M = randi(9, 5, 5); % input: square matrix, arbitrary size
N = 3; % block size, assumed square, not larger than M
result = conv2(M, ones(N), 'valid');
Equivalently, you can use the recently introduced movsum
function, twice (once for each dimension):
result = movsum(movsum(M, N, 1, 'Endpoints', 'discard'), N, 2, 'Endpoints', 'discard');
Example:
M =
4 4 3 1 2
2 8 7 1 6
3 6 7 5 5
6 5 4 8 1
5 9 6 9 4
result =
44 42 37
48 51 44
51 59 49
Problem #2
The simplest way (not the most efficient one) is to use convolution again with a logical matrix containing true
at the desired position and false
otherwise, and checking where the convolution is not zero:
in_coords = [3 4]; % example input coordinates
T = false(size(M)); % initiallize matrix containing false, same size as M
T(in_coords(1), in_coords(2)) = true; % true at the desired coordinates
C = conv2(T, ones(N), 'valid'); % this gives 1 for blocks affected by in_coords
[ii, jj] = find(C); % row and column indices of nonzero values
out_coords = [ii jj]; % build result
In this example,
out_coords =
1 2
2 2
3 2
1 3
2 3
3 3