快速傅里叶变换(二)
FFT算法参考本书第12章
FFT算法主要流程:
1. 把一个N点的时域信号分解成N个单点时域信号
2. 计算N个单点时域信号的频谱
3. 将N个频谱合成一个N点的频谱。
public struct Complex
{
public double X;
public double Y;
public double M
{
get
{
return Math.Sqrt(this.X * this.X + this.Y * this.Y);
}
}
public double E
{
get
{
return this.X * this.X + this.Y * this.Y;
}
}
public Complex(double x, double y)
{
this.X = x;
this.Y = y;
}
}
//real DFT & real FFT
public static class FFT
{
//1.[in] double[] x_R real port time domain ,当用于实数的fft时,可以把虚部设为0;
//2[in] double[] x_I imagine part
//3 [out] frequency domain real and imagine in complex.x and comple.y//频域的实部与虚部。
public static Complex[] FFT_radix2(double[] x_R, double[] x_I)
{
int N = x_R.Length;
int M = (int)Math.Log(N, 2);////蝶形运算的级数
for (int L = 1; L <= M; L++)
{
int LE = (int)Math.Pow(2, L);
int b = LE / 2; ////step
//////////////蝶形因子////////////
double UR = 1.0;
double UI = 0.0;
double w_re = Math.Cos(Math.PI / b);
double w_im = -Math.Sin(Math.PI / b);
double TR, TI;
////////////////蝶形运算//////////////
for (int j = 0; j < b; j++)
{
for (int i = j; i < N; i = i + LE)
{
int c = i + b;
TR = x_R[c] * UR - x_I[c] * UI;
TI = x_R[c] * UI + x_I[c] * UR;
x_R[c] = x_R[i] - TR;
x_I[c] = x_I[i] - TI;
x_R[i] = x_R[i] + TR;
x_I[i] = x_I[i] + TI;
}
TR = UR * w_re - UI * w_im;
TI = UR * w_im + UI * w_re;
UR = TR;
UI = TI;
}
}
List<Complex> y_out = new List<Complex>();
for (int i = 0; i < N; i++)
{
Complex data_in = new Complex(x_R[i], x_I[i]);
y_out.Add(data_in);
}
return y_out.ToArray();
}