-1
for i = 1:N 
    for j = 1:M 
     for c = 1:3 
      A(:,:,c,i) = A(:,:,c,i).*B(:,:,j); 
     end 
    end 
end 

Можно ли, например, устранить самую внутреннюю петлю путем векторизации?Как ускорить это умножение массива?

+3

Правильно ли ваш код? Цикл 'j' бесполезен, выживает только значение' j = M'. С вашим кодом в его нынешнем виде вы можете удалить второй цикл и просто установить 'j = M;' –

+0

О, цикл 'j' в порядке, имена переменных были неправильными, и я исправил его сейчас, спасибо. –

+0

Такая же проблема. Только 'j = M' действительно используется! Результаты других значений 'j': _overwritten_ –

ответ

1

Сначала вы можете устранить петлю над J путем предварительного умножения матрицы:

B2 = prod(B, 3); % Element-wise product along third dim 

for i = 1:N 
    for c = 1:3 
     A(:,:,c,i) = A(:,:,c,i) .* B2; 
    end 
end 

Затем вы можете использовать repmat для плитки Матричный B2 и устранять другие две петли. У меня есть некоторые трудности обертывание мою голову вокруг 4D-матриц,, но это должно выглядеть следующим образом:

B2 = prod(B, 3); % Element-wise product along third dim 
B3 = repmat(B2, [1 1 3 N]); 
A = A .* B3; 

или (еще лучше) использовать bsxfun:

B2 = prod(B, 3); % Element-wise product along third dim 
A = bsxfun(@times, A, B2); 

bsxfun будет использовать меньше памяти, потому что «практически реплицирует "B2.

+0

Ну, это не то же самое, если бы« B2 »находился внутри цикла« i »и выглядел так:« B2 = prod (B (:,:, i-1), 3), что должно ускорить программу, спасибо за это, но теперь, как я могу использовать repmat для этого? –

+0

@ ĬnfernalSeraphím: Помимо ошибок точности с плавающей запятой, выход такой же. На математическом уровне код делает то же самое. – Daniel

+3

Я бы использовал 'A = bsxfun (@ times, A, B2);' вместо 'repmat' – Daniel

Смежные вопросы