在MATLAB中,我有一系列2x2矩阵堆叠成3D张量,我想为每个矩阵实例执行矩阵乘法。
所以我的C = A * B被定义为
C_ijk = sum(a_ilk * b_ljk, over all l)
我当前的实现看起来像这样
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
这很容易阅读,但我记得有人说MATLAB不喜欢for循环。
那么你能想到一个更好的实现,它不会比这个消耗更多的内存而更快吗?我的代码在这个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 :(得分:1)
我建议您使用mtimesx
请参阅此处:https://www.mathworks.com/matlabcentral/answers/62382-matrix-multiply-slices-of-3d-matricies
mtimesx
使用优化的 mex文件来执行" Matrix倍增3d Matricies" 的切片。
mtimesx
使用BLAST 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
:http://www.dynare.org/DynareWiki/ConfigureMatlabWindowsForMexCompilation
我将mexopts.bat
复制到本地文件夹:c:\Users\
Rotem \AppData\Roaming\MathWorks\MATLAB\R2014b\
毕竟mtimesx
工作得很好......
使用mex文件应该比使用for循环快得多。