从FFTW中添加每个频率的所有值

时间:2016-07-28 05:16:49

标签: fft fftw

我使用FFTW(fftw_plan_dft_r2c_3d)运行了3D傅里叶变换,我想在每个频率上总结变换值的(对数),包括不重复的频率实际存储在输出数组中(我理解大小为Nx x Ny x (Nz/2 + 1))。如果不重复计算,我该怎么做?

1 个答案:

答案 0 :(得分:3)

好问题。对不起,我的回答有点啰嗦,我想确保我不犯任何错误。在这里 -

如果对所有“切片”进行双重计算,复数到复数3D FFT的对数和幅度之和将等于实数到复数3D FFT的对数总和。 (前者的最后一个维度)是前者所缺少的。

  • 如果Nz是偶数,则表示重复计算除第一个和最后一个切片以外的所有切片。
  • 如果Nz为奇数,则重复计算除第一个以外的所有切片。

(这是因为偶数长度的实数到复数DFT包括-π弧度角频率(对应于-1的相量),而奇数长度则不包括它。我永远不会记住这种模式,所以我总是在单位圆周围绘制N = 4对N = 3个相量,以提醒自己是否奇数或甚至包括-πrad。)

这是使用Numpy / Python的想法的实验验证,我认为其符合FFTW的实数到复数的FFT:通过Nx = 10 Ny = 20实数Nz = 8生成Nz 。计算其复杂到复杂的3D FFT(由N乘Nz复数阵列产生Nx)其实际到复杂的3D FFT(通过Ny产生Nx乘以(Nz / 2 + 1)复数数组)。如果你对除了第一个和第一个之外的所有数据进行重复计算,则验证前者的对数和的总和是相同与后者的对数和。最后一片,因为import numpy as np import numpy.fft as fft Nx = 10 Ny = 20 Nz = 8 x = np.random.randn(Nx, Ny, Nz) Xf = fft.fftn(x) Xfr = fft.rfftn(x) energyProduct1 = np.log10(np.abs(Xf)).sum() lastSlice = -1 if Nz % 2 is 0 else None energyProduct2 = np.log10(np.abs(np.dstack((Xfr, Xfr[:, :, 1:lastSlice])))).sum() print('Difference: %g' % (energyProduct1 - energyProduct2)) # Difference: -4.54747e-13 是偶数。

代码:

Nz

如果用奇数np.dstack((Xfr, Xfr[:, :, 1:lastSlice))重新运行它,你会发现复数到复数和实数之间的差异仍在机器精度为0之内。

rfftndstack的文档,fft.rfftn)将Nz输出与第二维倒数第二个切片堆叠在倒数第二个 - 倒数第二个,因为Nz是偶数,你不想重复计算0或-πDFT箱。

当然,另一种方法是计算实数到复数数组的对数和, double ,然后减去第一个切片上的对数和大小(如果Nz是偶数)是最后一个切片。

tl; dr 将实际到复数输出的对数幅度相加。加倍它。从该结果中减去第一个切片(在第三维中)的和 - 对数量值。如果Nz是奇数,那么你已经完成了。如果if 'xyz' in 'oiurwernjfndj xyz iekjerk': print True 是偶数,也会减去最后一个切片的sum-log-magnitude。