简明FFT公式

news/2024/7/6 1:36:43 标签: FFT, 信号处理, 傅里叶变换

1. 傅里叶变换

F ( ω ) = ∫ − ∞ ∞ f ( x ) e − i ω x d x F(\omega)=\int_{-\infty}^{\infty} f(x) e^{-i \omega x} d x F(ω)=f(x)exdx

2. 逆傅里叶变换

f ( x ) = 1 2 π ∫ − ∞ ∞ F ( ω ) e i ω x d ω f(x)=\frac{1}{2 \pi} \int_{-\infty}^{\infty} F(\omega) e^{i \omega x} d \omega f(x)=2π1F(ω)exdω

f(x)是一个关于时间t的函数,信号处理中代表信号值
F(ω)为信号在频域中的表示,描述原始函数f(t)在各个频率ω上的成分或强度
eiωx/e-iωx是旋转因子

3. 离散傅里叶变换(DFT)

A k = ∑ n = 0 N − 1 e − i 2 π N k n a n A_k=\sum_{n=0}^{N-1} e^{-i \frac{2 \pi}{N} k n} a_n Ak=n=0N1eiN2πknan

傅里叶变换针对连续信号,离散傅里叶DFT针对采样得到的离散信号
an表示第n个采样点处(或者说在时间n)信号的强度
Ak表示该信号在频率k上的强度或振幅
总的来说,an是输入信号的离散时间域表示,经过DFT后,将这个时域的表示转换为频域的表示Ak

DFT通常写作:
A k = ∑ n = 0 N − 1 W N k n a n A_k=\sum_{n=0}^{N-1} W_N^{k n} a_n Ak=n=0N1WNknan
其中, W N = e − i 2 π N W_N=e^{-i \frac{2 \pi}{N}} WN=eiN2π

W N k W_N^k WNk ( k = 0 … N − 1 k=0 \ldots N-1 k=0N1) 通常被称为N次单位根。因为在复数运算中, ( W N k ) N = 1 \left(W_N^k\right)^N=1 (WNk)N=1. 复平面上绘制的 N = 2 , N = 4 N=2, N=4 N=2,N=4, N = 8 N=8 N=8的单位根分别如下所示:

复平面单位根

4. 逆离散傅里叶变换(IDFT)

a n = 1 N ∑ k = 0 N − 1 W N − k n A k a_n=\frac{1}{N}\sum_{k=0}^{N-1} W_N^{-k n} A_k an=N1k=0N1WNknAk

其实就是换了个旋转因子

FFT_34">5. 快速傅里叶变换FFT

Cooley-Turkey算法是应用最广泛的FFT算法,采用分而治之的方法,将大DFT分解为小DFT,公式如下:

A k = ∑ n = 0 N − 1 a n W N n k , k = 0 , 1 , ⋯   , N − 1 = ∑ n = 0 N / 2 − 1 a 2 n W N 2 n k + ∑ n = 0 N / 2 − 1 a 2 n + 1 W N ( 2 n + 1 ) k = ∑ n = 0 N / 2 − 1 a 2 n W N 2 n k + W N k ∑ n = 0 N / 2 − 1 a 2 n + 1 W N 2 n k = ∑ n = 0 N / 2 − 1 a 2 n W N / 2 n k + W N k ∑ n = 0 N / 2 − 1 a 2 n + 1 W N / 2 n k = F k + W N k G k , F k = ∑ n = 0 N / 2 − 1 a 2 n W N / 2 n k , G k = ∑ n = 0 N / 2 − 1 a 2 n + 1 W N / 2 n k , k = 0 , 1 , ⋯   , N 2 − 1 \begin{aligned} A_k & =\sum_{n=0}^{N-1}a_n W_N^{n k}, k=0,1, \cdots, N-1 \\ & =\sum_{n=0}^{N / 2-1} a_{2 n} W_N^{2 n k}+ \sum_{n=0}^{N / 2-1} a_{2 n+1} W_N^{(2 n+1) k} \\ & =\sum_{n=0}^{N / 2-1} a_{2 n} W_N^{2 n k}+W_N^k \sum_{n=0}^{N / 2-1} a_{2 n+1} W_N^{2 n k} \\ & =\sum_{n=0}^{N / 2-1} a_{2 n} W_{N / 2}^{n k}+W_N^k \sum_{n=0}^{N / 2-1} a_{2 n+1} W_{N / 2}^{n k} \\ & =F_k+W_N^k G_k, \\ F_k & =\sum_{n=0}^{N / 2-1} a_{2 n} W_{N / 2}^{n k}, G_k=\sum_{n=0}^{N / 2-1} a_{2 n+1} W_{N / 2}^{n k},k=0,1, \cdots, \frac N 2 -1 \end{aligned} AkFk=n=0N1anWNnk,k=0,1,,N1=n=0N/21a2nWN2nk+n=0N/21a2n+1WN(2n+1)k=n=0N/21a2nWN2nk+WNkn=0N/21a2n+1WN2nk=n=0N/21a2nWN/2nk+WNkn=0N/21a2n+1WN/2nk=Fk+WNkGk,=n=0N/21a2nWN/2nk,Gk=n=0N/21a2n+1WN/2nk,k=0,1,,2N1

由此将长度为N的DFT分解为两个长度为N/2的DFT,但是仅能得到前一半频率对应的结果
而由 W N / 2 n k = W N / 2 n ( k + N / 2 ) , W N n k = − W N n ( k + N / 2 ) W_{N / 2}^{n k}=W_{N / 2}^{n (k+N/2)}, W_{N}^{n k}=-W_{N}^{n (k+N/2)} WN/2nk=WN/2n(k+N/2),WNnk=WNn(k+N/2),可得 F k + N 2 = F k , G k + N 2 = G k F_{k+\frac N 2} = F_k, G_{k+\frac N 2} = G_k Fk+2N=Fk,Gk+2N=Gk,即:

A k + N 2 = F k + N 2 + W N k + N 2 G k + N 2 , k = 0 , 1 , ⋯   , N 2 − 1 = F k − W N k G k \begin{aligned} A_{k+\frac N 2}& =F_{k+\frac N 2}+W_N^{k+\frac N 2} G_{k+\frac N 2},k=0,1, \cdots, \frac N 2 -1\\ &=F_k-W_N^k G_k \end{aligned} Ak+2N=Fk+2N+WNk+2NGk+2N,k=0,1,,2N1=FkWNkGk

DFT时间复杂度为 O ( N 2 ) {O}({N^2}) O(N2)FFT时间复杂度为 O ( N l o g 2 N ) O(Nlog_2N) O(Nlog2N)

FFT处理的离散序列长度为1,可以发现如下蝶形运算
蝶形运算
蝶形运算组合成蝶形网络,以N=8的FFT为例:
蝶形网络

IFFT同理,换个旋转因子即可

———————————————————————————————— ———————————————————————————————— ————————————————————————————————

参考: Fourier transforms and the fast Fourier transform (FFT) algorithm


http://www.niftyadmin.cn/n/5299948.html

相关文章

C语言中的联合体的由来和存储

一、联合体的由来 1.1. 数据类型的不足 C语言中,基本数据类型只有整型、字符型、浮点型等少数几种,无法满足复杂数据类型的需要。 1.2. 数组的限制 虽然数组可以存储多个同类型的数据,但是数组中的元素个数是固定的,无法动态地…

Redis源码——压缩列表

压缩列表ziplist本质上就是一个字节数组,是Redis为了节约内存而设计的一种线性数据结构,可以包含多个元素,每个元素可以是一个字节数组或一个整数。Redis的有序集合、散列和列表都直接或者间接使用了压缩列表。当有序集合或散列表的元素个数比…

3D视觉-相机选用的原则

鉴于不同技术方案都有其适用的场景,立体相机的选型讲究的原则为“先看用途,再看场景,终评精度”,合适的立体相机在方案中可以起到事半功倍的效果。从用途上来进行划分,三维视觉方案主要应用在两个方向:测量…

004、变量与可变性

1. 变量与可变性 在Rust中,变量默认是不可变的,这一设计是为了让你安全方便地写出复杂、甚至是并行的代码。 当然,Rust也提供了可使用的可变变量的方法,这个待会讨论。 当一个变量是不可变时,一旦它被绑定到某个值上面…

[设计模式 Go实现] 创建型~建造者模式

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。 代码实…

redis数据库高可用应用场景-配置哨兵

一,redis数据库哨兵的使用场景 Redis哨兵机制通常在需要高可用性的 Redis 环境中使用,如果是普通的项目,只是用来做缓存的可以忽略。 适用场景: 高可用性需求:当需要确保 Redis 服务的高可用性并且防止单点故障时&…

【linux】echo命令踩坑详解

想用echo 命令把修改完的一段字符写入文件,发现换行符被当作正常字符处理了。一查发现默认是特殊字符是不转义的。 在shell脚本中,echo常用于显示消息或输出其他命令的结果。 echo命令的语法 echo[-neE] [参数] 当使用-n选项时,会抑制末尾的…

React实现拖拽效果

基于 React 的拖拽效果 Demo 一个基于 React 的拖拽功能实现的 Demo. 两个关键点 1, draggable 属性 2, drag 事件 draggable 属性 img 标签默认是支持拖拽的, 当时其他 HTML 标签, 想要其拖动的话, 需要为其添加 draggable“true” 属性 drag 事件 drag 相关的事件有:…