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
これ以上の提案はありません。
任意のサイズの場合、 'bsxfun'と' permute'で行うことができますが、より多くのメモリが必要となり、より速くなることははっきりしません。最近のMatlabのバージョンでは、ループはそれまでと同じくらい遅くはありません。いくつかのサイズが固定されている場合は、おそらくそれが悪用される可能性があります。どのサイズ(ディメンション)が固定され、その価値は何ですか? –
'A'と' B'の典型的な形は何ですか? – Divakar
最適化されたライブラリは、[link](https://www.mathworks.com/matlabcentral/answers/62382-matrix-multiply-slices-of-3d-matricies)で見つかりました。私はそれを構築するのに問題がありました。 – Rotem