Шаги к векторизации
1] Выполнить sum(bsxfun(@times, V(:,t:end), K(:,t)),1)
для всех столбцов в V для всех столбцов в K с умножением матрицы -
sum_mults = V.'*K
Это даст нам двумерный массив с каждым столбцом, представляющим sum(bsxfun(@times,..
операцию на каждой итерации.
2] Шаг 1 дал нам все возможные суммы, а также значения, которые должны быть суммированы, не выровнены в одной и той же строке на протяжении итераций, поэтому нам нужно проделать еще немного работы перед суммированием по строкам. Остальная часть работы - получение сдвинутой версии. Для этого же вы можете использовать логическое индексирование с верхней и нижней треугольной логической маской. Наконец, мы суммируем по каждой строке для окончательного результата. Итак, эта часть кода будет выглядеть так -
valid_mask = tril(true(size(sum_mults)));
sum_mults_shifted = zeros(size(sum_mults));
sum_mults_shifted(flipud(valid_mask)) = sum_mults(valid_mask);
out = sum(sum_mults_shifted,2);
Испытания во время выполнения -
%// Inputs
V = rand(1000,1000);
K = rand(1000,200);
disp('--------------------- With original loopy approach')
tic
[M N] = size(K);
S = zeros(1, M);
for t = 1 : N
S(1,1:end-t+1) = S(1,1:end-t+1) + sum(bsxfun(@times, V(:,t:end), K(:,t)),1);
end
toc
disp('--------------------- With proposed vectorized approach')
tic
sum_mults = V.'*K; %//'
valid_mask = tril(true(size(sum_mults)));
sum_mults_shifted = zeros(size(sum_mults));
sum_mults_shifted(flipud(valid_mask)) = sum_mults(valid_mask);
out = sum(sum_mults_shifted,2);
toc
Вывод -
--------------------- With original loopy approach
Elapsed time is 2.696773 seconds.
--------------------- With proposed vectorized approach
Elapsed time is 0.044144 seconds.