简体   繁体   English

C#中的逆FFT

[英]Inverse FFT in C#

I am writing an application for procedural audiofiles, I have to analyze my new file, get its frequency spectrum and change it in its calculated. 我正在编写程序性音频文件的应用程序,我必须分析我的新文件,获取其频谱并在其计算中更改它。

I want to do this with the Fast Fourier Transform (FFT). 我想用快速傅立叶变换(FFT)来做到这一点。 This is my recursive 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);
        }
    }
}

The inspiring example was 鼓舞人心的例子是 来自维基

I then compared my results with those from wolframalpha for the same input 0.6,0.7,0.8,0.9 but the results aren't be the same. 然后我将我的结果与来自wolframalpha的结果进行比较,输入相同的输入为0.6,0.7,0.8,0.9但结果并不相同。 My results are twice as big than Wolfram's and the imaginary part are the -2 times of Wolfram's. 我的结果是Wolfram的两倍,虚部是Wolfram的-2倍。

Also, wiki indicates that the inverse of FFT can be computed with 另外,wiki表示可以用FFT计算FFT的逆

这个

But I compare inputs and outputs and they are different. 但我比较输入和输出,它们是不同的。

Has anyone an idea what's wrong? 有谁知道什么是错的?

Different implementations often use different definitions of the Discrete Fourier Transform (DFT), with correspondingly different results. 不同的实现通常使用离散傅立叶变换(DFT)的不同定义,具有相应不同的结果。 The correspondence between implementations is usually fairly trivial (such as a scaling factor). 实现之间的对应关系通常相当简单(例如缩放因子)。

More specifically, your implementation is based on the following definition of the DFT: 更具体地说,您的实现基于以下DFT定义:

OP的DFT定义

On the other hand, Wolfram alpha by default uses a definition , which after adjusting to 0-based indexing looks like: 另一方面,默认情况下Wolfram alpha使用一个定义 ,在调整为基于0的索引后,它看起来像:

Wolfram alpha默认DFT定义

Correspondingly, it is possible to transform the result of your implementation to match Wolfram alpha's with: 相应地,可以将您的实现结果转换为匹配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]);
  }
}

Now as far as computing the inverse DFT using the forward transform, a direct implementation of the formula 现在,使用正向变换计算逆DFT,直接实现公式

OP的反公式

you provided would be: 你提供的将是:

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]);
  }
}

Calling ft on the original sequence 0.6, 0.7, 0.8, 0.9 should thus get you the transformed sequence 3, -0.2+0.2j, -0.2, -0.2-0.2j . 调用ft的原始序列0.6, 0.7, 0.8, 0.9因此应该让你变换序列3, -0.2+0.2j, -0.2, -0.2-0.2j

Further calling inverseFt on this transform sequence should then bring you back to your original sequence 0.6, 0.7, 0.8, 0.9 (within some reasonable floating point error), as shown in this live demo . 进一步呼吁inverseFt这个变换顺序则应该让你回到你原来的顺序0.6, 0.7, 0.8, 0.9 (一些合理的浮点误差范围内),如在此现场演示

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

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