简体   繁体   English

C# FFT 实施未产生预期结果

[英]C# FFT Implementation not producing expected results

I'm trying to implement, in C#, for my own learning, an FFT algorithm described here:为了我自己的学习,我正在尝试在 C# 中实现此处描述的 FFT 算法:

https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm

under "Data reordering, bit reversal, and in-place algorithms".在“数据重新排序、位反转和就地算法”下。

My code is as follows, with some background operator overloading for the "cplx" structure to allow me to do arithmetic on these objects.我的代码如下,为“cplx”结构重载了一些后台运算符,以允许我对这些对象进行算术运算。

Bitreverse seems to work fine, and so does the "twiddle factor" calculation, so I'm not sure where I've gone wrong. Bitreverse 似乎工作正常,“旋转因子”计算也是如此,所以我不确定我哪里出错了。 The code looks awfully similar to the pseudocode given on the wiki page.该代码看起来与 wiki 页面上给出的伪代码非常相似。

    public cplx[] FFT(cplx[] x)
    {
        //Bitreverse Copy
        cplx[] a = BitReverse(x);

        //Number of points
        int n = a.Length;

        for (int s = 1; s <= Math.Log(n); s++)
        {
            int m = (int)Math.Pow(2,s);
            cplx w_m = Omega(m);

            for (int k = 0; k < n; k += m)
            {
                cplx w = new cplx(1, 0);

                for(int j = 0; j < m/2; j++)
                {
                    cplx t = w * a[k + j + (m / 2)];
                    cplx u = a[k + j];

                    a[k + j] = u + t;
                    a[k + j + (m / 2)] = u - t;

                    w = w * w_m;
                }
            }
        }

        return a;
    }

I'm testing it with an input array of an origin-impulse with 8 samples, which should produce a constant output.我正在使用具有 8 个样本的原点脉冲的输入数组对其进行测试,这应该会产生一个常数 output。

Instead, I'm getting 4 ones and 4 zeros, in that order.相反,我按顺序得到 4 个 1 和 4 个 0。

As an aside, I assume that in the pseudocode:顺便说一句,我假设在伪代码中:

for k = 0 to n-1 by m

Refers to for(k = 0; k < n; k += m) although I'm not sure that's right.for(k = 0; k < n; k += m)虽然我不确定这是对的。

Hopefully someone can shed some light on my incompetence!希望有人能对我的无能有所了解!

Cheers.干杯。

Here's the code for bitreversal and the omega calculation.这是位反转和欧米茄计算的代码。

       private int Rev(int x, int k)
    {
        int reversed = 0;

        for (int i = 0; i < k; i++)
        {
            reversed |= (x & (1 << i)) != 0 ? 1 << (k - 1 - i) : 0;
        }

        return reversed;
    }

    public cplx[] BitReverse(cplx[] x)
    {
        cplx[] r = new cplx[x.Length];

        int bits = (int)Math.Log(x.Length, 2);

        for(int k = 0; k < x.Length; k++)
        {
            r[Rev(k, bits)] = x[k];
        }

        return r;
    }

    private cplx Omega(int m)
    {
        float x = (- 2 * (float)Math.PI) / m;

        return new cplx((float)Math.Cos(x), (float)(Math.Sin(x)));
    }

I should have been using log2(n) when I was using Math.Log() .我应该在使用Math.Log()时使用log2(n) ) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM