串行FFT递归算法(蝶式递归计算原理)求傅里叶变换

合集下载

FFT-快速傅里叶变换

FFT-快速傅里叶变换
pi[0]=0.0;
p=6.283185306/n;
pr[1]=cos(p);
pi[1]=-sin(p);
if (l)
pi[1]=-pi[1];
for(i=2;i<=n-1;i++){
p=pr[i-1]*pr[1];
q=pi[i-1]*pi[1];
s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);
注:亲测,这个版本无法运行,作者删改了重要内容[1] 请参考源码(2)
//快速傅立叶变换
// 入口参数:
// l: l=0, 傅立叶变换;l=1, 逆傅立叶变换
// il: il=0,不计算傅立叶变换或逆变换模和幅角;il=1,计算模和幅角
// n: 输入的点数,为偶数,一般为32,64,128,...,1024等
wi = wi*wpr + wtemp*wpi + wi;
}
mmax = istep;
}
}
在C++环境下的源码
bool FFT(complex<double> * TD, complex<double> * FD, int r)
{
//一维快速Fourier变换。
//complex<double> * TD ——指向时域数组的指针; complex<double> * FD ——指向频域数组的指针; r ——2的幂数,即迭代次数
// fr[]: l=0, 返回傅立叶变换的实部
// l=1, 返回逆傅立叶变换的实部
// fi[]: l=0, 返回傅立叶变换的虚部

快速傅里叶变换的原理

快速傅里叶变换的原理

快速傅里叶变换的原理快速傅里叶变换(FFT)是一种计算傅里叶变换的快速算法,它将傅里叶变换的复杂度从O(n^2)降低到O(n log n),大大提高了计算效率。

快速傅里叶变换的原理是基于分治法和递归的思想,通过将一个长度为N的离散序列分成两个长度为N/2的子序列,然后将这些子序列分别进行快速傅里叶变换,最后再将它们合并起来,从而得到原序列的傅里叶变换结果。

快速傅里叶变换的原理可以通过以下步骤详细解释:1. 初始化:首先将输入的N个复数序列x(n)进行重排,以便使得序列中的奇数项和偶数项可以分别在计算时被独立处理。

这一步可以使用位逆序排列(bit-reversal permutation)算法来实现,将输入序列中的元素按照其二进制位反转的方法进行重新排列,使得后续计算能够高效地进行。

2. 分治处理:将N个复数序列x(n)分成两个长度为N/2的子序列,分别记为偶数项序列x_e(n)和奇数项序列x_o(n)。

分别对这两个子序列进行快速傅里叶变换,得到它们的傅里叶变换结果X_e(k)和X_o(k)。

3. 合并结果:利用蝶形算法(butterfly algorithm)将两个子序列的傅里叶变换结果X_e(k)和X_o(k)合并起来,得到原序列的傅里叶变换结果X(k)。

蝶形算法是一种迭代的方法,通过不断的蝶形运算将两个输入信号的频域信息进行合并,实现了快速的傅里叶变换。

以上三个步骤就构成了快速傅里叶变换的基本原理,通过将一个长度为N的复数序列进行分治处理,并利用蝶形算法将子序列的傅里叶变换结果合并起来,从而高效地得到原序列的傅里叶变换结果。

快速傅里叶变换的原理可以通过一个简单的例子进行解释。

假设有一个长度为8的复数序列x(n)={1, 2, 3, 4, 4, 3, 2, 1},我们希望计算这个序列的傅里叶变换。

首先将输入序列按照位逆序排列,得到新的序列x'(n)={1, 3, 2, 4, 4, 2, 3, 1},然后将x'(n)分成两个长度为4的子序列x_e(n)={1, 2, 4, 3}和x_o(n)={3, 4, 2, 1}。

串行FFT递归算法(蝶式递归计算原理)求傅里叶变换

串行FFT递归算法(蝶式递归计算原理)求傅里叶变换

串行FFT递归算法(蝶式递归计算原理)求傅里叶变换摘要FFT,即为快速傅氏变换,是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。

它对傅氏变换的理论并没有新的发现,但是对于在计算机系统或者说数字系统中应用离散傅立叶变换,可以说是进了一大步。

设x(n)为N项的复数序列,由DFT变换,任一X(m)的计算都需要N次复数乘法和N-1次复数加法,而一次复数乘法等于四次实数乘法和两次实数加法,一次复数加法等于两次实数加法,即使把一次复数乘法和一次复数加法定义成一次“运算”(四次实数乘法和四次实数加法),那么求出N项复数序列的X(m),即N点DFT变换大约就需要N^2次运算。

当N=1024点甚至更多的时候,需要N2=1048576次运算,在FFT 中,利用WN的周期性和对称性,把一个N项序列(设N=2k,k为正整数),分为两个N/2项的子序列,每个N/2点DFT变换需要(N/2)^2次运算,再用N次运算把两个N/2点的DFT变换组合成一个N点的DFT变换。

这样变换以后,总的运算次数就变成N+2(N/2)^2=N+N^2/2。

继续上面的例子,N=1024时,总的运算次数就变成了525312次,节省了大约50%的运算量。

而如果我们将这种“一分为二”的思想不断进行下去,直到分成两两一组的DFT运算单元,那么N点的DFT变换就只需要Nlog(2)(N)次的运算,N在1024点时,运算量仅有10240次,是先前的直接算法的1%,点数越多,运算量的节约就越大,这就是FFT的优越性。

关键字:FFT 蝶式计算傅里叶变换目录一.题目及要求 (1)1.1题目 (1)二.设计算法、算法原理 (1)2.1算法原理与设计 (1)2.2设计步骤 (2)三.算法描述、设计流程 (4)3.1算法描述 (4)3.2流程图 (5)四.源程序代码及运行结果 (7)4.1源程序代码 (7)4.2运行结果 (12)五.算法分析、优缺点 (13)5.1算法分析 (13)5.2优缺点 (14)六.总结 (15)七.参考文献 (16)一.题目及要求1.1题目对给定的)23,27,16,8,30,74,22,21(--=α,利用串行FFT 递归算法(蝶式递归计算原理)计算其傅里叶变换的结果。

DFT算法原理FFT的算法原理

DFT算法原理FFT的算法原理

DFT算法原理FFT的算法原理快速傅里叶变换(Fast Fourier Transform,FFT)是一种用于高效计算离散傅里叶变换(Discrete Fourier Transform,DFT)的算法。

为了理解FFT算法原理,首先需要了解DFT算法原理。

DFT是一种将离散信号从时间域转换到频率域的技术,用于分析信号的频谱特征。

设离散信号x的长度为N,DFT的基本思想是将信号x拆分为N个不同频率的正弦和余弦波的加权和。

具体来说,DFT将信号x的N个采样点视为离散周期信号,然后将其与N个复指数函数(正弦和余弦波形成)进行内积运算,得到N个频率分量的复数值。

这N个频率分量包含了信号x在不同频率上的能量分布情况。

DFT的计算复杂度为O(N^2),即当信号长度N较大时,计算量非常庞大。

为了提高计算效率,约翰逊(James William Cooley)和图基(John William Tukey)于20世纪60年代提出了FFT算法。

FFT是一种基于分治策略的快速计算DFT的算法。

FFT将DFT的计算拆解为多个规模较小的DFT计算,并通过巧妙的计算顺序和重复利用计算结果的方式,大大降低了计算复杂度。

FFT算法的计算复杂度为O(NlogN),在信号长度较大时,计算速度比DFT快上几个数量级。

FFT算法的核心思想是蝶形运算(Butterfly Operation)。

蝶形运算是在计算DFT的过程中进行的一种线性运算,将两个复数进行乘法和加法运算,输出两个新的复数。

FFT算法通过重复应用蝶形运算,将DFT的计算分解为一系列规模更小的DFT计算,从而实现快速计算。

具体来说,FFT算法首先将输入的N个采样点按照一定的计算顺序重新排列,然后通过递归地将N个采样点分解为两个规模较小的DFT计算。

在每一级的计算中,利用蝶形运算对这些子问题进行计算,然后将计算结果合并得到最终的DFT结果。

由于FFT算法采用了递归和迭代的结构,可以高效地利用计算结果,从而减少计算量。

fft计算公式

fft计算公式

fft计算公式摘要:一、引言二、FFT 计算公式简介1.离散傅里叶变换2.快速傅里叶变换三、FFT 计算公式推导1.基2 递归算法2.蝴蝶运算四、FFT 在实际应用中的优势五、总结正文:一、引言在数字信号处理、图像处理等领域,傅里叶变换是一种非常重要的数学工具。

然而,对于大规模的信号处理问题,直接应用傅里叶变换的计算复杂度较高,因此,快速傅里叶变换(FFT)应运而生。

本文将详细介绍FFT 的计算公式及应用。

二、FFT 计算公式简介为了便于理解FFT 的计算公式,我们先简要介绍一下离散傅里叶变换(DFT)和快速傅里叶变换(FFT)。

1.离散傅里叶变换(DFT)DFT 是一种将离散信号从时域转换到频域的方法,其计算公式如下:X[k] = ∑N/2^n i^(-k+n) * x[n]其中,X[k] 表示频域的系数,x[n] 表示时域的信号,k 和n 分别为频域和时域的下标,N 为信号长度。

2.快速傅里叶变换(FFT)FFT 是DFT 的高效实现方法,它采用分治策略和循环移位技术,将DFT 的计算复杂度从O(N^2) 降低到O(NlogN)。

FFT 的计算公式如下:X[k] = ∑(N/2^n)^(2m) * C[m, k] * x[n]其中,m 为迭代次数,k 和n 分别为频域和时域的下标,N 为信号长度,C[m, k] 为复合基函数。

三、FFT 计算公式推导为了更直观地理解FFT 的计算过程,我们分两步进行推导。

1.基2 递归算法(1)首先,将输入序列x[n] 进行零填充,使其长度变为2 的整数次幂,即N = 2^n。

(2)将x[n] 和x[n+N/2] 进行旋转,得到x[n] 和x[n+N/2],其中x[n] 为原始序列,x[n+N/2] 为旋转后的序列。

(3)对旋转后的序列进行DFT 计算,得到频域系数X[k] 和X[k+N/2]。

(4)根据旋转序列的关系,可以得到频域系数X[k+N/2] = X[k],因此,我们只需计算一半的频域系数。

fft dif dit 原理

fft dif dit 原理

fft dif dit 原理
傅里叶变换(FFT)是一种数学算法,用于将一个函数(通常是
一个时域信号)转换为其频域表示。

FFT算法有两种主要实现方式,分治法(DIF)和蝶形运算法(DIT)。

首先来看DIF算法,它基于分治法的思想,将一个长度为N的
离散序列分解成两个长度为N/2的子序列,然后对这两个子序列分
别进行FFT变换,最后将它们合并起来。

这个过程可以递归地进行
下去,直到序列长度为1,这时FFT变换就变成了一个简单的乘法。

而DIT算法则是基于蝶形运算的思想,将整个FFT变换看作是
一系列蝶形运算的组合。

在蝶形运算中,输入序列被分成偶数和奇
数位置的两部分,然后进行加权和乘法运算,最后得到FFT变换的
结果。

这种算法的优点在于它可以利用数据的局部性,因此在实际
应用中通常有较好的性能表现。

总的来说,无论是DIF还是DIT算法,它们的原理都是基于将
一个复杂的FFT变换分解成一系列简单的操作,然后通过递归或迭
代的方式将这些简单操作组合起来,最终得到整个FFT变换的结果。

这些算法的设计使得FFT变换可以高效地在数字信号处理、通信系
统、图像处理等领域得到广泛应用。

希望这个回答能够全面地解答你的问题。

fft 快速傅里叶变换 (fast fourier transform)

fft 快速傅里叶变换 (fast fourier transform)

FFT 快速傅里叶变换(Fast Fourier Transform) 是一种用于快速计算傅里叶变换的算法,是在傅里叶变换的基础上发展而来的。

FFT 算法被广泛应用于数字信号处理、图像处理、声音处理、卷积操作、解析几何等领域,它的高效性和实时性使得它成为了当今计算机科学领域不可或缺的一部分。

一、傅里叶变换简介傅里叶变换是将一个时域信号转换为频域信号的过程,其公式如下:$F(\omega)=\int_{-\infty}^{\infty}f(t)e^{-i\omega t}dt$其中,$f(t)$ 表示时域信号,$F(\omega)$ 表示频域信号,$\omega$ 表示角频率。

傅里叶变换可以分为连续傅里叶变换和离散傅里叶变换两种。

连续傅里叶变换仅适用于连续信号,而离散傅里叶变换适用于离散信号。

二、离散傅里叶变换离散傅里叶变换是一种将离散信号变换为频域信号的方法,其公式如下:$X_k=\sum_{n=0}^{N-1}x_n e^{-\frac{2\pi i}{N}kn},k=0,1,...,N-1$其中,$x_n(n=0,1,...,N-1)$ 表示原始离散信号,$X_k(k=0,1,...,N-1)$ 表示变换后的频域信号。

但是,使用该公式直接计算离散傅里叶变换的时间复杂度为$O(N^2)$,计算效率低下。

三、FFT 快速傅里叶变换FFT 快速傅里叶变换是一种基于DFT 离散傅里叶变换的高效算法,它的时间复杂度可以达到$O(NlogN)$,较之直接计算DFT 的时间复杂度要低得多。

FFT 算法的基本思想是将 DFT 分治成多个较小的 DFT,并利用其重复性降低运算次数。

1.蝴蝶运算蝴蝶运算是 FFT 算法的基本运算,通过它可以将 DFT 的计算复杂度降低为 $O(N)$。

蝴蝶运算的实质是将两个相邻点之间的信号进行乘法和加法运算,其公式如下:$X_k=X_{k1}+W_{N}^kX_{k2},X_{k+N/2}=X_{k1}-W_{N}^kX_{k2}$其中,$X_{k1}$ 表示 $X_k$ 中偶数项,$X_{k2}$ 表示 $X_k$ 中奇数项,$W_N$ 是DFT 的核函数。

蝶形算法的原理

蝶形算法的原理

蝶形算法是一种高效的离散傅里叶变换算法,它的原理是利用分治法和蝴蝶操作,将一个大规模的DFT问题分解成若干个小规模的DFT问题,从而加速计算。

本文将详细介绍蝶形算法的原理及其应用。

一、分治法分治法是一种将问题分解成若干个子问题,然后递归地解决每个子问题的算法。

在DFT问题中,我们可以将一个长度为N的序列x分解成长度为N/2的两个序列x0和x1,然后对它们分别进行DFT变换,最后再通过合并操作得到原序列的DFT结果。

二、蝴蝶操作蝴蝶操作是蝶形算法的核心,它是一种对两个复数进行计算的方法,可以将两个复数进行加减乘除等运算。

在蝶形算法中,我们将每个DFT分解成若干个蝴蝶操作,每个蝴蝶操作都是对两个复数进行计算,然后将它们合并成一个复数。

三、蝶形算法的实现步骤1.将输入序列x分解成两个长度为N/2的序列x0和x1。

2.对x0和x1分别进行DFT变换。

3.对每个蝴蝶操作进行计算,计算公式如下:y[j]=x0[j]+Wn^j*x1[j]y[j+N/2]=x0[j]-Wn^j*x1[j]其中Wn是旋转因子,j是序列下标。

4.通过递归的方式对y0和y1进行DFT变换。

5.将y0和y1合并成一个长度为N的序列y。

四、蝶形算法的应用蝶形算法广泛应用于信号处理、图像处理、音频处理等领域。

以音频处理为例,蝶形算法可以用于实现音频信号的快速傅里叶变换,从而实现音频信号的频谱分析、滤波、降噪等处理。

总之,蝶形算法是一种高效的离散傅里叶变换算法,它利用分治法和蝴蝶操作将一个大规模的DFT问题分解成若干个小规模的DFT问题,从而加速计算。

蝶形算法在信号处理、图像处理、音频处理等领域有着广泛的应用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

串行FFT递归算法(蝶式递归计算原理)求傅里叶变换摘要FFT,即为快速傅氏变换,是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。

它对傅氏变换的理论并没有新的发现,但是对于在计算机系统或者说数字系统中应用离散傅立叶变换,可以说是进了一大步。

设x(n)为N项的复数序列,由DFT变换,任一X(m)的计算都需要N次复数乘法和N-1次复数加法,而一次复数乘法等于四次实数乘法和两次实数加法,一次复数加法等于两次实数加法,即使把一次复数乘法和一次复数加法定义成一次“运算”(四次实数乘法和四次实数加法),那么求出N项复数序列的X(m),即N点DFT变换大约就需要N^2次运算。

当N=1024点甚至更多的时候,需要N2=1048576次运算,在FFT中,利用WN的周期性和对称性,把一个N项序列(设N=2k,k为正整数),分为两个N/2项的子序列,每个N/2点DFT变换需要(N/2)^2次运算,再用N次运算把两个N/2点的DFT变换组合成一个N点的DFT变换。

这样变换以后,总的运算次数就变成N+2(N/2)^2=N+N^2/2。

继续上面的例子,N=1024时,总的运算次数就变成了525312次,节省了大约50%的运算量。

而如果我们将这种“一分为二”的思想不断进行下去,直到分成两两一组的DFT运算单元,那么N点的DFT变换就只需要Nlog(2)(N)次的运算,N在1024点时,运算量仅有10240次,是先前的直接算法的1%,点数越多,运算量的节约就越大,这就是FFT的优越性。

关键字:FFT 蝶式计算傅里叶变换目录一.题目及要求 (1)1.1题目 (1)二.设计算法、算法原理 (1)2.1算法原理与设计 (1)2.2设计步骤 (2)三.算法描述、设计流程 (4)3.1算法描述 (4)3.2流程图 (6)四.源程序代码及运行结果 (8)4.1源程序代码 (8)4.2运行结果 (13)五.算法分析、优缺点 (15)5.1算法分析 (15)5.2优缺点 (16)六.总结 (17)七.参考文献 (18)一.题目及要求1.1题目对给定的)23,27,16,8,30,74,22,21(--=α,利用串行FFT 递归算法(蝶式递归计算原理)计算其傅里叶变换的结果。

1.2要求利用串行递归与蝶式递归原理,对给定的向量求解傅里叶变换的结果。

二.设计算法、算法原理2.1算法原理与设计蝶式递归计算原理:令 为n/2次单位元根,则有 , 将b 向量的偶数项 和奇数项 分别记为 和 。

注意推导中反复使用: 。

图2.1 公式图形)2//(2~n i e πω=2~ωω=Tn b b b ),...,,(220-Tn b b b ),...,,(131-Tnb b b ),...,,(1102-'''T nb b b ),...,,(1102-''''''ppsn n nωωωωω==-==+,1,1,1ln2/2.2设计步骤DFT a a a a a a b b b T n T n n n n 的是因此,向量),...,,(),...,,(11110220222--+-+++DFT a a a a a a b b b T n Tn n n n n 的是因此,向量))(),...,(),((),...,,(1111101312222---+----ωω()()()()1,,1,0)(~)(~)(~)(~)()()()()(21011122211011122241120112241211224120122222222222222222222-=+=++++++++=++++++++=+++++++++==='∑∑-=+---++---++--++---=n k kk l k n l l l n ll l n lll llln k klk l l l a a a aa a a a a a a a a a a a a a a a a a a a a a ab b nn nn n n n n n n n n n n n n n n ωωωωωωωωωωωωωω偶数时:()()()()()()()1,,1,0)(~)(~)(~)(~)()()()()(21011112222110111122224112011121211122241201)12(11)12(1)12(1)12(12)12(211201)12(12222222222222222222222222222-=-=-++-+-+-=-++-+-+-=----++++=++++++++===''∑∑-=+----++----++---+----+-++++-+-++-=++n k kk k l k n l l l n llln llllln l n l l l l l n k k k l l l l a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a b b n n n n n n n n n n n n n n n n n n n n n n n n nn n ωωωωωωωωωωωωωωωωωωωωωωωωωωωωωωω奇数时:对于以上的分析可画出如图 2.2所示的离散傅里叶变换递归计算流图。

图2.3就是一个按此递归方法计算的n=8的FFT 蝶式计算图。

FFT 的蝶式递归计算图(有计算原理推出):图2.2 递归计算流图特别的,n=8的FFT 蝶式计算图(展开的):...a 0a1a n -1DFT(n /2)DFT(n /2).........+++---1-a (a )ωn 2-1n 2-1n-1-a (a )ωn 2+11-a a n20+a a n 2-1n-1+a a 20+a a n 2+11a n 2-1a n 2an 2+1......ωn 2-1ω图2.3 蝶式计算图按输入元素k a 展开,前面将输出序列之元素j b 按其偶下标(l j 2=)和(12+=l j )展开,导出∑-=++1022)(~n n k k k lk a a ω和∑-=+-1022)(~nn k kk k l k a a ωω递归计算式,按此构造出了如图1所示的FFT 递归计算流程图。

事实上,我们也可以将输入序列之元素k a 按其偶下标(k 2) 和几下标(12+k )展开,则导出另一种形式的FFT 递归计算式 ∑-==10n k k kj j a w b 。

三.算法描述、设计流程3.1算法描述SISD 上的FFT 分治递归算法:输入: a=(a 0,a 1,…,a n-1); 输出: B=(b 0,b 1,…,b n-1) Procedure RFFT(a,b) beginif n=1 then b 0=a 0 else(1)RFFT(a 0,a 2,…,a n-2, u 0,u 1,…,u n/2-1) (2)RFFT(a 1,a 3,…,a n-1, v 0,v 1,…,v n/2-1) (3)z=1(4)for j=0 to n-1 do(4.1)b j =u j mod n/2+zv j mod n/2 (4.2)z=z ωendfor endif end注: (1)算法时间复杂度t(n)=2t(n/2)+O(n)t(n)=O(nlogn)n=8的FFT蝶式计算图:图3.1 FFT蝶式计算图n=6的FFT递归计算流程图:图3.2 FFT递归计算流程图3.2流程图四.源程序代码及运行结果4.1源程序代码/************FFT***********/#include <stdio.h> //整个程序输入和输出利用同一个空间x[N],节约空间#include <math.h>#include <stdlib.h>#define N 1000 //定义输入或者输出空间的最大长度typedefstruct{double real;doubleimg;}complex; //定义复数型变量的结构体void fft(); //快速傅里叶变换函数声明void initW(); //计算W(0)~W(size_x-1)的值函数声明void change(); //码元位置倒置函数函数声明void add(complex,complex,complex *); /*复数加法*/void mul(complex,complex,complex *); /*复数乘法*/void sub(complex,complex,complex *); /*复数减法*/void divi(complex,complex,complex *); /*复数除法*/void output(); /*输出结果*/complex x[N],*W; /*输出序列的值*/intsize_x=0; /*输入序列的长度,只限2的N次方*/double PI; //pi的值int main(){inti;system("cls");PI=atan(1)*4;printf("Please input the size of x:\n"); /*输入序列的长度*/scanf("%d",&size_x);printf("Please input the data in x[N]:(such as:5 6)\n");for(i=0;i<size_x;i++) /*输入序列对应的值*/ scanf("%lf %lf",&x[i].real,&x[i].img);initW(); //计算W(0)~W(size_x-1)的值fft(); //利用fft快速算法进行DFT变化output(); //顺序输出size_x个fft的结果return 0;}/*进行基-2 FFT运算,蝶形算法。

这个算法的思路就是,先把计算过程分为log(size_x)/log(2)-1级(用i控制级数);然后把每一级蝶形单元分组(用j控制组的第一个元素起始下标);最后算出某一级某一组每一个蝶形单元(用k控制个数,共l个)。

*/voidfft(){inti=0,j=0,k=0,l=0;complexup,down,product;change(); //实现对码位的倒置for(i=0;i<log(size_x)/log(2);i++) //循环算出fft的结果{l=1<<i;for(j=0;j<size_x;j+=2*l){for(k=0;k<l;k++) //算出第i级内j组蝶形单元的结果{ //算出j组中第k个蝶形单元mul(x[j+k+l],W[(size_x/2/l)*k],&product); /*size/2/l是该级W的相邻上标差,l是该级该组取的W总个数*/add(x[j+k],product,&up);sub(x[j+k],product,&down);x[j+k]=up; //up为蝶形单元右上方的值x[j+k+l]=down; //down为蝶形单元右下方的值}}}}void initW() //计算W的实现函数{inti;W=(complex *)malloc(sizeof(complex) * size_x);/*申请size_x个复数W的空间(这部申请的空间有点多,实际上只要申请size_x/2个即可)*/for(i=0;i<(size_x/2);i++)/*预先计算出size_x/2个W的值,存放,由于蝶形算法只需要前size_x/2个值即可*/ {W[i].real=cos(2*PI/size_x*i); //计算W的实部W[i].img=-1*sin(2*PI/size_x*i); //计算W的虚部}}void change() //输入的码组码位倒置实现函数{complex temp;unsigned short i=0,j=0,k=0;double t;for(i=0;i<size_x;i++){k=i;j=0;t=(log(size_x)/log(2));while((t--)>0){j=j<<1;j|=(k & 1);k=k>>1;}if(j>i){temp=x[i];x[i]=x[j];x[j]=temp;}}}void output() //输出结果实现函数{inti;printf("The result are as follows\n");for(i=0;i<size_x;i++){printf("%.4f",x[i].real); //输出实部if(x[i].img>=0.0001) //如果虚部的值大于0.0001,输出+jx.img的形式printf("+j%.4f\n",x[i].img);else if(fabs(x[i].img)<0.0001)printf("\n");elseprintf("-j%.4f\n",fabs(x[i].img));//如果虚部的值小于-0.0001,输出-jx.img的形式}}void add(complex a,complexb,complex *c) //复数加法实现函数{c->real = a.real + b.real; //复数实部相加c->img = a.img + b.img; //复数虚部相加}void mul(complex a,complexb,complex *c) //复数乘法实现函数{c->real = a.real*b.real - a.img*b.img; //获取相乘结果的实部c->img = a.real*b.img + a.img*b.real; //获取相乘结果的虚部}void sub(complex a,complexb,complex *c) //复数减法实现函数{c->real = a.real - b.real; //复数实部相减c->img = a.img - b.img; //复数虚部相减}void divi(complex a,complexb,complex *c) //复数除法实现函数{c->real = (a.real*b.real + a.img*b.img) / (b.real*b.real+b.img*b.img);//获取相除结果的实部c->img = (a.img*b.real - a.real*b.img) / (b.real*b.real+b.img*b.img);//获取相除结果的虚部}4.2运行结果(1)处理器p=8:α时串行FFT输出结果图4.1当)8,7,6,5,4,3,2,1(=(2)处理器p=8:α时输出结果与计算结果相符如图4.2所示当)(-,21-=,3023,22,27,16,8,74图4.2运行图五.算法分析、优缺点5.1算法分析(1)FFT算法的基本原理是把长序列的DFT逐次分解为较短序列的DFT。

相关文档
最新文档