设x(N)为N点有限长离散序列,代入式(8-3)、式(8-4),并令 其傅里叶变换(DFT)为
反变换(IDFT)为
地球物理数据处理基础
两者的差异只在于W的指数符号不同,以及差一个常数1/N,因此下面我们只讨论DFT正变换式(8-5)的运算量,其反变换式(8-6)的运算是完全相同的。
一般来说,W是复数,因此,X(j)也是复数,对于式(8-5)的傅里叶变换(DFT),计算一个X(j)值需要N次复数乘法和N-1次复数加法。而X(j)一共有N个值(j=0,1,…,N-1),所以完成整个DFT运算总共需要N2次复数乘法和N(N-1)次复数加法。
直接计算DFT,乘法次数和加法次数都是与N2成正卜颂茄比的,当N很大时,运算量会很大,例如,当N=8时,DFT需64次复数乘法;而当N=1024时,DFT所需乘法为1048576次,即一百多万次的复数乘法运算,对运算速度要求高。所以需要改进DFT的计算方法,以减少运算次数。
分析Wjk,表面上有N2个数值,由于其周期性,实际上仅有N个不同的值W0,W1,…,WN-1。对于N=2m时,由于其对称性,只有N/2个不同的值W0,W1,…,
地球物理数据处理基础
因此可以把长序列的DFT分解为短序列DFT,而前面已经分析DFT与N2成正比,所以N越小越有利。同时,利用ab+ac=a(b+c)结合律法则,可以将同一个Wr对应的系数x(k)相加后再乘以Wr,就能大大减少运算次数。这就是快速傅里叶变换(FFT)的算法思路。下面,我们来分析N=2m情况下的FFT算法。
1.N=4的FFT算法
对于m=2,N=4,式(8-5)傅里叶变换为
地球物理数据处理基础
将式(8-7)写成矩阵樱芹形式
地球物理数据处理基础
为了便于分析,将上式中的j,k写成二进制形式,即
地球物理数据处理基础
代入式(8-7),得
地球物理数据处理基础
分析Wjk的周期性来减少乘法次数
地球物理数据处理基础
则 代回式(8-9),整理得
地球物理数据处理基础
上式可分层计算,先计算内层,再计算外层时就利用内层计算的结果,可避免重复计算。写成分层形式
地球物理数据处理基础
则X(j1 j0)=X2(j1 j0)。
上式表明对于N=4的FFT,利用Wr的周期关系可分为m=2步计算。实际上,利用Wr的对称性,仍可型察以对式(8-11)进行简化计算。考虑到
地球物理数据处理基础
式(8-11)可以简化为
地球物理数据处理基础
令j=j0;k=k0,并把上式表示为十进制,得
地球物理数据处理基础
可以看到,完成上式N=4的FFT计算(表8-1)需要N·(m-1)/2=2次复数乘法和N·m=8次复数加法,比N=4的DFT算法的N2=16次复数乘法和N·(N-1)=12次复数加法要少得多。
表8-1 N=4的FFT算法计算过程
注:W0=1;W1=-i。
[例1]求N=4样本序列1,3,3,1的频谱(表8-2)。
表8-2 N=4样本序列
2.N=8的FFT算法
类似N=4的情况,用二进制形式表示,有
地球物理数据处理基础
写成分层计算的形式:
地球物理数据处理基础
则X(j2 j1 j0)=X3(j2 j1 j0)。
对式(8-14)的X1(k1 k0 j0)进行展开,有
地球物理数据处理基础
还原成十进制,并令k=2k1+k0,即k=0,1,2,3,有
地球物理数据处理基础
用类似的方法对式(8-14)的X2(k0 j1 j0),X3(j2 j1 j0)进行展开,整理得
地球物理数据处理基础
用式(8-16)、式(8-17)逐次计算到X3(j)=X(j)(j=0,1,…,7),即完成N=23=8的FFT计算,其详细过程见表8-3。
表8-3 N=8的FFT算法计算过程
注:对于正变换 对于反变换 所
[例2]求N=8样本序列(表8-4)x(k)=1,2,1,1,3,2,1,2的频谱。
表8-4 N=8样本序列
3.任意N=2m的FFT算法
列出N=4,N=8的FFT计算公式,进行对比
地球物理数据处理基础
观察式(8-18)、式(8-19),不难看出,遵循如下规律:
(1)等式左边的下标由1递增到m,可用q=1,2,…,m代替,则等式右边为q-1;
(2)k的上限为奇数且随q的增大而减小,至q=m时为0,所以其取值范围为k=0,1,2,…,(2m-q-1);
(3)j的上限为奇数且随q的增大而增大,且q=1时为0,其取值范围为j=0,1,2,…,(2q-1-1);
(4)k的系数,在等式左边为2q,等式右边为2q-1(包括W的幂指数);
(5)等式左边序号中的常数是2的乘方形式,且幂指数比下标q小1,即2q-1;等式右边m对式子序号中的常数都是定值2m-1。
归纳上述规则,写出对于任意正整数m,N=2m的FFT算法如下:
由X0(p)=x(p)(p=0,1,…,N-1)开始:
(1)对q=1,2,…,m,执行(2)~(3)步;
(2)对k=0,1,2,…,(2m-q-1)及j=0,1,2,…,(2q-1-1),执行
地球物理数据处理基础
(3)j,k循环结束;
(4)q循环结束;由Xm(p)(p=0,1,…,N-1)输出原始序列x(p)的频谱X(p)。
在计算机上很容易实现上述FFT算法程序,仅需要三个复数数组,编程步骤如下:
(1)设置复数数组X1(N-1),X2(N-1)和 (数组下界都从0开始);
(2)把样本序列x赋给X1,即X1(k)=x(k)(k=0,1,…,N-1);
(3)计算W,即正变换 反变换
(4)q=1,2,…,m,若q为偶数,执行(6),否则执行第(5)步;
(5)k=0,1,2,…,(2m-q-1)和j=0,1,2,…,(2q-1-1)循环,作
X2(2qk+j)=X1(2q-1k+j)+X1(2q-1k+j+2m-1)
X2(2qk+j+2q-1)=[X1(2q-1k+j)-X1(2q-1k+j+2m-1)]W(2q-1k)
至k,j循环结束;
(6)k=0,1,2,…,(2m-q-1)和j=0,1,2,…,(2q-1-1)循环,作
X1(2qk+j)=X2(2q-1k+j)+X2(2q-1k+j+2m-1)
X1(2qk+j+2q-1)=[X2(2q-1k+j)-X2(2q-1k+j+2m-1)]W(2q-1k)
至k,j循环结束;
(7)q循环结束,若m为偶数,输出X1(j),否则输出X2(j)(j=0,1,…,N-1),即为所求。
void fft(){
int nn,n1,n2,i,j,k,l,m,s,l1
float ar[1024],ai[1024]// 实部 虚部
float a[2050]
float t1,t2,x,y
float w1,w2,u1,u2,z
float fsin[10]={0.000000,1.000000,0.707107,0.3826834,0.1950903,0.09801713,0.04906767,0.02454123,0.01227154,0.00613588,}// 优化
float fcos[10]={-1.000000,0.000000,0.7071068,0.9238796,0.9807853,0.99518472,0.99879545,0.9996988,0.9999247,0.9999812,}
nn=1024
s=10
n1=nn/2 n2=nn-1
j=1
for(i=1i<=nni++)
{
a[2*i]=ar[i-1]
a[2*i+1]=ai[i-1]
}
for(l=1l<n2l++)
{
if(l<j)
{
t1=a[2*j]
t2=a[2*j+1]
a[2*j]=a[2*l]
a[2*j+1]=a[2*l+1]
a[2*l]=t1
a[2*l+1]=t2
}
k=n1
while (k<j)
{
j=j-k
k=k/2
}
j=j+k
}
for(i=1i<=si++)
{
u1=1
u2=0
m=(1<<i)
k=m>>1
w1=fcos[i-1]
w2=-fsin[i-1]
for(j=1j<=kj++)
{
for(l=jl<nnl=l+m)
{
l1=l+k
t1=a[2*l1]*u1-a[2*l1+1]*u2
t2=a[2*l1]*u2+a[2*l1+1]*u1
a[2*l1]=a[2*l]-t1
a[2*l1+1]=a[2*l+1]-t2
a[2*l]=a[2*l]+t1
a[2*l+1]=a[2*l+1]+t2
}
z=u1*w1-u2*w2
u2=u1*w2+u2*w1
u1=z
}
}
for(i=1i<=nn/2i++)
{
ar[i]=a[2*i+2]/nn
ai[i]=-a[2*i+3]/nn
a[i]=4*sqrt(ar[i]*ar[i]+ai[i]*ai[i]) // 幅值
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)