我现在进行了一些时间测试,这是2x2x2x2的最快途径。 注
C = A;
C(1,1,:) = A(1,1,:).*B(1,1,:) + A(1,2,:).*B(2,1,:);
C(1,2,:) = A(1,1,:).*B(1,2,:) + A(1,2,:).*B(2,2,:);
C(2,1,:) = A(2,1,:).*B(1,1,:) + A(2,2,:).*B(2,1,:);
C(2,2,:) = A(2,1,:).*B(1,2,:) + A(2,2,:).*B(2,2,:);
在一般情况下,选择住宿实际上是最快的(登机忘记预先分配C,但!)。
Should one already have the result as cell-array of matrices though, using cellfun is the fastest choice, it is also faster than looping over the cell elements:
C = cellfun(@mtimes, A, B, UniformOutput , false);
但是,必须打上rel=“nofollow”>num2cell 首先(Ac = num2cell(A, [1 2]
)和cell2mat
,用于3d-array案废物,时间过长。
这里,我是随机挑选的2×2×1e4:
array-for: 0.057112
arrayfun : 0.14206
num2cell : 0.079468
cell-for : 0.033173
cellfun : 0.025223
cell2mat : 0.010213
explicit : 0.0021338
Explicit refers to using direct calculation of the 2 x 2 matrix elements, see bellow.
The result is similar for new random arrays, cellfun
is the fastest if no num2cell
is required before and there is no restriction to 2x2xN. For general 3d-arrays looping over the third dimension is indeed the fastest choice already. Here s the timing code:
n = 2;
m = 2;
l = 1e4;
A = rand(n,m,l);
B = rand(m,n,l);
% naive for-loop:
tic
%Cf = nan(n,n,l);
Cf = A;
for jl = 1:l
Cf(:,:,jl) = A(:,:,jl) * B(:,:,jl);
end;
disp([ array-for: num2str(toc)]);
% using arrayfun:
tic
Ca = arrayfun(@(k) A(:,:,k)*B(:,:,k), 1:size(A,3), UniformOutput ,false);
Ca = cat(3,Ca{:});
disp([ arrayfun : num2str(toc)]);
tic
Ac = num2cell(A, [1 2]);
Bc = num2cell(B, [1 2]);
disp([ num2cell : num2str(toc)]);
% cell for-loop:
tic
Cfc = Ac;
for jl = 1:l
Cfc{jl} = Ac{jl} * Bc{jl};
end;
disp([ cell-for : num2str(toc)]);
% using cellfun:
tic
Cc = cellfun(@mtimes, Ac, Bc, UniformOutput , false);
disp([ cellfun : num2str(toc)]);
tic
Cc = cell2mat(Cc);
disp([ cell2mat : num2str(toc)]);
tic
Cm = A;
Cm(1,1,:) = A(1,1,:).*B(1,1,:) + A(1,2,:).*B(2,1,:);
Cm(1,2,:) = A(1,1,:).*B(1,2,:) + A(1,2,:).*B(2,2,:);
Cm(2,1,:) = A(2,1,:).*B(1,1,:) + A(2,2,:).*B(2,1,:);
Cm(2,2,:) = A(2,1,:).*B(1,2,:) + A(2,2,:).*B(2,2,:);
disp([ explicit : num2str(toc)]);
disp( );