2013-10-10 96 views
2

我有一个奇怪的问题与离散fft。我知道高斯函数exp(-x^2/2)的傅里叶变换又是相同的高斯函数exp(-k^2/2)。我试图用MatLab和FFTW中的一些简单代码来测试,但我得到了奇怪的结果。FFTW和fft与MatLab

首先,结果的虚部不是零(在MatLab中),因为它应该是。

其次,实部的绝对值是高斯曲线,但没有绝对值的一半的模式具有负系数。更确切地说,每个第二模式都有一个系数,它是应该是负数的系数。第三,得到的高斯曲线的峰值(在取实部的绝对值之后)不是一而是高得多。其高度与x轴上的点数成正比。但是,比例因子不是1,但接近1/20。

任何人都可以解释我做错了什么?

这里是MATLAB代码,我用:

function [nooutput,M] = fourier_test 

    Nx = 512;  % number of points in x direction 

    Lx = 50;  % width of the window containing the Gauss curve 

    x = linspace(-Lx/2,Lx/2,Nx);  % creating an equidistant grid on the x-axis 

    input_1d = exp(-x.^2/2);     % Gauss function as an input 
    input_1d_hat = fft(input_1d);   % computing the discrete FFT 
    input_1d_hat = fftshift(input_1d_hat); % ordering the modes such that the peak is centred 

    plot(real(input_1d_hat), '-') 
    hold on 
    plot(imag(input_1d_hat), 'r-') 
+0

您可能将* continuous * FT与* discrete * FT混合在一起。高斯的连续FT是高斯函数,但我不确定DFT(FFT)是如此。 –

+2

当然,离散性使得事物不精确,但离散FT被创建为连续FT的近似值。当点数和间隔足够大时,这里就是这种情况,近似值应该是好的。会有一些偏差,但他们绝对不应该那么大,如此系统。另外,当我增加Nx和Lx时,结果不会改变,这意味着收敛是可以实现的。 –

+1

我认为在你的DFT情况下可能会出现一个隐含的时间偏移,这就意味着频域的相位旋转 - 我认为幅度是正确的,相位是一条直线(如果你是模2π不解开它,即锯齿)。 –

回答

4

答案基本上是保罗 - [R表明在他的第二个意见,你介绍的相移(线性依赖于频率),因为中心由input_1d_hat描述的高斯实际上在k>0,其中k+1input_1d_hat的索引。相反,如果你Center的资料(这样input_1d_hat(1)对应中心)如下你在频域中的相位校正高斯:

Nx = 512;  % number of points in x direction 
    Lx = 50;  % width of the window containing the Gauss curve 

    x = linspace(-Lx/2,Lx/2,Nx);  % creating an equidistant grid on the x-axis 

    %%%%%%%%%%%%%%%% 
    x=fftshift(x); % <-- center 
    %%%%%%%%%%%%%%%% 

    input_1d = exp(-x.^2/2);     % Gauss function as an input 
    input_1d_hat = fft(input_1d);   % computing the discrete FFT 
    input_1d_hat = fftshift(input_1d_hat); % ordering the modes such that the peak is centered 

    plot(real(input_1d_hat), '-') 
    hold on 
    plot(imag(input_1d_hat), 'r-') 

从DFT的定义,如果高斯不集中等那最大值发生在k=0,你会看到相位扭曲。 fftshift的效果是执行数据集左侧和右侧的循环移位或交换,这相当于将峰的中心移至k=0

至于幅度缩放,这是在Matlab中实现的DFT的定义的问题。从对FFT的文档:

For length N input vector x, the DFT is a length N vector X, 
with elements 
       N 
    X(k) =  sum x(n)*exp(-j*2*pi*(k-1)*(n-1)/N), 1 <= k <= N. 
       n=1 
The inverse DFT (computed by IFFT) is given by 
       N 
    x(n) = (1/N) sum X(k)*exp(j*2*pi*(k-1)*(n-1)/N), 1 <= n <= N. 
       k=1 

注意的是,在向前迈进了一步的总和由N.标准化因此如果增加点Nx的数量的总和,同时保持宽度高斯函数常数的Lx,您将按比例增加X(k)

至于信号泄漏到假想频率维度,也就是说是由于DFT,这导致截断和其它效果的离散形式,如再由Paul R.注意到如果减少Lx同时保持恒定Nx,你应该看到在虚拟维数相对于的信号量减少到实际维度(比较光谱,同时保持实际维度中的峰值强度相等)。

你会发现类似问题的其他答案herehere

+0

谢谢你的提示。但是,我仍然不明白为什么我应该用fftshift来更改x阵列。你能详细解释一下吗?我认为这是通过在输出上做fftshift来提供的。为什么我的版本中的高斯有效地以x> 0为中心? –

+0

你对我有其他两个问题的原因有什么想法吗?我实施你的解决方案。它修复了输出两部分的振荡,但虚部仍然不为零。而且,当我改变点数Nx时,它保持不变,而实部的峰值与Nx成比例变化。任何想法为什么这是这样的? –

+0

任何想法如何解决与FFTW使用C++时的问题?在那里,我得到了同样令人讨厌的震荡。 你能给出关于这个问题的数学工具参考吗?我没有看到关于fft例程解释页面上的评论。 –