快速傅里叶变换及其应用Word下载.docx
《快速傅里叶变换及其应用Word下载.docx》由会员分享,可在线阅读,更多相关《快速傅里叶变换及其应用Word下载.docx(6页珍藏版)》请在冰豆网上搜索。
2.voidfft(Coaplex»
det,Complex*src,intp>
;
快速傅里叶变换.求复数数组src[U2)的傅里叶变换•结果存放在伽[()/)«
1>
3.voidifXt(C0Bplex*dst,Complex*src.intp);
快速傅里叶逆变换.
求复数績组打"
[0.剪)的逆傅.里叶变换.姑果存放在山级.2"
)中.
4.利用快速傅里叶变换il氛长整数乘法.
typedefstd:
:
vector<
unsignedchar>
Integer;
voidmultiply(Intoger*rst.Int©
gerconstfta.Integercon3tib);
2实验原理
计算离散傅里叶变换的一种快速算法,简称FFT。
快速傅里叶变换是1965年
IIIJ.w.库利和T.W.图基提出的。
采用这种算法能使计算机讣算离散傅里叶变换所需要的乘法次数大为减少,特别是被变换的抽样点数'
越多,FFT算法计算量的节省就越显著。
快速傅氏变换,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。
它对傅氏变换的理论并没有新的发现,但是对于在计算机系统或者说数字系统中应用离散傅立叶变换,可以说是进了一大步。
设x(n)为'
项的复数序列,由DFT变换,任一X(m)的汁算都需要N次复数乘法和\-1次复数加法,而一次复数乘法等于四次实数乘法和两次实数加法,一次复数加法等于两次实数加法,即使把一次复数乘法和一次复数加法定义成一次“运算”(四次实数乘法和四次实数加法),那么求出'
项复数序列的X(m),即N点DFT变换大约就需要N2次运算。
当21024点甚至更多的时候,需要N2=1018576次运算.
在FFT中,利用WN的周期性和对称性,把一个N项序列(设N二2k,k为正整数),分为两个$/2项的子序列,每个\/2点DFT变换需要(N/2)2次运算,再用X次运算把两个N/2点的DFT变换组合成一个X点的DFT变换。
这样变换以后,总的运算次数就变成N+2(N/2)2=N+X2/2o继续上面的例子,01024时,总的运算次数就变成了525312次,节省了大约50%的运算量。
如果我们将这种“一分为二”的思想不断进行下去,直到分成两两一组的DFT运算单元,那么N点的DFT变换就只需要Nlog2N次的运算,'
在1024点时,运算量仅有10240次,是先前的直接算法的1%,点数越多,运算量的节约就越大,这就是FFT的优越性。
3算法思想及代码实现
3.1复数类及常规运算
函数定义了复数类,以及复数的“+”,“一”,“*”,“宁”四则运算。
复数是指能写成如下形式的数a+bi,这里a和b是实数,i是虚数单位(即-1开根)。
在复数a+bi中,a称为复数的实部,b称为复数的虚部,i称为虚数单位。
当虚部等于零时,这个复数就是实数;
当虚部不等于零时,这个复数称为虚数,复数的实部如果等于零,则称为纯虚数。
山上可知,复数集包含了实数集,因而是实数集的扩张。
复数是由意大利米兰学者卡当在十六世纪首次引入,经过达朗贝尔、棣莫弗、欧拉、高斯等人的工作,此概念逐渐为数学家所接受。
复数的四则运算规定为:
(a+bi)+(c+di)二(a+c)+(b+d)i,(a+bi)
—(c+di)=(a-c)+(b—d)i,(a+bi)•(c+di)=(ac~bd)+(bc+ad)i,(c与d不同时为零)。
//定义复数类
Complex:
:
Complex()
{real_=0;
imag_=0;
}
Comp1ex(doub1econst&
real)
this->
real_=real;
}
real,doubleconst&
imdg)
imag_=imag;
Complex(Complexconst&
v)
real_=v.real_;
const
imag_=v.imag_;
a.加法运算
ComplexComplex:
operator+(Complexconst&
{//符号重定义
Complexsum;
sum.real_=this->
real_+a.real_;
sum.imag_=this一〉imdg_+d・
returnsum;
b.减法运算
operator-(Complexconst&
Complexdiff;
diff.real=this->
real一real;
diff.imag_=this->
imag_一&
imag_;
returnd辻f;
c.乘法运算
Complexmuti;
muti・real_=this->
real_*a.real_一this->
imag_*a.
muti・imd£
_=this->
imag_*d・real_+this->
real_*d・imd£
_;
returnmuti;
d.除法运算
operator/(Complexconst&
a)const
ComplexDiv;
Div.real_=(this->
real_*a・ithis-
>
imag_*a・imag_)/(a.real_*a・real_+a.imag_*a・imag_);
Div.imdg_二(this一〉imag_*d・real_一this一>
real_*
a.imag_)/(a.real_*a・real_+a.imag_*a.imag_);
returnDiv;
3.2复数数组的傅里叶变换
傅立叶变换,也称作傅里叶变换,表示能将满足一定条件的某个函数表示成三角函数(正弦和/或余弦函数)或者它们的积分的线性组合。
在不同的研究领域,傅立叶变换具有多种不同的变体形式,如连续傅立叶变换和离散傅立叶变换。
最初傅立叶分析是作为热过程的解析分析的工具被提出的。
f(t)是t的周期函数,如果t满足狄里赫莱条件:
在一个周期内具有有限个间断点,且在这些间断点上,函数是有限值;
在一个周期内具有有限个极值点;
绝对可积。
则有下图①式成立。
称为积分运算f(t)的傅里叶变换,
②式的积分运算叫做F(3)的傅里叶逆变换。
F(3)叫做f(t)的像函数,f(t)叫做
F(3)的像原函数。
F(3)是f(t)的像。
f(t)是F(3)原像。
1傅里叶变换
2傅里叶逆变换
实现复数数组的傅里叶变换函数
voidfft(Complex*dst,Complex*src,intp)//快速傅里叶变换
{//求复数数组src[0,2"
p)的傅里叶变换,结果存放在dst[O,2P)中
intpow_p=pow((double)2,p):
intflag,mO,ml,m2,m3;
Complexemp,*w,wO;
doublereal,imag;
flag二0;
temp=(Complex*)malloc(sizeof(Complex)*pow_p);
〃计算出w;
w[0]・set_Complex(l,0);
real=cos(2*PI/pow_p);
imag=sin(2*PI/pow_p);
w0・set_Complex(real,imag);
for(inti=1;
i〈pow_p/2;
i++)
讥i]=w[i~l]*w0;
for(inti=pow_p/2;
i>
0;
i/=2)
{//从二进制的最高位开始处理,依次往低位计算
flag++;
//应该在偶数次得到结果
for(intk=0;
k<
i;
k++)
{for(intj二0;
j<
pow_p/(2*i);
j++)
{mO=(k+j*i)%(pow_p/2);
//低位
ml=pow_p/2+(k+j*i)%(pow_p/2);
//高位
m2=(k+j*i*2)%(pow_p);
m3=(k+j*i*2+i)%(pow_p);
if(flag二二1)//第一次
{templmO]=src[m2]+src[m3]*w[j*i];
temp[ml]=src[m2]-src[m3]*w[j*i];
elseif(flag%2==O)//偶数次
{dst[mO]=temp[m2]+temp[m3]*w[j*i];
dst[ml]=temp[m2]-temp[m3]*w[j*i];
else//奇数次
{temp[mO]=dst[m2]+dst[m3]*w[j*i];
temp[ml]=dst[m2]-dst[m3]*w[j*i];
}}}}
if(flag%2二二1)//奇数次时应当把temp中的变换结果放回dest中
for(inti二0;
i〈pow_p;
dst[i]二temp[i];
free(temp);
free(w);
//Print_Complex_Array(dst,pow_p);
3.3复数数组的逆傅里叶变换
实现复数数组的逆傅里叶变换函数
{//求复数数组src[O,2"
p)的傅里叶逆变换,结果存放在dst[0,2P)中
继续阅读