我有两个矩阵:大小为B
的{{1}}和大小为9x100x51
的{{1}}。我想将K
的所有34x9x100
乘以K(34)
中的每一个,以便得到一个大小为B(9)
的最终矩阵G
。
例如:元素34x9x100x51
的组成如下
G(:,5,60,25)
我希望这个例子有助于理解我想要做的事情。 谢谢
答案 0 :(得分:3)
每当你发现自己在matlab中编写嵌套循环时,你很有可能使用内置的矢量化函数来加速。代码最终通常也会缩短(但读者通常不太清楚,所以请注释您的代码!)。
在这种情况下,避免嵌套循环会有所作为吗?绝对!让我们开始工作吧。 @slayton提供了一个3循环解决方案。我们可以加快速度。
稍微重述一下问题,B
有51 9x100
个矩阵,K
有34 9x100
个矩阵。对于51x34
的每个组合,您希望以元素方式乘以9x100
和B
的相应K
矩阵。
元素乘法对bsxfun
来说是一个很好的工作,因此我们可以从概念上将此问题简化为沿着两个维度(B
的第三维,K
的第一维)。 :
初始,双循环解决方案:
B = rand(9,100,51);
K = rand(34,9,100);
G = nan(34,9,100,51);
for b=1:size(B,3)
for k=1:size(K,1)
G(k,:,:,b) = bsxfun(@times,B(:,:,b), squeeze(K(k,:,:)));
end
end
好的,两个循环正在取得进展。我们可以做得更好吗?好吧,让我们认识到矩阵B
和K
可以沿着适当的维度进行复制,然后逐个元素倍增。
B = rand(9,100,51);
K = rand(34,9,100);
B2 = repmat(permute(B,[4 1 2 3]), [size(K,1) size(B)]);
K2 = repmat(K, [size(K) size(B,3)]);
G = bsxfun(@times,B2,K2);
那么,解决方案如何快速比较?我测试了八度音阶在线实用程序,但没有包括生成初始B
和K
矩阵的时间。我确实包含了为需要预分配的解决方案预分配G
矩阵的时间。代码如下。
3个循环(@ slayton的答案):4.024471 s
2循环解决方案:1.616120 s
0循环repmat / bsxfun解决方案:1.211850 s
0循环repmat / bsxfun解,没有临时值:0.605838 s
以下是速度测试的代码:
B = rand(9,100,51);
K = rand(34,9,100);
tic
G1 = nan(34,9,100,51);
for ii = 1:size(B,1)
for jj = 1:size(B,2);
for kk = 1:size(B,3)
G1(:, ii, jj, kk) = K(:,ii,jj) .* B(ii,jj,kk);
end
end
end
t=toc;
printf('Time for 3 loop solution: %f\n' ,t)
tic
G2 = nan(34,9,100,51);
for b=1:size(B,3)
for k=1:size(K,1)
G2(k,:,:,b) = bsxfun(@times,B(:,:,b), squeeze(K(k,:,:)));
end
end
t=toc;
printf('Time for 2 loop solution: %f\n' ,t)
tic
B2 = repmat(permute(B,[4 1 2 3]), [size(K,1) 1 1 1]);
K2 = repmat(K, [1 1 1 size(B,3)]);
G3 = bsxfun(@times,B2,K2);
t=toc;
printf('Time for 0-loop repmat/bsxfun solution: %f\n' ,t)
tic
G4 = bsxfun(@times,repmat(permute(B,[4 1 2 3]), [size(K,1) 1 1 1]),repmat(K, [1 1 1 size(B,3)]));
t=toc;
printf('Time for 0-loop repmat/bsxfun solution, no temporaries: %f\n' ,t)
disp('Are the results equal?')
isequal(G1,G2)
isequal(G1,G3)
Time for 3 loop solution: 4.024471
Time for 2 loop solution: 1.616120
Time for 0-loop repmat/bsxfun solution: 1.211850
Time for 0-loop repmat/bsxfun solution, no temporaries: 0.605838
Are the results equal?
ans = 1
ans = 1
答案 1 :(得分:0)
您可以使用嵌套循环执行此操作,但它可能不会非常快:
B = rand(9,100,51);
K = rand(34,9,100);
G = nan(34,9,100,51)
for ii = 1:size(B,1)
for jj = 1:size(B,2);
for kk = 1:size(B,3)
G(:, ii, jj, kk) = K(:,ii,jj) .* B(ii,jj,kk);
end
end
end
这是漫长的一天,我的大脑有点油腻,对任何可以改善这一点的人都感到荣幸!