2016-07-13 12 views
3

MATLABでは、一連の2x2行列を3Dテンソルに積み重ねて行列の各インスタンスに対して行列乗算を実行したいと考えています。matlabでのテンソル積の効率的な実装

ので、私のCは= * Bは私の現在の実装は非常に読みやすいですが、私は誰かがMATLABにはないことを言って覚えて、この

function mats = mul3D(A, B) 
     % given a list of 2D matrices (e.g. rotation matrices) applies 
     % the matrix product for each instance along the third dimension 
     % mats(:,:,i) = A(:,:,i) * B(:,:,i) for all i 
     % for this to succeed matrix dimensions must agree. 
     mats = zeros(size(A,1), size(B,2), size(B,3)); 
     for i=1:size(B, 3) 
      mats(:,:,i) = A(:,:,i) * B(:,:,i); 
     end 
    end 

のように見えます

C_ijk = sum(a_ilk * b_ljk, over all l) 

として定義されますfor-loopsのようなものです。

このように、より速い速度でメモリを消費しない優れた実装について考えることができますか?私のコードはこのforループの実行時間の約50%を費やします。ご提案のための

編集

感謝。残念ながら、サードパーティのコードに新しい依存関係を導入することはできません。

質問に基づいて、私はテンソルの2 x 2 x n構造を利用する考えがありました。最新の実装は次のようになります。

function mats = mul3D(A, B) 
     % given a list of 2D matrices (e.g. rotation matrices) applies 
     % the matrix product for each instance along the third dimension 
     % mats(:,:,i) = A(:,:,i) * B(:,:,i) for all i 
     % for this to succeed matrix dimensions must agree. 
     mats = zeros(size(A,1), size(B,2), size(B,3)); 

     mats(1,1,:) = A(1,1,:) .* B(1,1,:) + A(1,2,:) .* B(2,1,:); 
     mats(2,1,:) = A(2,1,:) .* B(1,1,:) + A(2,2,:) .* B(2,1,:); 
     if(size(mats,2) > 1) 
      mats(1,2,:) = A(1,1,:) .* B(1,2,:) + A(1,2,:) .* B(2,2,:); 
      mats(2,2,:) = A(2,1,:) .* B(1,2,:) + A(2,2,:) .* B(2,2,:); 
     end 
    end 

これ以上の提案はありません。

+0

任意のサイズの場合、 'bsxfun'と' permute'で行うことができますが、より多くのメモリが必要となり、より速くなることははっきりしません。最近のMatlabのバージョンでは、ループはそれまでと同じくらい遅くはありません。いくつかのサイズが固定されている場合は、おそらくそれが悪用される可能性があります。どのサイズ(ディメンション)が固定され、その価値は何ですか? –

+0

'A'と' B'の典型的な形は何ですか? – Divakar

+0

最適化されたライブラリは、[link](https://www.mathworks.com/matlabcentral/answers/62382-matrix-multiply-slices-of-3d-matricies)で見つかりました。私はそれを構築するのに問題がありました。 – Rotem

答えて

1

mtimesxを使用することをお勧めします。
はここに参照してください:https://www.mathworks.com/matlabcentral/answers/62382-matrix-multiply-slices-of-3d-matricies

mtimesxは "マトリックスは、3D Matriciesのスライスを掛ける" を行うには、最適化さMEXファイルを使用しています。

mtimesxBLAST libraryを使用します(BLASTライブラリはMatlabインストールの一部です)。ここから

ダウンロードmtimesxソースコード:http://www.mathworks.com/matlabcentral/fileexchange/25977-mtimesx-fast-matrix-multiply-with-multi-dimensional-support

私はMatalb r2014bでMEXファイルを構築する問題を抱えていました。
問題は、r2014aを超えるMatlabではファイルmexopts.batが不足していることです。
mexビルディングスクリプトではmexopts.batが使用されています。

mexopts.batをダウンロードして解決しました。
私は、Visual Studio 2010のコンパイラを使用して、見つかっていますここmexopts.batをマッチング:
\AppData\Roaming\MathWorks\MATLAB\R2014b\

そのmtimesxが非常にうまく機能しているすべての後に...
c:\Users\ロテム:http://www.dynare.org/DynareWiki/ConfigureMatlabWindowsForMexCompilation

は私がローカルフォルダにmexopts.batをコピー mexファイルの使用は、forループを使用するほうがはるかに高速でなければなりません。