Векторизация тройной петли - MATLAB

У меня есть следующий большой, очень неэффективный цикл.

P is a [2000 x 200 x 5] matrix
D is a [2000 x 200 x 5] matrix
S is a [200 x 1005] matrix
PS is a [2000 x 1000 x 5] matrix

Я хочу вычислить следующий цикл:

for k=1:2000
   for n=1:200
      for t=1:5
          P(k,n,t) = sum(S(n,t+1:t+1000) .* PS(k,1:1000,t));
      end
   end
end

Очевидно, это очень неэффективно. Я старался parfor, но я бы предпочел векторизованное решение. Я попробовал пару вещей с bsxfunНо так и не удалось заставить его работать.

Спасибо.

1 ответ

Решение

Вот почти (почти потому что у нас все еще есть цикл, но только с 5 итерациями) векторизованный подход с использованием powerful matrix-multiplication -

out = zeros(2000,200,5);
for t=1:size(P,3) %// size(P,3) = 5
    out(:,:,t) = PS(:,:,t)*S(:,t+1:t+1000).';
end

Испытания во время выполнения и проверка вывода -

%// Inputs
D = rand(2000,200,5);
S = rand(200,1005);
PS = rand(2000,1000,5);

disp('--------------------- No Matrix-mult-fun')
tic
P = zeros(2000,200,5);
for k=1:2000
   for n=1:200
      for t=1:5
          P(k,n,t) = sum(S(n,t+1:t+1000) .* PS(k,1:1000,t));
      end
   end
end
toc

disp('--------------------- Fun fun Matrix-mult-fun')
tic
out = zeros(2000,200,5);
for t=1:size(P,3) %// size(P,3) = 5
    out(:,:,t) = PS(:,:,t)*S(:,t+1:t+1000).';
end
toc

error_val = max(abs(P(:)-out(:)))

Выход -

--------------------- No Matrix-mult-fun
Elapsed time is 70.223008 seconds.
--------------------- Fun fun Matrix-mult-fun
Elapsed time is 0.624308 seconds.
error_val =
     1.08e-12
Другие вопросы по тегам