正向变换是正确的了,我测试过,但是逆变换出错了?请问问题在哪里?
ComplexNumber是复数的类,实现了复数的加减乘除法以及求倒数的运算。
using System;
using System.Collections.Generic;
using System.Text;
using ComplexNumber;using CN = ComplexNumber.ComplexNumber;namespace FFT
{
public class FFT
{
public static CN[] FastFourierTransformation(CN[] a, bool direct)
{
CN[] y=new CN[a.Length];
if (a.Length == 1)
{
y[0] = a[0].Clone();
return y;
}
CN[] y0 = new CN[a.Length / 2];
CN[] y1 = new CN[a.Length / 2];
CN[] a0 = new CN[a.Length / 2];
CN[] a1 = new CN[a.Length / 2];
for (int i = 0; i < a.Length / 2; i++)
{
a0[i] = a[2 * i];
a1[i] = a[2 * i + 1];
}
y0 = FastFourierTransformation(a0,direct);
y1 = FastFourierTransformation(a1,direct);
CN wn = CN.GetRootOfUnity(a.Length);
if (direct == false)
wn = wn.Invert();
CN w=(CN)1;
for (int i = 0; i < a.Length / 2; i++)
{
w *= wn;
y[i] = y0[i] + y1[i] * w;
y[i + a.Length / 2] = y0[i] - w * y1[i];
}
if (direct == false)
{
for (int i = 0; i < y.Length; i++)
y[i] /= (CN)y.Length;
}
return y; }
}
}namespace FFT
{
class Program
{
static void Main(string[] args)
{
double[] a = { 1, 2, 3, 1 };
double[] c = { 3, 2, 1, 2 };
ComplexNumber.ComplexNumber[] b = new ComplexNumber.ComplexNumber[a.Length];
for (int i = 0; i < a.Length; i++)
b[i] = (ComplexNumber.ComplexNumber)a[i];
ComplexNumber.ComplexNumber[] d = new ComplexNumber.ComplexNumber[c.Length];
for (int i = 0; i < a.Length; i++)
d[i] = (ComplexNumber.ComplexNumber)c[i];
ComplexNumber.ComplexNumber[] e = FFT.FastFourierTransformation(b, true);
ComplexNumber.ComplexNumber[] f = FFT.FastFourierTransformation(d, true); ComplexNumber.ComplexNumber[] g = FFT.FastFourierTransformation(e, false);
}
}
}
下面是ComplexNumber类的实现,也许会用到,不过应该是没有什么问题的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace ComplexNumber
{
public class ComplexNumber
{
public static double Error = 1e-20;
public static ComplexNumber GetRootOfUnity(int n)
{
ComplexNumber c = new ComplexNumber(Math.Cos(2*Math.PI / n), Math.Sin(2*Math.PI / n));
return c;
}
double RealPart;
double ImaginaryPart;
public ComplexNumber(double pReal, double pImaginary)
{
RealPart = pReal;
ImaginaryPart = pImaginary;
} public ComplexNumber()
: this(0, 0)
{ } public double Modulus { get { return Math.Sqrt(RealPart*RealPart + ImaginaryPart*ImaginaryPart); } }
public static explicit operator ComplexNumber(double d)
{
ComplexNumber c = new ComplexNumber(d, 0);
return c;
} public static ComplexNumber operator +(ComplexNumber a, ComplexNumber b)
{
ComplexNumber c = new ComplexNumber();
c.RealPart = a.RealPart + b.RealPart;
c.ImaginaryPart = a.ImaginaryPart + b.ImaginaryPart;
return c;
}
public static ComplexNumber operator -(ComplexNumber a, ComplexNumber b)
{
ComplexNumber c = new ComplexNumber();
c.RealPart = a.RealPart - b.RealPart;
c.ImaginaryPart = a.ImaginaryPart - b.ImaginaryPart;
return c;
} public static bool operator ==(ComplexNumber a,double b)
{
if (Math.Abs(a.ImaginaryPart) <=Error && Math.Abs(a.RealPart -b)<=Error)
return true;
return false;
} public static bool operator ==(ComplexNumber a,ComplexNumber b)
{
if (Math.Abs(a.ImaginaryPart-b.ImaginaryPart) <= Error && Math.Abs(a.RealPart - b.RealPart) <= Error)
return true;
return false;
} public static bool operator !=(ComplexNumber a, double b)
{
if (a == b)
return false;
return true;
} public static bool operator !=(ComplexNumber a, ComplexNumber b)
{
return !(a == b);
} public static ComplexNumber operator *(ComplexNumber a, ComplexNumber b)
{
ComplexNumber c = new ComplexNumber();
c.RealPart = a.RealPart * b.RealPart - a.ImaginaryPart * b.ImaginaryPart;
c.ImaginaryPart = a.RealPart * b.ImaginaryPart + a.ImaginaryPart * b.RealPart;
return c;
}
public ComplexNumber Invert()
{
ComplexNumber a = new ComplexNumber();
if (Math.Abs(ImaginaryPart) <= Error && Math.Abs(RealPart) <= Error)
throw (new ArgumentException("0 can not be inverted"));
a.ImaginaryPart = -ImaginaryPart / (RealPart * RealPart + ImaginaryPart * ImaginaryPart);
a.RealPart = RealPart / (RealPart * RealPart + ImaginaryPart * ImaginaryPart);
return a;
}
public ComplexNumber Clone()
{
ComplexNumber c = new ComplexNumber(RealPart, ImaginaryPart);
return c;
} public static ComplexNumber operator /(ComplexNumber a, ComplexNumber b)
{
ComplexNumber c = b.Invert();
return a*c;
}
}
}
ComplexNumber是复数的类,实现了复数的加减乘除法以及求倒数的运算。
using System;
using System.Collections.Generic;
using System.Text;
using ComplexNumber;using CN = ComplexNumber.ComplexNumber;namespace FFT
{
public class FFT
{
public static CN[] FastFourierTransformation(CN[] a, bool direct)
{
CN[] y=new CN[a.Length];
if (a.Length == 1)
{
y[0] = a[0].Clone();
return y;
}
CN[] y0 = new CN[a.Length / 2];
CN[] y1 = new CN[a.Length / 2];
CN[] a0 = new CN[a.Length / 2];
CN[] a1 = new CN[a.Length / 2];
for (int i = 0; i < a.Length / 2; i++)
{
a0[i] = a[2 * i];
a1[i] = a[2 * i + 1];
}
y0 = FastFourierTransformation(a0,direct);
y1 = FastFourierTransformation(a1,direct);
CN wn = CN.GetRootOfUnity(a.Length);
if (direct == false)
wn = wn.Invert();
CN w=(CN)1;
for (int i = 0; i < a.Length / 2; i++)
{
w *= wn;
y[i] = y0[i] + y1[i] * w;
y[i + a.Length / 2] = y0[i] - w * y1[i];
}
if (direct == false)
{
for (int i = 0; i < y.Length; i++)
y[i] /= (CN)y.Length;
}
return y; }
}
}namespace FFT
{
class Program
{
static void Main(string[] args)
{
double[] a = { 1, 2, 3, 1 };
double[] c = { 3, 2, 1, 2 };
ComplexNumber.ComplexNumber[] b = new ComplexNumber.ComplexNumber[a.Length];
for (int i = 0; i < a.Length; i++)
b[i] = (ComplexNumber.ComplexNumber)a[i];
ComplexNumber.ComplexNumber[] d = new ComplexNumber.ComplexNumber[c.Length];
for (int i = 0; i < a.Length; i++)
d[i] = (ComplexNumber.ComplexNumber)c[i];
ComplexNumber.ComplexNumber[] e = FFT.FastFourierTransformation(b, true);
ComplexNumber.ComplexNumber[] f = FFT.FastFourierTransformation(d, true); ComplexNumber.ComplexNumber[] g = FFT.FastFourierTransformation(e, false);
}
}
}
下面是ComplexNumber类的实现,也许会用到,不过应该是没有什么问题的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace ComplexNumber
{
public class ComplexNumber
{
public static double Error = 1e-20;
public static ComplexNumber GetRootOfUnity(int n)
{
ComplexNumber c = new ComplexNumber(Math.Cos(2*Math.PI / n), Math.Sin(2*Math.PI / n));
return c;
}
double RealPart;
double ImaginaryPart;
public ComplexNumber(double pReal, double pImaginary)
{
RealPart = pReal;
ImaginaryPart = pImaginary;
} public ComplexNumber()
: this(0, 0)
{ } public double Modulus { get { return Math.Sqrt(RealPart*RealPart + ImaginaryPart*ImaginaryPart); } }
public static explicit operator ComplexNumber(double d)
{
ComplexNumber c = new ComplexNumber(d, 0);
return c;
} public static ComplexNumber operator +(ComplexNumber a, ComplexNumber b)
{
ComplexNumber c = new ComplexNumber();
c.RealPart = a.RealPart + b.RealPart;
c.ImaginaryPart = a.ImaginaryPart + b.ImaginaryPart;
return c;
}
public static ComplexNumber operator -(ComplexNumber a, ComplexNumber b)
{
ComplexNumber c = new ComplexNumber();
c.RealPart = a.RealPart - b.RealPart;
c.ImaginaryPart = a.ImaginaryPart - b.ImaginaryPart;
return c;
} public static bool operator ==(ComplexNumber a,double b)
{
if (Math.Abs(a.ImaginaryPart) <=Error && Math.Abs(a.RealPart -b)<=Error)
return true;
return false;
} public static bool operator ==(ComplexNumber a,ComplexNumber b)
{
if (Math.Abs(a.ImaginaryPart-b.ImaginaryPart) <= Error && Math.Abs(a.RealPart - b.RealPart) <= Error)
return true;
return false;
} public static bool operator !=(ComplexNumber a, double b)
{
if (a == b)
return false;
return true;
} public static bool operator !=(ComplexNumber a, ComplexNumber b)
{
return !(a == b);
} public static ComplexNumber operator *(ComplexNumber a, ComplexNumber b)
{
ComplexNumber c = new ComplexNumber();
c.RealPart = a.RealPart * b.RealPart - a.ImaginaryPart * b.ImaginaryPart;
c.ImaginaryPart = a.RealPart * b.ImaginaryPart + a.ImaginaryPart * b.RealPart;
return c;
}
public ComplexNumber Invert()
{
ComplexNumber a = new ComplexNumber();
if (Math.Abs(ImaginaryPart) <= Error && Math.Abs(RealPart) <= Error)
throw (new ArgumentException("0 can not be inverted"));
a.ImaginaryPart = -ImaginaryPart / (RealPart * RealPart + ImaginaryPart * ImaginaryPart);
a.RealPart = RealPart / (RealPart * RealPart + ImaginaryPart * ImaginaryPart);
return a;
}
public ComplexNumber Clone()
{
ComplexNumber c = new ComplexNumber(RealPart, ImaginaryPart);
return c;
} public static ComplexNumber operator /(ComplexNumber a, ComplexNumber b)
{
ComplexNumber c = b.Invert();
return a*c;
}
}
}
正向都是对的