跳到正文
格致开物MATHWIKI

傅里叶变换与频谱峰识别

傅里叶变换把随时间或位置变化的信号表示为不同频率的分量;对有限、等间隔样本常用离散傅里叶变换(DFT)。频谱峰可帮助寻找周期、薄膜干涉条纹间距或机械振动频率,但一个最大峰不自动等于唯一的物理原因:采样、趋势、窗口和噪声都可能改变峰形。

八点信号的完整计算

设每秒采样 fs=8 次,共 N=8 点,n=0,…,7,信号为 xn=1+cos⁡(2πn/8). 它含常量 1 和一个每秒 1 周期的余弦。DFT 定义为 Xk=∑n=0N−1xne−2πikn/N,k=0,…,N−1. 将余弦展开为两个复指数:cos⁡(2πn/8)=[e2πin/8+e−2πin/8]/2。对每个整数 m,有限等比级数 ∑n=07e2πimn/8 在 m 为 8 的倍数时等于 8,否则为 0。因此 X0=8,X1=X7=4,其余 Xk=0(数值计算时可能是极小舍入残差)。图中的时间样本和频率柱是一回事的两种读法,不是两套独立数据。

八个等间隔样本组成一个余弦周期并有常数基线,离散频谱在零号、 一号与七号频点非零,分别为八、四、四
去掉常量基线后,正负频率对应同一个实余弦周期。

频率格点为 fk=kfs/N;本例 Δf=fs/N=1Hz。X0/N=1 是常量均值;对于非直流且非奈奎斯特频点,实信号的一侧幅值为 2|Xk|/N,故 1 Hz 余弦幅值为 2(4)/8=1。k=7 是 1 Hz 的负频率对应点,不应再当成一个独立的 7 Hz 物理振动。

可运行的八点 DFT

下面只用 Python 标准库复算上例。输入是八个实数,不改写输入;直接求和的时间成本 O(N2)、输出空间 O(N),适合解释定义。长序列应使用快速傅里叶变换(FFT),其成本约为 O(Nlog⁡N)。

Python 3
import cmath
import math

def dft(samples):
    n = len(samples)
    if n == 0:
        return []
    return [
        sum(value * cmath.exp(-2j * math.pi * k * j / n)
            for j, value in enumerate(samples))
        for k in range(n)
    ]

samples = [1 + math.cos(2 * math.pi * j / 8) for j in range(8)]
spectrum = dft(samples)
for k, value in enumerate(spectrum):
    print(k, round(abs(value), 6))

输出中只有 0 8.0、1 4.0 与 7 4.0 非零;其他行是 0.0。若把所有样本都乘以二,DFT 的每个 Xk 也乘二;若只增加一个常量,只改变 X0,这是线性性和常数基线的直接检查。

采样混叠、截断泄漏与峰位

采样间隔是 Δt=1/fs。对实余弦,cos⁡[2π(fs−f)n/fs]=cos⁡(2πfn/fs);在每秒 8 次采样时,1 Hz 与 7 Hz 的这两个余弦在采样点上完全一样。没有额外先验或提高采样率,就不能由这些离散点区分它们。通常先限制原信号带宽低于 fs/2,并在采样前做抗混叠处理;仅把序列补零不会恢复已经混叠的频率。

若真实频率不是 Δf 的整数倍,例如在同样八点、1 秒窗口中是 1.5 Hz,截取的序列在窗口两端通常不能无缝衔接,DFT 能量会分散到邻近频点,称为频谱泄漏。可以先去均值或去基线、选择合适窗函数并说明其主瓣宽度与幅值修正,再比较峰位。补零会把离散频谱曲线插得更密,却不增加这 1 秒观测中的独立信息;提高真实分辨能力要延长观测时长,并核查频率在观察期内是否稳定。

若用于光谱条纹或振动检测,先标明自变量究竟是时间、波长、波数还是空间距离;“峰在 2”只有写上 Hz 或 mm−1 才有物理意义。对噪声信号还应估计峰位不确定度,并在独立记录、不同窗口及有无去趋势处理下复核。非均匀采样不能直接按上述等间隔 DFT 公式给出频率轴。

参考资料与相关词条