C++ 为什么我的数据在频域中;“镜像”;使用FFTW在DFT中执行(2d)IDFT时?

C++ 为什么我的数据在频域中;“镜像”;使用FFTW在DFT中执行(2d)IDFT时?,c++,fft,fftw,C++,Fft,Fftw,我通过在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+

我通过在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);
int N=16;//数据的维度
int逻辑_宽度=(N/2)+1;//频域的逻辑宽度
double*real=新的double[N*N];
fftw_complex*complex=(fftw_complex*)fftw_malloc(sizeof(fftw_complex)*N*逻辑_宽度);
fftw_plan plan=fftw_plan_dft_r2c_2d(N,N,实,复,fftw_估计);
fftw_平面iplan=fftw_平面dft_c2r_2d(N,N,复,实,fftw_估计);
//将所有实际数据初始化为0
对于(int i=0;iDFT之前打印
打印复合体(复合体,N);
//IDFT
fftw_执行(iplan);
//DFT背面
fftw_执行(计划);
//在IDFT->DFT后打印
printComplex(复数,N,真);//通过“真”将振幅除以N*N
//清理
fftw销毁计划(计划);
fftw销毁计划(iplan);
删除[]不动产;
无fftw_(复合);

两个
printComplex(…)
调用的输出可以在上面的问题中看到。

您需要阅读离散傅里叶变换

对于实值时域信号,DFT具有共轭对称性:

F(k)=conj(F(N-k))


用N表示样本数。通过对非对称频域信号进行逆变换,可以获得复值时域信号,但由于使用复到实变换,因此实际上只计算该结果的实部。你在这里浪费了一半的数据。然后,前向变换返回该变换信号的DFT。因为您的时域信号现在是实值,所以您的频域结果具有共轭对称性。

嗨,克里斯,谢谢您的回答。我在这里发布了另一个(类似于后续)问题:如果你有时间,你介意看一下吗?