matlab에 중첩 루프를 작성하면 언제든지 내장 된 벡터화 된 함수 형식을 사용하여 속도를 높일 수 있습니다. 코드는 일반적으로 너무 짧게 끝나기도합니다 (그러나 독자에게는 덜 분명해지기 때문에 코드에 주석을 달아보십시오!).
이 경우 중첩 루프를 피하는 것이 효과가 있습니까? 전혀! 일하러 가자. @slayton은 3 루프 솔루션을 제공합니다. 우리는 더 빨리 갈 수 있습니다.
B
은 51 9x100
개의 행렬을 가지고 K
은 34 9x100
개의 행렬을 가지고 있습니다. 51x34
의 각 조합에 대해 행렬을 B
및 K
에서 요소 단위로 곱하려고합니다.
요소 현명한 곱셈 bsxfun
을위한 좋은 일이다, 그래서 우리는 개념적으로 두 가지 차원 (B
의 세 번째 차원, K
의 첫 번째 차원)에 따라 작업에이 문제를 줄일 수
초기, 두 개의 루프 솔루션 :
B = rand(9,100,51);
K = rand(34,9,100);
G = nan(34,9,100,51);
for b=1:size(B,3)
for k=1:size(K,1)
G(k,:,:,b) = bsxfun(@times,B(:,:,b), squeeze(K(k,:,:)));
end
end
두 개의 루프가 진행 중입니다. 더 잘할 수 있을까요? 자, 행렬 B
과 K
이 적절한 차원을 따라 복제 될 수 있고 요소 단위로 한번에 곱해질 수 있다는 것을 알아 봅시다.
B = rand(9,100,51);
K = rand(34,9,100);
B2 = repmat(permute(B,[4 1 2 3]), [size(K,1) size(B)]);
K2 = repmat(K, [size(K) size(B,3)]);
G = bsxfun(@times,B2,K2);
그래서 솔루션은 어떻게 속도면에서 비교할 수 있습니까? 옥타브 온라인 유틸리티를 테스트 한 결과 초기 B
및 K
행렬을 생성하는 시간은 포함되지 않았습니다. 사전 할당이 필요한 솔루션에 대해 G
행렬을 미리 할당 할 시간을 포함했습니다. 코드는 다음과 같습니다.
3 루프 (@ slayton의 대답) : 4.024471의
2 루프 솔루션 : 1.616120의
0 루프 repmat/bsxfun 솔루션 : 1.211850의
0 루프 repmat/bsxfun 솔루션, 아니 한 임시 : 0.605838 s
경고 : 타이밍이 컴퓨터에 상당히 다를 수 있으므로 좋은 타이밍 테스트를 위해 온라인 유틸리티를 신뢰하지 않습니다. 루프가 실행 된 순서를 변경하면 (심지어 변수를 재사용하거나 할당 시간을 낭비하지 않도록주의를 기울여도) 조금 바뀌 었습니다. 즉, 2 루프 솔루션이 임시 변수가 저장되어있는 루프가없는 솔루션만큼 빠른 경우가있었습니다. 그러나 당신이 얻을 수있는 벡터화가 많을수록 당신은 더 잘 될 것입니다.
다음은 속도 테스트에 대한 코드입니다 :
B = rand(9,100,51);
K = rand(34,9,100);
tic
G1 = nan(34,9,100,51);
for ii = 1:size(B,1)
for jj = 1:size(B,2);
for kk = 1:size(B,3)
G1(:, ii, jj, kk) = K(:,ii,jj) .* B(ii,jj,kk);
end
end
end
t=toc;
printf('Time for 3 loop solution: %f\n' ,t)
tic
G2 = nan(34,9,100,51);
for b=1:size(B,3)
for k=1:size(K,1)
G2(k,:,:,b) = bsxfun(@times,B(:,:,b), squeeze(K(k,:,:)));
end
end
t=toc;
printf('Time for 2 loop solution: %f\n' ,t)
tic
B2 = repmat(permute(B,[4 1 2 3]), [size(K,1) 1 1 1]);
K2 = repmat(K, [1 1 1 size(B,3)]);
G3 = bsxfun(@times,B2,K2);
t=toc;
printf('Time for 0-loop repmat/bsxfun solution: %f\n' ,t)
tic
G4 = bsxfun(@times,repmat(permute(B,[4 1 2 3]), [size(K,1) 1 1 1]),repmat(K, [1 1 1 size(B,3)]));
t=toc;
printf('Time for 0-loop repmat/bsxfun solution, no temporaries: %f\n' ,t)
disp('Are the results equal?')
isequal(G1,G2)
isequal(G1,G3)
Time for 3 loop solution: 4.024471
Time for 2 loop solution: 1.616120
Time for 0-loop repmat/bsxfun solution: 1.211850
Time for 0-loop repmat/bsxfun solution, no temporaries: 0.605838
Are the results equal?
ans = 1
ans = 1
가 대단히 감사합니다! 그것은 작동하고 그것은 빠릅니다. – Kostas
@ Kostas 다음 투표를하십시오. 그리고/또는이 대답을 받아들입니다. – slayton
@slayton 나는 (내가 현재 matlab을 가지고 있지 않기 때문에 옥타브 온라인으로 테스트 한) 점점 더 벡터화 된 솔루션을 생각해 내었습니다. 컴퓨터에서 테스트 할 때 느끼는 속도 차이에 대해서는 궁금 할 것입니다. – tmpearce