2016-07-17 4 views
1

내 코드의 일부를 벡터화하는 데 문제가 있습니다. 나는 (n, n, m) 텐서를 가지고 있고 m에서 각 슬라이스에 두 번째 (n은 n) 행렬 (요소가 현명하지 않음)을 곱하고 싶습니다.텐서 내부에서 행렬 곱셈을 벡터화하기

여기에 보이는 무엇 등과 같은 대한 루프 :

Tensor=zeros(2,2,3); 
Matrix = [1,2; 3,4]; 

for j=1:n 
    Matrices_Multiplied = Tensor(:,:,j)*Matrix; 
    Recursive_Matrix=Recursive_Matrix + Tensor(:,:,j)/trace(Matrices_Multiplied); 
end 

가 어떻게 벡터화 방식으로 텐서 내부의 개별 행렬에 대한 행렬 곱셈을 수행합니까? 이것을 처리 할 수있는 tensor-dot과 같은 내장 함수가 있습니까? 아니면 더 영리합니까?

답변

1

Bsxfunningefficient matrix-multiplication 사용하여, 우리는 할 수 -

% Calculate trace values using matrix-multiplication 
T = reshape(Matrix.',1,[])*reshape(Tensor,[],size(Tensor,3)); 

% Use broadcasting to perform elementwise division across all slices 
out = sum(bsxfun(@rdivide,Tensor,reshape(T,1,1,[])),3); 

을 다시 한 성능이 가능한 더욱 향상을위한 또 하나의 행렬 곱셈과 마지막 단계를 대체 할 수 있습니다. 따라서, 모든 행렬 곱셈 전용 용액 것 -

[m,n,r] = size(Tensor); 
out = reshape(reshape(Tensor,[],size(Tensor,3))*(1./T.'),m,n) 

런타임 테스트

벤치마킹 코드 -

% Input arrays 
n = 100; m = 100; 
Tensor=rand(n,n,m); 
Matrix=rand(n,n); 
num_iter = 100; % Number of iterations to be run for 

tic 
disp('------------ Loopy woopy doops : ') 
for iter = 1:num_iter 
    Recursive_Matrix = zeros(n,n); 
    for j=1:n 
     Matrices_Multiplied = Tensor(:,:,j)*Matrix; 
     Recursive_Matrix=Recursive_Matrix+Tensor(:,:,j)/trace(Matrices_Multiplied); 
    end 
end 
toc, clear iter Recursive_Matrix Matrices_Multiplied 

tic 
disp('------------- Bsxfun matrix-mul not so dull : ') 
for iter = 1:num_iter 
    T = reshape(Matrix.',1,[])*reshape(Tensor,[],size(Tensor,3)); 
    out = sum(bsxfun(@rdivide,Tensor,reshape(T,1,1,[])),3); 
end 
toc, clear T out 

tic 
disp('-------------- All matrix-mul having a ball : ') 
for iter = 1:num_iter 
    T = reshape(Matrix.',1,[])*reshape(Tensor,[],size(Tensor,3)); 
    [m,n,r] = size(Tensor); 
    out = reshape(reshape(Tensor,[],size(Tensor,3))*(1./T.'),m,n); 
end 
toc 

타이밍 -

------------ Loopy woopy doops : 
Elapsed time is 3.339464 seconds. 
------------- Bsxfun matrix-mul not so dull : 
Elapsed time is 1.354137 seconds. 
-------------- All matrix-mul having a ball : 
Elapsed time is 0.373712 seconds. 
+0

있는가 두 번째 for 루프를 벡터화하는 방법 ("iter"를 인덱스로 사용하는 방법)? –

+0

@StevenSagona That 루프 :'for iter = 1 : num_iter'는 벤치 마크를위한 것일 뿐이므로 실행 시간을 가능한 한 정확하게 측정 할 수 있도록 충분한 시간 동안 코드를 실행해야합니다. MATLAB 코드 타이밍에 익숙하지 않은 경우 timeit을 사용하려면 여기를 참조하십시오. http://stackoverflow.com/a/29719681/3293881 여기에서 워밍업에 대한 tic-toc에 대한 또 다른 예제가 있습니다. http : // stackoverflow. com/a/26137901/3293881 – Divakar

+0

죄송합니다. 의견을 내기 전에 코드를 검토해야합니다. 나는이 줄을 제외한 모든 코드를 이해합니다 : '(reshape (Tensor, [], size (Tensor, 3)) * (1./T. ')' origial for-loop 않습니다 .n, m 작은 경우이 코드를 실행하고 벡터화 된 코드 원래대로 동일한 결과를 생성하지 않는 것을 보았다. 그것은 결국 행렬 곱셈 생각합니다. 아마 요소 단위로 곱하기 전환 생각 –

관련 문제