2016-07-17 24 views
1

私のコードの一部をベクトル化するのに問題があります。私は(n、n、m)テンソルを持ち、mの各スライスに2番目(n×n)の行列(要素は賢明ではない)を乗算したい。テンソル内の行列乗算をベクトル化する

は、ここでは、forループとして次のようになります。

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 

私はベクトル化された方法でテンソル内部の個々の行列の行列乗算を実行するにはどうすればよいですか?これを処理できるテンソルドットのような組み込み関数がありますか、それともより賢いですか?

答えて

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

を繰り返しますが、一つはパフォーマンスの可能性をさらに高めるための1以上のマトリックス乗算との最後のステップを置き換えることができます。したがって、すべての行列乗算専用ソリューションがあろう -

[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

がありますその2番目のforループ( "iter"をインデックスとして持つもの)をベクトル化する方法? –

+0

@StevenSagonaそのループ: '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。 ')'これは、元のfor-loopはそうです。n、mが小さいときにこのコードを実行し、ベクトル化されたコードが元のものと同じ結果を生成しないことがわかりました。 –

関連する問題