繁体   English   中英

C#中的逆FFT

[英]Inverse FFT in C#

我正在编写程序性音频文件的应用程序,我必须分析我的新文件,获取其频谱并在其计算中更改它。

我想用快速傅立叶变换(FFT)来做到这一点。 这是我的递归C#FFT:

void ft(float n, ref Complex[] f)
{
    if (n > 1)
    {
        Complex[] g = new Complex[(int) n / 2];
        Complex[] u = new Complex[(int) n / 2];

        for (int i = 0; i < n / 2; i++)
        {
            g[i] = f[i * 2];
            u[i] = f[i * 2 + 1];
        }

        ft(n / 2, ref g);
        ft(n / 2, ref u);

        for (int i = 0; i < n / 2; i++)
        {
            float a = i;
            a = -2.0f * Mathf.PI * a / n;
            float cos = Mathf.Cos(a);
            float sin = Mathf.Sin(a);
            Complex c1 = new Complex(cos, sin);
            c1 = Complex.Multiply(u[i], c1);
            f[i] = Complex.Add(g[i], c1);

            f[i + (int) n / 2] = Complex.Subtract(g[i], c1);
        }
    }
}

鼓舞人心的例子是 来自维基

然后我将我的结果与来自wolframalpha的结果进行比较,输入相同的输入为0.6,0.7,0.8,0.9但结果并不相同。 我的结果是Wolfram的两倍,虚部是Wolfram的-2倍。

另外,wiki表示可以用FFT计算FFT的逆

这个

但我比较输入和输出,它们是不同的。

有谁知道什么是错的?

不同的实现通常使用离散傅立叶变换(DFT)的不同定义,具有相应不同的结果。 实现之间的对应关系通常相当简单(例如缩放因子)。

更具体地说,您的实现基于以下DFT定义:

OP的DFT定义

另一方面,默认情况下Wolfram alpha使用一个定义 ,在调整为基于0的索引后,它看起来像:

Wolfram alpha默认DFT定义

相应地,可以将您的实现结果转换为匹配Wolfram alpha的:

void toWolframAlphaDefinition(ref Complex[] f)
{
  float scaling = (float)(1.0/Math.Sqrt(f.Length));
  for (int i = 0; i < f.Length; i++)
  {
    f[i] = scaling * Complex.Conjugate(f[i]);
  }
}

现在,使用正向变换计算逆DFT,直接实现公式

OP的反公式

你提供的将是:

void inverseFt(ref Complex[] f)
{
  for (int i = 0; i < f.Length; i++)
  {
    f[i] = Complex.Conjugate(f[i]);
  }
  ft(f.Length, ref f);
  float scaling = (float)(1.0 / f.Length);
  for (int i = 0; i < f.Length; i++)
  {
    f[i] = scaling * Complex.Conjugate(f[i]);
  }
}

调用ft的原始序列0.6, 0.7, 0.8, 0.9因此应该让你变换序列3, -0.2+0.2j, -0.2, -0.2-0.2j

进一步呼吁inverseFt这个变换顺序则应该让你回到你原来的顺序0.6, 0.7, 0.8, 0.9 (一些合理的浮点误差范围内),如在此现场演示

暂无
暂无

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

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