我正在写一个非常简单的就地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。
答案 0 :(得分:9)
我相信你在本节中有错误
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);
}
您应该将数据[k]替换为数据[n]
修改强>
你也在破坏你的数据:
data[k] = Math.Sqrt(real[k] * real[k] + imag[k] * imag[k]);
你必须在其他地方或以后存储复数的模数。如果模数是你想要的,并且你想将它存储在data []中你必须在计算变换后编写另一个循环。整个数据[]是计算每个真实[k]和imag [k]所必需的。
答案 1 :(得分:7)
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;
}