FFTW库:验证傅立叶变换导数属性

时间:2018-02-15 11:02:27

标签: c signal-processing fft fftw

我正在尝试验证与fftw库的这种关系:

enter image description here

因此,我选择f为高斯,计算其导数的傅里叶变换,并将其与高斯的傅里叶变换乘以ik进行比较。这是我得到的:

enter image description here

这很奇怪,特别是因为高斯衍生物(即红色的)的傅里叶变换图在原点不是0,而应该是(我用解析的那个检查)。

代码对我来说似乎没问题,无论如何它(我正在使用C):

int main() {

    int i, N = 100;
    double v[N], x[N], k[N/2+1], vd[N];
    double dx = 2*pi/N, dk=2*pi/(N*dx), tmp;
    fftw_complex *out;
    fftw_plan forward,inverse;

    out = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex )*( N/2 + 1 )); 


    forward = fftw_plan_dft_r2c_1d(N, v, out, FFTW_ESTIMATE);
    inverse = fftw_plan_dft_c2r_1d(N, out, vd, FFTW_ESTIMATE);

    //Initialise arrays 

    for( i = 0; i < N; i++ ) {   
            x[i] = dx*i;
            v[i] = -2*x[i]*exp( -pow( x[i], 2) );

            printf( " %le %le \n ", x[i], v[i] );
    }  


    for( i = 0; i < N; i++ ) {
       k[i]=i*dk;
    }

    k[N/2]=0.;

    //Compute fft
    fftw_execute( forward ); 

    //Print the results

    for( i = 0; i < N/2 + 1 ; i++ ) {
        printf( "%le %le %le \n", i*dk, out[i][0], out[i][1] );
    }

    //Multiply by ik 

    for( i = 0; i < ( N/2 + 1 ); i++ ) {

            tmp=out[i][0];
            out[i][0]=-k[i]*out[i][1];
            out[i][1]=k[i]*tmp;

            printf( "%le %le %le \n", i*dk, out[i][0], out[i][1] );

    }

    fftw_destroy_plan(forward);
    fftw_destroy_plan(inverse);
    fftw_free(out);

    return 0;  
}

有谁能告诉我我做错了什么?

1 个答案:

答案 0 :(得分:3)

衍生高斯的离散化信号应该是:

        x[i] = dx*i;
        v[i] = -2*x[i]*exp( -pow( x[i], 2) );

然而,离散傅里叶变换对应于周期性信号的傅里叶变换。实际上,强调离散函数被写成正弦波的无限加权和。

因此,当应用DFT时,上面的离散化信号对应于高斯导数的周期性一半。实际上,它的平均值(零频率)不为零,因为所有值都是负值。

为了模仿高斯(或有限&#34;范围的任何其他信号)的导数,必须覆盖整个信号范围。因此,必须选择dx dx*N>>sigma,其中sigma是高斯的标准偏差。并且必须涵盖该功能的所有支持,包括衍生产品的积极方面。

你可以试试像:

        double sigma=dx*N*0.1;
        x[i] = dx*i-dx*(N/2);
        v[i] = -2*x[i]*exp( -pow( x[i]/sigma, 2) );

由于标准差的值,必须留下缩放。

DFT仍然可用于非周期函数,但非周期函数将使用window映射到周期函数。这里观察到的是应用矩形窗口,进行周期化然后导出与导出,应用矩形窗口并最终进行周期化不同。虽然都是线性的,但这些操作员不通勤!