2013-02-27 3 views
2

두 개의 행렬이 있습니다 : B 크기는 9x100x51이고 K 크기는 34x9x100입니다. 모든 K(34)B(9)에 곱하여 최종 행렬 G의 크기가 34x9x100x51이되도록합니다. 예를 들어Matlab : 요소 3D 행렬 곱셈

: 나는 예는 내가 원하는 것을 이해하는 데 도움이되기를 바랍니다

G(:,5,60,25)=K(:,5,60)*B(5,60,25).

을 따를 요소 G(:,5,60,25)이 구성되어있다. 아마 정말 빠르지 않을지라도 , 당신은

답변

0

당신은 중첩 루프와 함께이 작업을 수행 할 수 있습니다 감사합니다

B = rand(9,100,51); 
K = rand(34,9,100); 

G = nan(34,9,100,51) 

for ii = 1:size(B,1) 
    for jj = 1:size(B,2); 
    for kk = 1:size(B,3) 
     G(:, ii, jj, kk) = K(:,ii,jj) .* B(ii,jj,kk); 
    end 
    end 
end 

그 긴 날이었다 나의 뇌는 튀김 조금, 사람에게 칭찬 누구 수 이것을 향상 시키십시오!

+0

가 대단히 감사합니다! 그것은 작동하고 그것은 빠릅니다. – Kostas

+0

@ Kostas 다음 투표를하십시오. 그리고/또는이 대답을 받아들입니다. – slayton

+0

@slayton 나는 (내가 현재 matlab을 가지고 있지 않기 때문에 옥타브 온라인으로 테스트 한) 점점 더 벡터화 된 솔루션을 생각해 내었습니다. 컴퓨터에서 테스트 할 때 느끼는 속도 차이에 대해서는 궁금 할 것입니다. – tmpearce

3

matlab에 중첩 루프를 작성하면 언제든지 내장 된 벡터화 된 함수 형식을 사용하여 속도를 높일 수 있습니다. 코드는 일반적으로 너무 짧게 끝나기도합니다 (그러나 독자에게는 덜 분명해지기 때문에 코드에 주석을 달아보십시오!).

이 경우 중첩 루프를 피하는 것이 효과가 있습니까? 전혀! 일하러 가자. @slayton은 3 루프 솔루션을 제공합니다. 우리는 더 빨리 갈 수 있습니다.

B은 51 9x100 개의 행렬을 가지고 K은 34 9x100 개의 행렬을 가지고 있습니다. 51x34의 각 조합에 대해 행렬을 BK에서 요소 단위로 곱하려고합니다.

요소 현명한 곱셈 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 

두 개의 루프가 진행 중입니다. 더 잘할 수 있을까요? 자, 행렬 BK이 적절한 차원을 따라 복제 될 수 있고 요소 단위로 한번에 곱해질 수 있다는 것을 알아 봅시다.

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); 

그래서 솔루션은 어떻게 속도면에서 비교할 수 있습니까? 옥타브 온라인 유틸리티를 테스트 한 결과 초기 BK 행렬을 생성하는 시간은 포함되지 않았습니다. 사전 할당이 필요한 솔루션에 대해 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