简单的就地离散傅立叶变换(DFT)

我正在写一个非常简单的就地DFT。 我正在使用此处显示的公式: http : //en.wikipedia.org/wiki/Discrete_Fourier_transform#Definition以及Euler的公式,以避免仅为此使用复数类。 到目前为止我有这个:

private void fft(double[] data) { double[] real = new double[256]; double[] imag = new double[256]; double pi_div_128 = -1 * Math.PI / 128; for (int k = 0; k < 256; k++) { for (int n = 0; n < 256; n++) { real[k] += data[k] * Math.Cos(pi_div_128 * k * n); imag[k] += data[k] * Math.Sin(pi_div_128 * k * n); } data[k] = Math.Sqrt(real[k] * real[k] + imag[k] * imag[k]); } } 

但是Math.Cos和Math.Sin术语最终都是正面和负面的,所以当我添加这些术语乘以数据[k]时,它们会被取消,我只会获得一些极小的值。 我看到它是如何发生的,但我无法理解我的代码是如何错误地代表数学的。 任何帮助表示赞赏。 仅供参考,我必须自己编写,我知道我可以获得现成的FFT。

我相信你在本节中有错误

 for (int n = 0; n < 256; n++) { real[k] += data[k] * Math.Cos(pi_div_128 * k * n); imag[k] += data[k] * Math.Sin(pi_div_128 * k * n); } 

你应该用数据[n]替换数据[k]

编辑:

您还在破坏行中的数据:

 data[k] = Math.Sqrt(real[k] * real[k] + imag[k] * imag[k]); 

你必须在其他地方或以后存储复数的模数。 如果模数是你想要的,并且你想将它存储在data []中你必须在计算变换后编写另一个循环。整个数据[]是计算每个真实[k]和imag [k]所必需的。

 private double[] dft(double[] data) { int n = data.Length; int m = n;// I use m = n / 2d; double[] real = new double[n]; double[] imag = new double[n]; double[] result = new double[m]; double pi_div = 2.0 * Math.PI / n; for (int w = 0; w < m; w++) { double a = w * pi_div; for (int t = 0; t < n; t++) { real[w] += data[t] * Math.Cos(a * t); imag[w] += data[t] * Math.Sin(a * t); } result[w] = Math.Sqrt(real[w] * real[w] + imag[w] * imag[w]) / n; } return result; }