首页 > 其他分享 >快速傅里叶变换(FFT)

快速傅里叶变换(FFT)

时间:2024-09-14 20:23:12浏览次数:10  
标签:运算 变换 DFT FFT 算法 序列 傅里叶

前言

傅里叶级数(FS)

傅里叶变换(FT)

离散时间傅里叶级数(DFS)

离散时间傅里叶变换(DTFT)

离散傅里叶变换(DFT)

建议先看以上文章

FFT是DFT的一种快速算法而不是一种新的变换,它可以在数量级的意义上提高运算速度。

直接计算DFT的问题

DFT的运算量

设有限长序列x(n),非零值长度为N,若对x(n)进行次DFT运算,共需多大的运算工作量?

X(k)=DFT[x(n)]=\sum_{n=0}^{N-1}x(n)W_{N}^{nk},k=0,1,\cdots N-1 
x(n)=IDFT[x(n)]=\frac{1}{N}\sum_{n=0}^{N-1}x(n)W_{N}^{-nk},n=0,1,\cdots N-1
  • x(n)为复数,W_{N}^{nk}=e^{-jk\frac{2\pi}{N} n}也为复数。
  • X(k)和x(n)的计算量基本相同,只差一个因子\frac{1}{N}

复数乘法次数N^{2},复数加法次数N(N-1),若N远远大于1,则这两者都近似为N^{2},随N增大而急速增大。

改善DFT运算效率的基本途径

1、利用W_{N}^{nk}=e^{-jk\frac{2\pi}{N} n}的性质

W_{N}^{nk}(单位周期复指数序列、旋转因子)具有以下性质

  • 周期性 W_{N}^{nk}=W_{N}^{(n+rN)k}=W_{N}^{(k+rN)n},r为整数

        W_{N}^{(n+rN)k}= W_{N}^{nk}\cdot W_{N}^{rNk}=W_{N}^{nk}\cdot 1=W_{N}^{nk}

        同理可得W_{N}^{(k+rN)n}=W_{N}^{nk}

  • 共轭对称性 \left ( W_{N}^{nk} \right ) ^{*}=W_{N}^{-nk}=W_{N}^{(rN-n)k}=W_{N}^{(rN-k)n},r为整数
  • 可约性 W_{N}^{nk}=W_{mN}^{mnk},W_{N}^{nk}=W_{\frac{N}{m}}^{\frac{nk}{m}},m为整数,N/m为整数

        W_{mN}^{mnk}=e^{-jk\frac{2\pi}{Nm} mn}=e^{-jk\frac{2\pi}{N} n}=W_{N}^{nk}

        同理可得W_{\frac{N}{m}}^{\frac{nk}{m}}=W_{N}^{nk}

  • 由以上性质,得出一些特殊点 

        W_{N}^{0}=e^{0}=1

        W_{N}^{N}=e^{-2\pi j}=1

        W_{N}^{\frac{N}{2}}=e^{-j\pi}=-1

        W_{N}^{k+\frac{N}{2}}= W_{N}^{\frac{N}{2}}\cdot W_{N}^{k}=-W_{N}^{k}

FFT算法的基本思想与分类

基本思想

利用DFT系数的特性,合并DFT运算中的某些项;

把长序列DFT分解为短序列DFT,从而减少运算量。

FFT算法分类

  • 时间抽选法(DIT):Decimation-In-Time
  • 频率抽选法(DIF):Decimation-In-Frequency

按时间抽选(DIT)的基-2 FFT算法 

算法原理

设输入序列长度为N=2^{M}(M为正整数),将该序列按时间顺序的奇偶分解为越来越短的子序列,称为基2按时间抽取的FFT算法。也称为Coolkey-Tukey(库利-图基)算法。

其中基2表示:N=2^{M},M为整数,若不满足这个条件,可以人为地加上若干零值(加零补长)使其达到N=2^{M}

N=2^{M}的序列x(n),按奇偶分成两组:

\left.\begin{matrix} x(2r) = x_{1}(r) \\ x(2r+1) = x_{2}(r) \end{matrix}\right\},r=0,1,\cdots ,\frac{N}{2}-1                                                                          (1)

则其N点DFT为

X(k)=DFT[x(n)]=\sum_{n=0}^{N-1}x(n)W_{N}^{nk}

           =\sum_{r=0}^{\frac{N}{2}-1} x(2r)W_{N}^{2rk}+\sum_{r=0}^{\frac{N}{2}-1} x(2r+1)W_{N}^{(2r+1)k}

           =\sum_{r=0}^{\frac{N}{2}-1} x_{1}(r)W_{N}^{2rk}+W_{N}^{k}\sum_{r=0}^{\frac{N}{2}-1} x_{2}(r)W_{N}^{2rk}

利用W_{N}^{nk}的可约性

X(k)=\sum_{r=0}^{\frac{N}{2}-1} x_{1}(r)W_{\frac{N}{2}}^{rk}+W_{N}^{k} \sum_{r=0}^{\frac{N}{2}-1} x_{2}(r)W_{\frac{N}{2}}^{rk}=X_{1}(k) + W_{N}^{k} X_{2}(k)                      (2)

式中X_{1}(k)X_{2}(k)分别是x_{1}(r)x_{2}(r)\frac{N}{2}点DFT

X_{1}(k)=\sum_{r=0}^{\frac{N}{2}-1} x_{1}(r)W_{\frac{N}{2}}^{rk}=\sum_{r=0}^{\frac{N}{2}-1} x(2r)W_{\frac{N}{2}}^{rk}                                                                 (3)

X_{2}(k)=\sum_{r=0}^{\frac{N}{2}-1} x_{2}(r)W_{\frac{N}{2}}^{rk}=\sum_{r=0}^{\frac{N}{2}-1} x(2r+1)W_{\frac{N}{2}}^{rk}                                                         (4)

由(2)式可看出,一个N点DFT已分解成两个\frac{N}{2}点DFT,但是x_{1}(r)x_{2}(r)以及X_{1}(k)X_{2}(k)都是 \frac{N}{2}点序列,即r,k 满足r,k=0,1,\cdots ,\frac{N}{2}-1。而X(k)却有 N点,用(2)式计算得到的只是 X(k)的前一半项数的结果,要用X_{1}(k)X_{2}(k)表达全部的X(k)值,还必须应用W_{N}^{nk}的周期性,即

W_{\frac{N}{2}}^{rk}= W_{\frac{N}{2}}^{r(k+\frac{N}{2})}

这样可得到

X_{1}(k+\frac{N}{2})=\sum_{r=0}^{\frac{N}{2}-1} x_{1}(r)W_{\frac{N}{2}}^{r(k+\frac{N}{2})}=\sum_{r=0}^{\frac{N}{2}-1} x_{1}(r)W_{\frac{N}{2}}^{rk}=X_{1}(k)                               (5)

同理可得

X_{2}(k+\frac{N}{2})=X_{2}(k)                                                                                                                 (6)

(5)式、(6)式说明了后半部分k值 \left ( \frac{N}{2}\leqslant k\leq N-1 \right ) 所对应的 X_{1}(k)X_{2}(k)等于前半部分k值\left ( 0\leqslant k\leq \frac{N}{2}-1 \right )所对应的 X_{1}(k)X_{2}(k)

再利用特殊点

W_{N}^{k+\frac{N}{2}}= W_{N}^{\frac{N}{2}}\cdot W_{N}^{k}=-W_{N}^{k}                                                                                                 (7)

整理得

前半部分 X(k) \left ( k=0,1\cdots ,\frac{N}{2}-1 \right )可表示为

X(k)=X_{1}(k) + W_{N}^{k} X_{2}(k),    k=0,1,\cdots ,\frac{N}{2}-1                                                          (8)

后半部分 X(k) \left ( k=\frac{N}{2},\cdots ,N-1 \right )可表示为

X(k+\frac{N}{2})=X_{1}(k) - W_{N}^{k} X_{2}(k),    k=0,1,\cdots ,\frac{N}{2}-1                                                 (9)

这样,只要求出0\sim \left ( \frac{N}{2} -1\right )区间的所有X_{1}(k)X_{2}(k)值,即可求出0~(N-1)区间内的所有 X(k)值,大大节省了运算。

(8)式和(9)式的运算可以用下图所示的蝶形运算流图符号表示。

N=2^{3}=8为例子

继续分解,把\frac{N}{2}点DFT,分解成\frac{N}{4}点DFT

先将x_{1}(r)进行分解:

\left.\begin{matrix} x_{1}(2l) = x_{3}(l) \\ x_{1}(2l+1) = x_{4}() \end{matrix}\right\},l=0,1,\cdots ,\frac{N}{4}-1                                                                        (10)

同样可得

X_{1}(k)=\sum_{l=0}^{\frac{N}{4}-1} x_{1}(2l)W_{\frac{N}{2}}^{2lk}+\sum_{l=0}^{\frac{N}{4}-1} x_{1}(2l+1)W_{\frac{N}{2}}^{(2l+1)k}

            =\sum_{l=0}^{\frac{N}{4}-1} x_{3}(l)W_{\frac{N}{2}}^{2lk}+W_{\frac{N}{2}}^{k}\sum_{l=0}^{\frac{N}{4}-1} x_{4}(l)W_{\frac{N}{2}}^{2lk}

            =\sum_{l=0}^{\frac{N}{4}-1} x_{3}(l)W_{\frac{N}{4}}^{lk}+W_{\frac{N}{2}}^{k}\sum_{l=0}^{\frac{N}{4}-1} x_{4}(l)W_{\frac{N}{4}}^{lk}

           =X_{3}(k) + W_{\frac{N}{2}}^{k} X_{4}(k),    k=0,1,\cdots ,\frac{N}{4}-1                                                       

X_{1}(k+\frac{N}{4})=X_{3}(k) - W_{\frac{N}{2}}^{k} X_{4}(k),    k=0,1,\cdots ,\frac{N}{4}-1                                             

其中

X_{3}(k)=\sum_{l=0}^{\frac{N}{4}-1} x_{1}(2l)W_{\frac{N}{4}}^{lk}=\sum_{l=0}^{\frac{N}{4}-1} x_{3}(l)W_{\frac{N}{4}}^{lk}                                                                (11)

X_{4}(k)=\sum_{l=0}^{\frac{N}{4}-1} x_{1}(2l+1)W_{\frac{N}{4}}^{lk}=\sum_{l=0}^{\frac{N}{4}-1} x_{4}(l)W_{\frac{N}{4}}^{lk}                                                        (12)

同理x_{2}(r)也可以分解得到

\left.\begin{matrix} X_{2}(k+)=X_{5}(k) + W_{\frac{N}{2}}^{k} X_{6}(k) \\ X_{2}(k+\frac{N}{4})=X_{5}(k) - W_{\frac{N}{2}}^{k} X_{6}(k)\end{matrix}\right\},k=0,1,\cdots ,\frac{N}{4}-1

其中

X_{5}(k)=\sum_{l=0}^{\frac{N}{4}-1} x_{2}(2l)W_{\frac{N}{4}}^{lk}=\sum_{l=0}^{\frac{N}{4}-1} x_{5}(l)W_{\frac{N}{4}}^{lk}                                                                (13)

X_{6}(k)=\sum_{l=0}^{\frac{N}{4}-1} x_{2}(2l+1)W_{\frac{N}{4}}^{lk}=\sum_{l=0}^{\frac{N}{4}-1} x_{6}(l)W_{\frac{N}{4}}^{lk}                                                        (14)

通常会把W_{\frac{N}{2}}^{k} 写成 W_{N}^{2k},这样,一个N点DFT就可以分解成4个\frac{N}{4}点DFT

N=2^{3}=8为例子,进行两次时域抽取分解

如果上图的2点DFT也能化成蝶形运算,就很完美了

X_{3}(k)=\sum_{l=0}^{\frac{N}{4}-1} x_{1}(2l)W_{\frac{N}{4}}^{lk}=\sum_{l=0}^{\frac{N}{4}-1} x_{3}(l)W_{\frac{N}{4}}^{lk},    k=0,1

展开X_{3}(k)有:

X_{3}(0)=x_{3}(0)+W_{2}^{0}x_{3}(1)=x(0)+W_{2}^{0}x(4)=x(0)+W_{8}^{0}x(4)

X_{3}(1)=x_{3}(0)+W_{2}^{1}x_{3}(1)=x(0)+W_{2}^{1}x(4)=x(0)-x(4)

因为W_{8}^{0}=1,所以X_{3}(1)=x(0)-W_{8}^{0}x(4)

由此可以看出2点DFT原本就可以看成一个蝶形运算

对比直接DFT和FFT的运算耗时

编程方法

未完待续。。。

编程实例

未完待续。。。

参考资料

《数字信号处理 华东理工大学 万永菁》课件、视频

《数字信号处理教程》(第5版)程佩青

标签:运算,变换,DFT,FFT,算法,序列,傅里叶
From: https://blog.csdn.net/DGY_ChenYong/article/details/142067102

相关文章

  • FFT
    FFT简介用于求卷积(\(a,b\)已知):\[\sum_{i=0}^na_ib_{n-i}\]或者多项式乘法(\(A(x),B(x)\)已知):\[C(x)=A(x)B(x)\]\(A(x)=\sum_{i=0}^{n}a_ix^i\\B(x)=\sum_{i=0}^{m}b_ix^i\)可见\(C(x)\)是\(n+m\)次多项式。如果我们把卷积的\(a_i,b_i\)看成多项式的系数,卷积......
  • 基于MATLAB蚁群算法优化的小波变换图像压缩
    随着计算机技术和网络速度的飞速发展,数字图像越来越成为人们生活中不可或缺的一部分,然而由于存储和传输的限制,如何对数字图像进行高效压缩成为了研究的热点问题,小波变换作为一种基于多尺度分析的信号处理方法,在数字图像压缩中有着广泛的应用。然而传统的小波变换图像压缩方法......
  • 信号与线性系统实验四 离散系统的时域及变换域分析
    文章目录一、实验目的二、实验内容与原理三、实验器材四、实验步骤五、实验数据及结果分析第一部分:离散时间信号的时域基本运算第二部分:离散LTI系统的时域分析第三部分:离散LTI系统Z域分析六、实验结论七、其他(主要是心得体会)一、实验目的  1.通过本实验的练习......
  • Cooley-Tukey FFT算法的非递归实现
    一维情况#include<iostream>#include<complex>#include<cmath>constdoublePI=3.14159265358979323846;//交换位置voidswap(std::complex<double>&a,std::complex<double>&b){std::complex<double>temp=a......
  • 6_Z字形变换
    6_Z字形变换【问题描述】将一个给定字符串s根据给定的行数numRows,以从上往下、从左到右进行Z字形排列。比如输入字符串为"PAYPALISHIRING"行数为3时,排列如下:PAHNAPLSIIGYIR之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHN......
  • 图形学系列教程,带你从零开始入门图形学(包含配套代码)—— 顶点变换
    图形学系列文章目录序章初探图形编程第1章你的第一个三角形第2章变换顶点变换视图矩阵&帧速率第3章纹理映射第4章透明度和深度第5章裁剪区域和模板缓冲区第6章场景图第7章场景管理第8章索引缓冲区第9章骨骼动画第10章后处理第11章实时光照(一)第12章实时光照(二)第1......
  • 洛谷P1032 [NOIP2002 提高组] 字串变换
    ac代码:#include<bits/stdc++.h>usingnamespacestd;constintN=15;structnode{ stringstr; intstep;};stringa,b;stringorginal[N];stringtranslated[N];intn,ans;map<string,int>ma;stringtrans(conststring&str,inti,i......
  • 是坐标转换,也是旋转——矩阵变换
    坐标转换一个向量可以被表示为\(v=xi+yj+zk\),其中\(i\),\(j\),\(k\)为坐标系的基向量:\(i=\begin{bmatrix}1\\0\\0\end{bmatrix}\),\(j=\begin{bmatrix}0\\1\\0\end{bmatrix}\),\(k=\begin{bmatrix}0\\0\\1\end{bmatrix}\)基向量可写成矩阵的方式:\(\begin......
  • Android开发 - Matrix 处理图像变换解析
    Matrix是什么Matrix是一个用于处理图像变换的类,它可以对图像进行缩放、旋转、平移和倾斜等操作。通俗来讲,Matrix就像是一个数学公式,用来定义如何改变图像的位置、形状或者方向Matrix的主要功能缩放(Scale):可以改变图片的大小,比如放大或缩小旋转(Rotate):可以将图片绕某个......
  • Leetocde 6. Z 字形变换
    将一个给定字符串s根据给定的行数numRows,以从上往下、从左到右进行Z字形排列。比如输入字符串为"PAYPALISHIRING"行数为3时,排列如下:PAHNAPLSIIGYIR之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。请你实现这个......