2013-08-22 6 views
1

У меня есть кусок кода, здесь мне нужно упорядочить, как это значительно увеличивает время выполнения моего сценария:Как я могу векторизовать эти вложенные петли в Matlab?

size=300; 
resultLength = (size+1)^3; 
freqResult=zeros(1, resultLength); 

inc=1; 

for i=0:size, 
    for j=0:size, 
     for k=0:size, 
      freqResult(inc)=(c/2)*sqrt((i/L)^2+(j/W)^2+(k/H)^2); 
      inc=inc+1; 
     end 
    end 
end 

C, L, W, H и все константы. Поскольку размер ввода превышает 400, время выполнения слишком велико, чтобы ждать, и я могу наблюдать, как мое дисковое пространство сливается с гигабайтом. Любой совет?

Спасибо!

+0

Первое, что вы могли бы сделать, это prealocate: 'freqResult = zeros (1, size^3);' – Marcin

+0

Я забыл упомянуть, что я предопределяю эти утверждения: 'resultLength = (size + 1)^3; freqResult = zeros (resultLength, 1); 'Я думаю, что ваш заказ правилен. – jephex

ответ

0

Что об этом:

[kT, jT, iT] = ind2sub([size+1, size+1, size+1], [1:(size+1)^3]); 
for indx = 1:numel(iT) 

    i = iT(indx) - 1; 
    j = jT(indx) - 1; 
    k = kT(indx) - 1;   

    freqResult1(indx) = (c/2)*sqrt((i/L)^2+(j/W)^2+(k/H)^2); 
end 

На моем компьютере, для размера = 400, версия с 3-мя петлями принимает 136S и это один принимает 19s.

Для более «matlaby» путь у также может даже сделать следующее:

[kT, jT, iT] = ind2sub([size+1, size+1, size+1], [1:(size+1)^3]); 
func = @(i, j, k) (c/2)*sqrt((i/L)^2+(j/W)^2+(k/H)^2); 
freqResult2 = arrayfun(func, iT-1, jT-1, kT-1); 

Но по какой-то причине, это медленнее, чем в выше версии.

0

Более быстрое решение может быть (на основе ответа Marcin в):

[k, j, i] = ind2sub([size+1, size+1, size+1], [1:(size+1)^3]); 
    freqResult = (c/2)*sqrt(((i-1)/L).^2+((j-1)/W).^2+((k-1)/H).^2); 

занимает около 5 секунд, чтобы работать на моем компьютере для size = 300

Ниже еще быстрее (но это не делает выглядят очень хорошо):

k = repmat(0:size,[1 (size+1)^2]); 
    j = repmat(kron(0:size, ones(1,size+1)),[1 (size+1)]); 
    i = kron(0:size, ones(1,(size+1)^2)); 
    freqResult = (c/2)*sqrt((i/L).^2+(j/W).^2+(k/H).^2); 

который принимает ~ 3.5с для size = 300

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