离散傅立叶变换

时间:2011-09-28 11:46:33

标签: c# math fft dft

我目前正在尝试编写一些傅里叶变换算法。我从一个简单的DFT算法开始,如数学定义中所述:

public class DFT {
    public static Complex[] Transform(Complex[] input) {
        int N = input.Length;

        Complex[] output = new Complex[N];

        double arg = -2.0 * Math.PI / (double)N;
        for (int n = 0; n < N; n++) {
            output[n] = new Complex();
            for (int k = 0; k < N; k++)
                output[n] += input[k] * Complex.Polar(1, arg * (double)n * (double)k);
        }
        return output;
    }
}

所以我用以下代码测试了这个算法:

    private int samplingFrequency = 120;
    private int numberValues = 240;

    private void doCalc(object sender, EventArgs e) {
        Complex[] input = new Complex[numberValues];
        Complex[] output = new Complex[numberValues];

        double t = 0;
        double y = 0;
        for (int i = 0; i < numberValues; i++) {
            t = (double)i / (double)samplingFrequency;
            y = Math.Sin(2 * Math.PI * t);
            input[i] = new Complex(y, 0);
        }

        output = DFT.Transform(input);

        printFunc(input);
        printAbs(output);
    }

转换工作正常,但仅当numberValues是samplingFrequency的多个数字时(在这种情况下:120,240,360,...)。这是我的240个值的结果:

http://s1.directupload.net/images/110928/n3m8hqg6.jpg

改造工作正常。

如果我想计算280个值,我会得到这个结果:

http://s7.directupload.net/images/110928/qizoiqbt.jpg

如果我更改计算值的数量,为什么我得到的结果不正确? 我不确定我的问题是否是我的代码问题或对DFT的数学定义的误解。无论哪种方式,任何人都可以帮我解决我的问题吗?感谢。

2 个答案:

答案 0 :(得分:29)

您遇到的问题称为Spectral Leakage

这是因为傅里叶变换的基础数学假定从-infinity到+ infinity的连续函数。因此,您提供的样本范围有效地重复了无数次。如果你在窗口中没有完整数量的波形循环,那么两端就不会排成一行,你将会出现一个不连续的现象,表明其自身是频率模糊到任何一方。

处理此问题的常用方法称为Windowing。然而,这确实有一个缺点,因为它导致幅度稍微偏离。这是将要处理的整个样本窗口乘以某个函数的过程,该函数在窗口的两端趋于0,导致末端排列但有一些幅度失真,因为此过程会降低总信号功率。 / p>

总而言之,您的代码中没有错误,结果与预期一致。可以使用窗函数来减少伪影,但是这将影响幅度的准确性。您需要调查并确定最适合您项目要求的解决方案。

答案 1 :(得分:5)

您没有得到非周期性正弦曲线的错误结果。它们不仅仅是“文物”。您的结果实际上是更完整的DFT结果,您没有看到周期性正弦曲线。那些其他非零值包含有用信息,可用于例如插入单个非周期性孔径正弦波的频率。

DFT可以被认为是用正弦波卷积矩形窗口。这产生(非常接近)Sinc函数,其具有无限范围,但是在除了其中心DFT仓之外的每个DFT仓频率恰好为零,对于任何正好在DFT仓上居中的正弦曲线。只有当频率在FFT孔径中精确周期时才会发生这种情况,而不是任何其他频率。 Sinc函数有很多“驼峰”,它们都隐藏在你的第一个图中。