为什么我的2D IDFT会产生两倍的预期幅度? 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()输出

Output of printTime():

IDFT之后,信号的振幅似乎为32。但是,由于唯一的贡献模式是k[0,1] = 16 + 0i,因此我希望它是16。

为什么会这样?我应该在执行IDFT之前以某种方式转换信号吗?

解决方法

您正在应用C2R转换。正如我在my answer to your previous question中所解释的那样,它期望共轭对称输入。您提供一半的输入,假定另一半是您输入的共轭对称。因此,您要设置两个模式,而不是一个,每个模式的幅度为16。它们一起形成幅度为32的正弦曲线。

请注意,FFTW的逆DFT不能归一化。 DFT有不同的定义,一些定义将正则化放置在正向变换中,有些定义将其放置在逆变换中。 FFTW完全不规范。这导致IFFT(FFT(f))= Nf(样本数为N)。您需要在某个地方手动标准化以保持等式。最常见的是将逆变换归一化。在您的情况下,这将导致振幅为32 / N的正弦波,这是您在大多数信号处理教科书中都会看到的。例如,请参见this PDF中的第7页。