为什么我的 2D IDFT 产生双倍的预期振幅? (FFTW)
Why does my 2D IDFT produce double the expected amplitudes? (FFTW)
我正在使用复数到真实的 2D IDFT 将复杂信号可视化为图像。我通过手动设置模式来初始化复杂的频域。但是,某些模式产生的实际输出似乎是预期的两倍。
我的代码:
int N = 8;
int logical_width = N / 2 + 1; // Logical width of frequency domain data
double* T = new double[N * N];
fftw_complex* F = (fftw_complex*)fftw_alloc_complex(N * logical_width);
fftw_plan plan = fftw_plan_dft_c2r_2d(N, N, F, T, FFTW_MEASURE);
// Initialize all frequency modes to 0
for (int i = 0; i < N * logical_width; i++) {
F[i][REAL] = 0.0;
F[i][IMAG] = 0.0;
}
F[1][REAL] = 16.0; // Set mode k[0, 1]
fftw_execute(plan);
printTime(T, N); // Print time domain to console
printTime()
的输出:
经过IDFT后信号的幅值似乎是32。但是,我希望它是 16,因为唯一的贡献模式是 k[0, 1] = 16 + 0i
.
为什么会这样?我应该在执行 IDFT 之前以某种方式转换信号吗?
您正在应用 C2R 转换。正如我在 中解释的那样,它需要一个共轭对称输入。您提供一半的输入,另一半假定为您输入的共轭对称。因此,您设置的是两种模式,而不是一种,每种模式的幅度均为 16。它们一起形成幅度为 32 的正弦波。
请注意,FFTW 的逆 DFT 未归一化。 DFT有不同的定义,有的将归一化放在正变换中,有的放在逆变换中。 FFTW 根本没有归一化。这导致 IFFT(FFT(f)) = Nf(N 为样本数)。您需要在某处手动规范化以保持相等性。最常见的逆变换是归一化的。在您的情况下,这将导致振幅为 32/N 的正弦波,这就是您在大多数信号处理教科书中看到的内容。例如参见 [=11=].
中的第 7 页
我正在使用复数到真实的 2D IDFT 将复杂信号可视化为图像。我通过手动设置模式来初始化复杂的频域。但是,某些模式产生的实际输出似乎是预期的两倍。
我的代码:
int N = 8;
int logical_width = N / 2 + 1; // Logical width of frequency domain data
double* T = new double[N * N];
fftw_complex* F = (fftw_complex*)fftw_alloc_complex(N * logical_width);
fftw_plan plan = fftw_plan_dft_c2r_2d(N, N, F, T, FFTW_MEASURE);
// Initialize all frequency modes to 0
for (int i = 0; i < N * logical_width; i++) {
F[i][REAL] = 0.0;
F[i][IMAG] = 0.0;
}
F[1][REAL] = 16.0; // Set mode k[0, 1]
fftw_execute(plan);
printTime(T, N); // Print time domain to console
printTime()
的输出:
经过IDFT后信号的幅值似乎是32。但是,我希望它是 16,因为唯一的贡献模式是 k[0, 1] = 16 + 0i
.
为什么会这样?我应该在执行 IDFT 之前以某种方式转换信号吗?
您正在应用 C2R 转换。正如我在
请注意,FFTW 的逆 DFT 未归一化。 DFT有不同的定义,有的将归一化放在正变换中,有的放在逆变换中。 FFTW 根本没有归一化。这导致 IFFT(FFT(f)) = Nf(N 为样本数)。您需要在某处手动规范化以保持相等性。最常见的逆变换是归一化的。在您的情况下,这将导致振幅为 32/N 的正弦波,这就是您在大多数信号处理教科书中看到的内容。例如参见 [=11=].
中的第 7 页