关于Julia中real FFT输出频率排列顺序的技术问询
理解Julia FFTW中2D实FFT的频率排列
我来帮你把这个问题理清楚——Julia的rfft完全沿用FFTW库的原生频率排列规则,和Numpy的默认逻辑确实不一样,下面结合你的MWE一步步拆解:
先搞懂输出尺寸的由来
你的输入是(64,64)的实数数组,执行plan_rfft(U, (1,2))后输出尺寸为(33,64):
- 第一维度从64变成33,是因为实FFT只存储正频率部分(包含直流分量和Nyquist频率),计算方式是
N/2 + 1 = 64/2 +1 =33 - 第二维度保持64,说明这个维度执行的是全范围的复FFT(保留正负频率信息)
逐维度解析频率排列(注意Julia是1-based索引!)
第一维度(输出轴1,长度33)
这个维度是实FFT的核心维度,频率从低到高线性排列:
- 索引
1:对应直流分量(0频率) - 索引
m(2 ≤ m ≤33):对应正频率,实际频率值为(m-1)/(N*Δx)(Δx是该维度的采样间隔,如果是单位采样,直接简化为(m-1)/64) - 索引
33:对应Nyquist频率(采样频率的一半),值为32/(N*Δx) = 1/(2Δx)
这里没有负频率,因为实信号的FFT满足共轭对称性——负频率的信息可以通过正频率的共轭结果推导出来,所以rfft只存储一半分量来节省内存。
第二维度(输出轴2,长度64)
这个维度执行的是标准复FFT,频率排列遵循FFTW的"未移位标准顺序":
- 索引
1:直流分量(0频率) - 索引
m(2 ≤m ≤32):正频率,实际频率值为(m-1)/(N*Δy)(Δy是该维度的采样间隔) - 索引
33:Nyquist频率,值为32/(N*Δy) - 索引
m(34 ≤m ≤64):负频率,对应实际频率为(m-65)/(N*Δy)——比如索引64对应-1/(N*Δy),索引34对应-31/(N*Δy)
快速验证的小技巧
如果你想亲手确认这个排列,可以构造一个已知频率的测试信号,比如:
N = 64 # 构造一个在维度1的5/64频率、维度2的10/64频率上的余弦信号 U = cos.(2π * 5/64 * (0:N-1)') .* cos.(2π * 10/64 * (0:N-1)) prfor = plan_rfft(U, (1,2)) F = prfor * U # 找到绝对值最大的位置 findmax(abs.(F))
运行后你会发现,最大值出现在索引(6, 11)——刚好对应我们设定的频率:维度1的m-1=5(即索引6),维度2的m-1=10(即索引11),完美匹配预期。
另外,如果你觉得原始排列看着别扭,可以用fftshift函数把频率轴中心对齐,这样直流分量会移到每个维度的中间,负频率在左、正频率在右,更符合直观理解:
F_shifted = fftshift(F)
内容的提问来源于stack exchange,提问作者TomCho
相关产品推荐
相关产品推荐

