作者Absolitude (别再睡了起床了爱丽)
看板MATLAB
标题[运算] 多层for回圈简化
时间Tue Dec 19 02:09:38 2017
最近遇到一个问题目前只想到用多层for来处理,想请问有没有办法简化
问题大概是这样,有两个m*n*k的三维矩阵atot和atotcc,atotcc是atot的共轭复数
https://imgur.com/9Eou21X
其中每一个k方向的红框atot(1,1,:) atotcc(2,3,:)这些视为一个个向量,目标是把所
有atot中的m*n个向量和atotcc中的m*n个向量分别做内积得到(m*n)^2个值,再取总合
目前的程式大概是这样
m=15;
n=19;
k=10000;
ar=randn(n,m,k);
ai=randn(n,m,k);
atot=ar+i*ai;
atotcc=conj(atot);
acsd=zeros(n,m,n,m)+i*zeros(n,m,n,m);
tic;
for ix=1:m
for iy=1:n
for ixc=1:m
for iyc=1:n
acsd(iy,ix,ixc,iyc)=sum(bsxfun(@times,atot(iy,ix,:),atotcc(iyc,ixc,:)));
end
end
end
end
toc
tic;
acsdsum=sum(sum(sum(sum(acsd))));
toc
说是内积但是不用dot是因为有复数用起来有些问题,一维的话我知道可以取转置,但是
写成(iy,ix,:)这种形式不太知道怎麽做所以先用sum配上bsxfun或.*
感觉写这麽多层回圈不是很有效率,而且也不适合用gpu加速(目前只会变慢),但这应该是
很适合平行化的计算(上面的程式在执行时会自动在cpu上平行化),因为所有的内积以及
内积中的运算分别都是独立的
在这先谢谢板上先进的不吝指教 感恩
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.114.253.34
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/MATLAB/M.1513620596.A.E0A.html
也可以先变成(m*n)*k的二维矩阵
https://imgur.com/OD6Cu3O
m=15;
n=19;
k=10000;
mtn=m*n;
ar=randn(mtn,k);
ai=randn(mtn,k);
atot=ar+i*ai;
atotcc=conj(atot);
tic;
for ixc=1:mtn
for iyc=1:mtn
acsd(iyc,ixc)=sum(atot(ixc,:).*atotcc(iyc,:));
end
end
toc
tic;
acsdsum=sum(sum(acsd));
toc
(可能是要转置的关系,写成dot
acsd(iyc,ixc)=dot(atot(ixc,:)',atotcc(iyc,:));
会更慢)
这样就少了两层for,用cpu速度看起来是差不多,gpu的话写成这样比四层快非常多,不
过还是比cpu慢,不知道有没有办法再简化
m=15;
n=19;
k=10000;
mtn=m*n;
ar=randn(mtn,k,'gpuArray');
ai=randn(mtn,k,'gpuArray');
atot=ar+i*ai;
atotcc=conj(atot);
acsd=zeros(mtn,mtn,'gpuArray')+i*zeros(mtn,mtn,'gpuArray');
tic;
for ixc=1:mtn
for iyc=1:mtn
acsd(iyc,ixc)=sum(atot(ixc,:).*atotcc(iyc,:));
end
end
toc
tic;
acsdsum=sum(sum(acsd));
toc
感恩
※ 编辑: Absolitude (140.114.253.34), 12/19/2017 02:47:19
※ 编辑: Absolitude (140.114.253.34), 12/19/2017 02:53:38
1F:推 sunev: atot=randn(m*n,k)+1i*randn(m*n,k); 12/19 05:27
2F:→ sunev: acsdsum=sum(sum(atot*atot')); 12/19 05:27
谢谢 我震惊到说不话..
※ 编辑: Absolitude (140.114.253.159), 12/19/2017 12:24:55
虽然一开始没说,但是给了一点P比以示谢意,帮助太多
我觉得我矩阵都白学了..
※ 编辑: Absolitude (140.114.253.159), 12/19/2017 12:27:33
3F:→ Absolitude: 之前用的时候都没用到复数,没想到转置後还会变共轭 12/19 15:40
4F:推 sunev: 你画的图很精美,证明你完全知道自己想算什麽,也用到了一 12/19 20:50
5F:→ sunev: 些vectorize的技巧,像是2维变1维以及bsxfun 12/19 20:50
6F:→ sunev: 你只是不知道两件事, 12/19 20:53
7F:→ sunev: 1.矩阵相乘可以看成向量内积的推广。 12/19 20:53
8F:→ sunev: 2.复数向量怎麽做内积。 12/19 20:54
9F:→ sunev: 有兴趣可以去翻一下线性代数的书,里面有提到这些事 12/19 20:54
谢谢你的建议
※ 编辑: Absolitude (140.114.253.151), 12/20/2017 03:19:45
比起一开始把MATLAB当C那样写,现在大致了解MATLAB要用什麽行事才会快,不过常常
想不到从何下手,大概也只能多练习了
※ 编辑: Absolitude (140.114.253.151), 12/20/2017 03:21:18