c++ - 为什么在使用 FFTW 将(2d)IDFT 转换为 DFT 时,频域中的数据会“镜像”?
问题描述
我通过在 16x16 数据集中设置某些模式的实分量来手动初始化 2d 频域中的状态。然后我执行 2d IDFT 来获取真实的域数据。这一切都按预期工作。
然后我对真实域数据执行 DFT,以返回(应该是)与我手动初始化的频率模式相同的频率模式。然而,它们返回时振幅减半,垂直频率“镜像”。为了显示:
输入模式:
k[1, 0]: 32 + 0i
k[2, 0]: 16 + 0i
k[3, 0]: 8 + 0i
k[4, 0]: 4 + 0i
IDFT -> DFT 后的输出模式:
k[ 1, 0]: 16 + 0i
k[ 2, 0]: 8 + 0i
k[ 3, 0]: 4 + 0i
k[ 4, 0]: 2 + 0i
k[12, 0]: 2 + 0i
k[13, 0]: 4 + 0i
k[14, 0]: 8 + 0i
k[15, 0]:16 + 0i
我的问题是,为什么 DFT 输出中的模式与 IDFT 的初始输入不同?
对于一些额外的上下文,我遇到的问题是我正在使用这些数据来“解决”热方程,并且高频信号会很快按比例缩小。所以 k[12, 0] 到 k[15, 0] 模式在几个时间步之后实际上并没有多大贡献。
重现问题的代码:
int N = 16; // Dimensions of the data
int logical_width = (N / 2) + 1; // Logical width of the frequency domain
double* real = new double[N * N];
fftw_complex* complex = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N * logical_width);
fftw_plan plan = fftw_plan_dft_r2c_2d(N, N, real, complex, FFTW_ESTIMATE);
fftw_plan iplan = fftw_plan_dft_c2r_2d(N, N, complex, real, FFTW_ESTIMATE);
// Initialize all real data to 0
for (int i = 0; i < N * N; i++) {
real[i] = 0.0;
}
// Initialize all complex data to 0
for (int i = 0; i < N * logical_width; i++) {
complex[i][REAL] = 0.0;
complex[i][IMAG] = 0.0;
}
// Set first 4 vertical modes
complex[1 * logical_width][REAL] = 32;
complex[2 * logical_width][REAL] = 16;
complex[3 * logical_width][REAL] = 8;
complex[4 * logical_width][REAL] = 4;
// Print before IDFT -> DFT
printComplex(complex, N);
// IDFT
fftw_execute(iplan);
// DFT back
fftw_execute(plan);
// Print after IDFT -> DFT
printComplex(complex, N, true); // Pass true to divide amplitudes by N*N
// Clean up
fftw_destroy_plan(plan);
fftw_destroy_plan(iplan);
delete[] real;
fftw_free(complex);
这两个printComplex(...)
调用的输出可以在上面的问题中看到。
解决方案
您需要阅读离散傅里叶变换。
对于实值时域信号,DFT 具有共轭对称性:
F(k) = conj(F(Nk)),
与 N 样本数。通过对非对称频域信号进行逆变换,您可以获得复值时域信号,但由于您使用复数到实数变换,因此实际上只计算了该结果的实部。您在这里丢弃了一半的数据。然后前向变换返回这个变换信号的 DFT。因为您的时域信号现在是实值的,所以您的频域结果具有共轭对称性。
推荐阅读
- python - python3.6支持的库函数是否也被python3.7支持?
- c++ - 在 C++ 中打印时只显示一个字符
- javascript - 在没有不必要空格的情况下替换句子中的单词?
- c# - 没有流的 Image.FromFile 内存不足
- django - 如何在 django-tables2 的列前添加空格和 $
- java - 内存数据库中的 H2 在列名和我想使用的值之间感到困惑
- java - Eclipse 4-10 64bit:无法解析 SWT 库
- reactjs - React Native - 在 WebView 中设置 localStorage
- django - 有什么区别:Django,Apache,AWS
- c++ - 矢量如何找到第一个和最后一个当前值