4D matrix multiplication
显示 更早的评论
I do the following in 4 loops and it takes ages to complete. Is there a way this code could be made more efficeint, without using parallel processing toolbox?
'steer' is a 136x101x101x16 matrix
'R' is a 136x16x16 matrix
'pow' and 'F' are 101x101 matrices.
pow = zeros(grdpts_y, grdpts_x); %grdpts_y, grdpts_x = 101
for l=1:nf %nf = 136
F = zeros(grdpts_y,grdpts_x);
for i=1:grdpts_x
for j=1:grdpts_y
F(i,j) = F(i,j) + 1./(squeeze(steer(l,i,j,:))'*squeeze(R(l,:,:))*squeeze(steer(l,i,j,:)));
end
end
F = F.*conj(F);
pow = pow + F;
end
Thanks in advance,
Kamran
采纳的回答
steer=reshape( permute(steer,[2,3,4,1]),101^2,[],136 );
R=permute(R,[2,3,1]);
F=1./sum( pagemtimes(conj(steer),R).*steer, 2);
F=reshape( abs(F).^2 ,101,101,[]);
pow=sum(F,3);
10 个评论
Thanks for the answer. It is very fast, but I get different results from the loop implementation.
Not me. See the comparison below:
[grdpts_y, grdpts_x] = deal(101);nf = 26;
steer=rand(26,101,101,16);
R=rand(26,16,16);
%Original version
pow = zeros(grdpts_y, grdpts_x); %grdpts_y, grdpts_x = 101
for l=1:nf %nf = 136
F = zeros(grdpts_y,grdpts_x);
for i=1:grdpts_x
for j=1:grdpts_y
F(i,j) = F(i,j) + 1./(squeeze(steer(l,i,j,:))'*squeeze(R(l,:,:))*squeeze(steer(l,i,j,:)));
end
end
F = F.*conj(F);
pow = pow + F;
end
pow0=pow;
%Proposed Version
steer=reshape( permute(steer,[2,3,4,1]),101^2,[],26 );
R=permute(R,[2,3,1]);
F=1./sum( pagemtimes(steer,R).*steer, 2);
F=reshape( abs(F).^2 ,101,101,[]);
pow=sum(F,3);
%Difference
difference=pow(:)-pow0(:);
[max(difference),min(difference)] %min and max differences
ans = 1×2
1.0e+-16 *
0.4163 -0.2776
Strange. I run your code and got the exact same results as you, but when I run it on my data the results from the two implemntations are different.
It shouldn't matter but 'steer' and 'R' are complex valued! Probably, I am doing something wrong!

The images don't tell us quantitatively what the differences are. What is the relative error:
norm(pow0(:)-pow(:))/norm(pow0(:))
strangely enough
norm(pow0(:)-pow(:))/norm(pow0(:)) = 1
Try
F=1./sum( pagemtimes(conj(steer),R).*steer, 2);
That did it. Thank you very much.
Can I ask one more question? I need to do the loop differntly for another method and I haven't quite understood how your solution works. I need to do the same for the following:
for l=1:nf
F= zeros(grdpts_y, grdpts_x);
for i=1:grdpts_x
for j=1:grdpts_y
[Vec, Val] = eig(squeeze(R(l,:,:)));
[Val Seq] = sort(max(Val));
Vec_s = Vec(:,Seq(nstat ,nstat));
Vec_n = Vec(:,Seq(1:nstat-1));
F(i, j) = F(i,j) + 1./(squeeze(steer(l,i,j,:))'*Vec_n*Vec_n'*squeeze(steer(l,i,j,:)));
end
end
F = F.*conj(F);
pow = pow + F;
end
In your new version, F will always be real, non-negative, so I don't know why you would still be computing conj(F).
steer=reshape( permute(steer,[2,3,4,1]),101^2,[],136 );
Vec_n=cell(1,nf);
for l=1:nf
[Vec, Val] = eig(squeeze(R(l,:,:)));
[Val Seq] = sort(max(Val));
Vec_s = Vec(:,Seq(nstat ,nstat));
Vec_n{l}= Vec(:,Seq(1:nstat-1));
end
Vec_n=cat(3,Vec_n{:});
F=1./sum( abs(pagemtimes(conj(steer),Vec_n)).^2, 2);
F=reshape( abs(F).^2 ,101,101,[]);
pow=sum(F,3);
Thank you very much. You are of course right. Thanks again for the prompt help.
更多回答(0 个)
类别
在 帮助中心 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
另请参阅
选择网站
选择网站以获取翻译的可用内容,以及查看当地活动和优惠。根据您的位置,我们建议您选择:。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
