1. 傅里叶级数 Fourier Series (FS)
傅里叶级数得名于法国数学家约瑟夫·傅里叶,他提出任何函数都可以展开为三角级数。
考虑一个在区间 [t0,t0+T] 上可积的函数 f(t),其傅里叶级数为
f(t)=2a0+n=1∑∞(ancosT2πnt+bnsinT2πnt)(1)
其中
an=T2∫t0t0+Tf(t)cosT2πntdt,n=0,1,2,⋯(2)
bn=T2∫t0t0+Tf(t)sinT2πntdt,n=1,2,⋯(3)
由欧拉公式 eiθ=cosθ+isinθ 得
cosθsinθ=21(eiθ+e−iθ)=−2i(eiθ−e−iθ)(4)
代入(1)可得
f(t)=2a0+n=1∑∞(2an−ibneiT2πnt+2an+ibne−iT2πnt)(5)
令
cn=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧2an−ibn2a02a∣n∣+ib∣n∣n>0n=0n<0(6)
则可以得到傅里叶级数的复数形式
f(t)=n=−∞∑+∞cneiT2πnt(7)
其中
cn=T1∫t0t0+Tf(t)e−iT2πntdt,n=0,±1±2,⋯(8)
傅里叶变换可以看作傅里叶级数的连续形式。
首先考虑定义在 [−2T,2T] 上的函数的傅里叶级数展开:
f(t)=n=−∞∑+∞cneiT2πnt(9)
其中
cn=T1∫−T/2T/2f(t)e−iT2πntdt,n=0,±1±2,⋯(10)
令
Δω=T2π(11)
记
f^(nΔω)=Tcn=∫−T/2T/2f(t)e−inΔωtdt,n=0,±1,±2,⋯(12)
则
cn=Tf^(nΔω)=2πΔωf^(nΔω)(13)
f(t)=n=−∞∑+∞cneiT2πnt=2π1n=−∞∑+∞f^(nΔω)einΔωtΔω(14)
当 T→∞ 时,nΔω→ω,Δω→dω, (14) 中的求和变为积分
f(t)=2π1∫−∞+∞f^(ω)eiωtdω(15)
相应地,(12) 变为
f^(ω)=∫−∞+∞f(t)e−iωtdt(16)
(16) 称为傅里叶变换,记作 f^(ω)=F[f](t);(15) 称为傅里叶变换的逆变换,记作 f(t)=F−1[f^](ω)。在信号分析中,f(t) 称为信号的时域表示,f^(ω) 称为信号的频域表示。
需要明确的是,不管是用时域还是用频域来表示一个信号,它们代表的都是同一个信号。可以从线性空间的角度理解这一点。同一个信号在不同的表象(或者说基向量)下具有不同的坐标。同一个向量在不同表象下的坐标可以通过一个线性变换联系起来。如果是有限维的空间,这个线性变换可以表示为一个矩阵。而傅里叶变换则是无限维空间不同表象之间的一种变换。举例来说,在量子力学中,一个波函数的坐标表象到动量表象间的变换就是一个傅里叶变换。
也可以将角频率 ω 替换为自然频率 ν,有 ω=2πν,则
f^(ν)=Ff(t)=∫−∞+∞f(t)e−i2πνtdt(17)
f(t)=F−1f^(ν)=∫−∞+∞f^(ξ)ei2πνtdν(18)
一般情况下,我们处理的信号都是离散的。取 f(t) 在时间上的离散采样
fn=f(nτ),n=0,±1,±2,⋯(19)
τ 是采样的时间间隔。傅里叶变换只能作用在连续函数上,为此我们引入
fs(t)=f(t)n=−∞∑+∞δ(t−nτ)=n=−∞∑+∞f(t)δ(t−nτ)=n=−∞∑+∞fnδ(t−nτ)(20)
其中
δ(x)={+∞,0,x=0x=0(21)
为 Dirac 函数。n=−∞∑+∞δ(t−nτ) 称为 Dirac 梳子,亦称 Shah 分布,是一个采样函数,常用在数字信号处理和离散时间信号分析中。
对 fs(t) 作傅里叶变换
f^s(ω)=∫−∞+∞fs(t)e−iωtdt=∫−∞+∞n=−∞∑+∞f(t)δ(t−nτ)e−iωtdt=n=−∞∑+∞∫−∞+∞δ(t−nτ)f(t)e−iωtdt=n=−∞∑+∞fne−iωnτ(22)
这里利用了 Dirac 函数的性质 ∫−∞+∞δ(x)g(x)dx=g(0)。(22) 即为离散时间傅里叶变换。
下面简单介绍一下采样定理。若原信号 f(t) 不包含高于 Ωm 的频率,即 f^(ω)=0,∀∣ω∣>Ωm,则只要采样频率 ωs≥2Ωm,时域采样就能完全重建原信号。
将 f^(ω) 在 [−2ωs,2ωs] 上展开为傅里叶级数
f^(ω)=m=−∞∑+∞cmeiωs2πmω(23)
其中
cm=ωs1∫−ωs/2ωs/2f^(ω)e−iωs2πmωdω(24)
注意到 ∣ω∣>Ωm 时 f^(ω)=0,而 ωs≥2Ωm,故 ∣ω∣>ωs/2 时 f^(ω)=0,因此 (24) 可改写为
cm=ωs1∫−∞+∞f^(ω)e−iωs2πmωdω=ωs2πf(−ωs2πm)=τf(−mτ)=τf−m(25)
代入 (23),得
f^(ω)=m=−∞∑+∞τf−meiωs2πmω=n=−∞∑+∞τfne−iωs2πnω=τn=−∞∑+∞fne−iωnτ=τf^s(ω)(26)
这里 n=−m。(26) 说明原信号的傅里叶变换可以由采样信号确定,进而可以利用傅里叶逆变换重建原信号。
此外,不难发现
f^s(ω)=n=−∞∑+∞fne−iωnτ=n=−∞∑+∞fne−i2πnωsω(27)
是一个周期为 ωs 的周期函数。离散傅里叶变换f^s(ω)可以看作原信号连续傅里叶变换f^(ω)的周期延拓,时域的离散化造成了频域的周期化。
离散时间傅里叶变换在频域上仍然是连续的。如果把频域也离散化,就得到了离散傅里叶变换。
f^k=n=0∑N−1fne−iN2πnk,k=0,1,⋯,N−1(28)
也可以写成矩阵形式
⎣⎢⎢⎢⎢⎢⎢⎡f^0f^1f^2⋮f^N−1⎦⎥⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎡111⋮11φφ2⋮φN−11φ2φ4⋮φ2(N−1)⋯⋯⋯⋱⋯1φN−1φ2(N−1)⋮φ(N−1)2⎦⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎡f0f1f2⋮fN−1⎦⎥⎥⎥⎥⎥⎤(29)
其中 φ=e−i2π/N。
离散傅里叶变换的逆变换为
fn=N1k=0∑N−1f^keiN2πnk,n=0,1,⋯,N−1(30)
直接根据定义计算离散傅里叶变换的复杂度是 O(N2)。快速傅里叶变换是快速计算离散傅里叶变换及其逆变换的一类数值算法。FFT 通过把 DFT 矩阵分解为稀疏矩阵之积,能够将复杂度降低到 O(NlogN)。
在 Python 中可以利用 scipy.fftpack
进行快速傅里叶变换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import numpy as np import pandas as pd import matplotlib.pyplot as plt
from scipy.fftpack import fft, ifft
x = np.linspace(0, 2*np.pi, 200) y = np.cos(5*x) + 0.5*np.sin(25*x) + 0.3*np.cos(75*x) plt.figure(figsize=(10,12)) ax1 = plt.subplot(311) ax1.plot(x, y, 'r') ax1.set_title('original signal in time domain')
Y = fft(y) ax2 = plt.subplot(323) ax2.plot(range(200), abs(Y)) ax2.set_title('original signal in frequency domain')
Y[10:-9] = 0 ax3 = plt.subplot(324) ax3.plot(range(200), abs(Y)) ax3.set_title('filtered signal in frequency domain')
filtered = ifft(Y).real ax4 = plt.subplot(313) ax4.plot(x, filtered, 'g') ax4.set_title('filtered signal in time domain')
|
参考文献
- 小波与傅里叶分析基础(第二版), 电子工业出版社,2017.6
- Fourier transform - Wikipeida
- Discrete-time Fourier transform - Wikipedia
- Discrete Fourier transform - Wikipedia
- Discrete Fourier transforms (scipy.fftpack)