Я думаю, вам может понадобиться переставить C в трехмерную матрицу, прежде чем суммировать ее по одному из измерений. Я отправлю с ответом в ближайшее время.
EDIT
Мне не удалось найти способ аккуратно векторизовать его, но я нашел функцию accumarray
, которая могла бы помочь. Я посмотрю на это более подробно, когда буду дома.
EDIT # 2
Нашли более простое решение с помощью линейного индексирования, но это может потребовать много памяти.
При C (1,1) индексы, которые мы хотим суммировать, составляют 1+ [0, m + 1, 2 * m + 2, 3 * m + 3, 4 * m + 4, ...], или (0: r-1) + (0: m: (r-1) * m)
sum_ind = (0:r-1)+(0:m:(r-1)*m);
создать S_offset
, (mr) по (nr) по r матрице, так что S_offset (:,:, 1) = 0, S_offset (:,:, 2) = m + 1, S_offset (:, :, 3) = 2 * m + 2 и т. Д.
S_offset = permute(repmat( sum_ind, [m-r, 1, n-r] ), [1, 3, 2]);
create S_base
, матрица адресов базового массива, из которой будет рассчитываться смещение.
S_base = reshape(1:m*n,[m n]);
S_base = repmat(S_base(1:m-r,1:n-r), [1, 1, r]);
Наконец, используйте S_base+S_offset
для адресации значений C.
S = sum(C(S_base+S_offset), 3);
Конечно, вы можете использовать bsxfun
и другие методы, чтобы сделать его более эффективным; здесь я решил выложить это для ясности. Мне еще предстоит сравнить это с тем, чтобы сравнить его с методом двойной петли; Мне нужно сначала пойти домой на ужин!