C++ 为什么我的2D IDFT产生预期振幅的两倍?(FFTW)

C++ 为什么我的2D IDFT产生预期振幅的两倍?(FFTW),c++,fftw,dft,C++,Fftw,Dft,我使用复杂到真实的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 * logi

我使用复杂到真实的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
int N=8;
int逻辑_宽度=N/2+1;//频域数据的逻辑宽度
double*T=新的double[N*N];
fftw_复数*F=(fftw_复数*)fftw_alloc_复数(N*逻辑宽度);
fftw_平面图=fftw_平面图_dft_c2r_2d(N,N,F,T,fftw_度量);
//将所有频率模式初始化为0
对于(int i=0;i
printTime()的输出

IDFT后信号的振幅似乎为32。然而,考虑到唯一的贡献模式是
k[0,1]=16+0i
,我希望它是16


为什么会发生这种情况?我是否应该在执行IDFT之前以某种方式转换信号?

您正在应用C2R转换。正如我在中所解释的,它需要共轭对称输入。你提供一半的输入,另一半假设是你输入的共轭对称。因此,您将设置两个模式,而不是一个,每个模式的幅值为16。它们一起构成振幅为32的正弦曲线


请注意,FFTW的逆DFT不会规格化。DFT有不同的定义,有的将归一化放在正变换中,有的放在逆变换中。FFTW根本不正常化。这导致IFFT(FFT(f))=Nf(N为样本数)。您需要在某个地方手动规范化,以保持相等。最常见的是,逆变换是规范化的。在你的例子中,这将导致一个振幅为32/N的正弦波,这是你在大多数信号处理教科书中看到的。例如,在

页7中,我不知道<代码> PrimTime[()] />代码>如何计算幅度,但是考虑函数<代码> A*Sin(x)< /C> >在<代码> -a < /COD>和<代码> < < /代码>之间产生值,因此最大值和最小值之间的差值是<代码> 2×A < /代码>。<代码> PrimTimeType()/代码>不计算任何内容。它只打印四舍五入到2位小数的时域值。在这种情况下,最大值和最小值分别为32和-32,即使输入形式为
16.0*cos(x)
。进行fft时,通常需要进行重新缩放或标准化。不过我还以为是通过
N
。所以我不太明白。请看fftw文档Hi Cris,再次感谢您的回复。我注意到,对于某些模式,振幅的倍增并没有发生。我假设是这样,因为它们在频域中没有共轭?因为我意识到我的解释可能有点糟糕,我把它想象成:时域是n0乘n1。灰色单元格是冗余的,不由FFTW计算。红细胞在时域中没有结合物。是吗?@Naemesis是的,没错。可以说,红细胞是它们自己的结合物,因此被认为是真正有价值的。顺便说一下,对于一个奇数大小的变换,您只有一个这样的列。嗨,克里斯,很抱歉再次打扰您,但我一直在努力解决另一个与复杂DFT相关的问题。你介意看一下吗?