为什么我的频域数据“镜像"?使用FFTW将(2d)IDFT转换为DFT时? [英] Why is my data in the frequency domain "mirrored" when performing (2d) IDFT into DFT using FFTW?

查看:63
本文介绍了为什么我的频域数据“镜像"?使用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;//数据维度int logical_width =(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,real,complex,FFTW_ESTIMATE);fftw_plan iplan = fftw_plan_dft_c2r_2d(N,N,复数,实数,FFTW_ESTIMATE);//将所有实际数据初始化为0for(int i = 0; i< N * N; i ++){实[i] = 0.0;}//将所有复杂数据初始化为0for(int i = 0; i< N * logical_width; i ++){complex [i] [REAL] = 0.0;complex [i] [IMAG] = 0.0;}//设置前4个垂直模式complex [1 * logical_width] [REAL] = 32;complex [2 * logical_width] [REAL] = 16;complex [3 * logical_width] [REAL] = 8;complex [4 * logical_width] [REAL] = 4;//在IDFT之前打印->DFTprintComplex(complex,N);//IDFTfftw_execute(iplan);//DFT返回fftw_execute(plan);//在IDFT之后打印->DFTprintComplex(complex,N,true);//传递true以将幅度除以N * N//清理fftw_destroy_plan(plan);fftw_destroy_plan(iplan);delete []实;fftw_free(complex); 

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

解决方案

您需要阅读离散傅立叶变换.

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

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

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

I am manually initializing a state in the 2d frequency domain by setting the real components of certain modes in a 16x16 data set. I then perform a 2d IDFT to acquire the real domain data. This all works as expected.

I then perform a DFT on the real domain data to get back (what should be) identical frequency modes to those that I manually initialized. However, they come back with their amplitudes halfed, and their vertical frequencies "mirrored". To illustrate:

Input modes:
k[1, 0]: 32 + 0i
k[2, 0]: 16 + 0i
k[3, 0]: 8 + 0i
k[4, 0]: 4 + 0i

Output modes after 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

My question is, why are the modes in the output of the DFT not the same as the initial input to the IDFT?

For some extra context, the problem I am having with this is that I am using this data to "solve" the heat equation, and higher frequency signals get scaled down very quickly. So the k[12, 0] to k[15, 0] modes don't actually contribute much after a few time steps.

Code to reproduce problem:

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);

The output of the two printComplex(...) calls can be seen in the question above.

解决方案

You need to read up on the Discrete Fourier Transform.

For a real-valued time domain signal, the DFT has a conjugate symmetry:

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

with N the number of samples. By inverse transforming a non-symmetric frequency-domain signal, you obtain a complex-valued time-domain signal, but because you use a complex-to-real transform, only the real part of this result is actually computed. You’re throwing away half the data here. The forward transform then returns the DFT of this transformed signal. Because your time-domain signal is now real-valued, your frequency-domain result has conjugate symmetry.

这篇关于为什么我的频域数据“镜像"?使用FFTW将(2d)IDFT转换为DFT时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆