我正在MATLAB中编写一个程序,作为基于DFT的项目的一部分。
让N x N
数据矩阵为X
且相应的DFT矩阵为Y
,则DFT系数可表示为
Y(k1,k2) = ∑(n1=0:N-1)∑(n2=0:N-1)[X(n1,n2)*(WN^(n1k1+n2k2))] (1)
0≤k1,k2≤N-1
Where WN^k=e^((-j2πk)/N)
由于旋转因子WN是周期性的,(1)
可以表示为
Y(k1,k2)=∑(n1=0:N-1)∑(n1=0:N-1)[X(n1,n2)*(WN^([(n1k1+n2k2)mod N) ] (2)
指定((n1k1 +n2k2)) N = p
由给定(n1,n2)
的一组(k1,k2)
满足。因此,通过对此类数据进行分组并应用WN^(p+N /2) = -(WN^P)
,
(2)
可以表示为
Y(k1,k2)= ∑(p=0:M-1)[Y(k1,k2,p)*(WN^p)] (3)
哪里
Y(k1,k2,p)= ∑(∀(n1,n2)|z=p)X(n1,n2) - ∑(∀(n1,n2)|z=p+M)X(n1,n2) (4)
z=[(n1k1+n2k2)mod N] (5)
我正在编写一个程序来查找Y(k1,k2,p)
。即我需要从给定的2D方阵(即矩阵)创建2d矩阵的切片(即每个切片是2D矩阵的3D矩阵) X
).. X
的维度最高可达512。
基于上面的等式,我编写了如下代码。我需要对它进行矢量化。
N=size(X,1);
M=N/2;
Y(1:N,1:N,1:M)=0;
for k1 = 1:N
for k2 = 1:N
for p= 1:M
for n1=1:N
for n2=1:N
N1=n1-1; N2=n2-1; P=p-1; K1=k1-1; K2=k2-1;
z=mod((N1*K1+N2*K2),N);
if (z==P)
Y(k1,k2,p)= Y(k1,k2,p)+ X(n1,n2);
elsif (z==(P+M))
Y(k1,k2,p)= Y(k1,k2,p)- X(n1,n2);
end
end
end
end
end
由于有5个FOR循环,对于N的大尺寸,执行时间非常大。因此,请为我提供一个消除FOR循环和矢量化代码的解决方案。我需要使代码以最大速度执行。 ..再次感谢..
答案 0 :(得分:2)
这是第一个对最内层循环进行矢量化的提示。
从您的代码中,我们可以注意到n1
,N1
,P
,K1
和K2
在此循环中是常量。
所以我们可以将z
重写为掩码向量,如下所示:
z = mod(N1*K1+K2*(0:N-1));
然后你的if语句相当于添加X中所有元素的总和,使z==P
减去X中所有元素的总和,使z==P+M
。重写这很简单:
Y(k1,k2,p)= Y(k1,k2,p)+sum(X(n1,z==P))-sum(X(n1,z==P+M));
所以你的程序可以按如下方式编写:
N=size(X,1);
M=N/2;
Y(1:N,1:N,1:M)=0;
for k1 = 1:N
for k2 = 1:N
for p= 1:M
for n1=1:N
N1=n1-1; P=p-1; K1=k1-1; K2=k2-1;
z=mod(N1*K1+K2*(0:N-1),N);
Y(k1,k2,p) = sum(X(n1,z==P))-sum(X(n1,z==P+M));
end
end
end
end
然后你可以用n1
做同样的事情;为此,您需要为z构建一个2D数组,例如:
z = mod(K1*repmat(0:N-1,N,1)+K2*repmat((0:N-1).',1,N));
注意size(z)==size(X)
。然后Y的2D总和变为:
Y(k1,k2,p) = Y(k1,k2,p)+sum(X(z==P))-sum(X(z==P+M));
此处不再需要+=
操作,因为您只能访问Y的每个元素一次:
Y(k1,k2,p)= sum(X(n1,z==P))-sum(X(n1,z==P+M));
所以我们再放弃一个循环:
N=size(X,1);
M=N/2;
Y(1:N,1:N,1:M)=0;
for k1 = 1:N
for k2 = 1:N
for p= 1:M
P=p-1; K1=k1-1; K2=k2-1;
z = mod(K1*repmat(0:N-1,N,1)+K2*repmat((0:N-1).',1,N));
Y(k1,k2,p) = sum(X(z==P))-sum(X(z==P+M));
end
end
end
关于其他循环,我认为它不值得对它们进行矢量化,因为你必须构建一个5D数组,这可能是非常庞大的内存。我的建议是将z
保留为2D数组,因为它的大小为X.如果它不适合内存,只需向量化最内层循环。