1. 先从结论清单说起离散傅里叶变换到底有哪些“常用结论”做信号处理的人不管你是搞音频算法、通信基带还是做故障诊断早晚都要跟离散时间傅里叶变换DTFT打交道。我以前上课的时候老师把一堆性质往黑板上一写线性、时移、频移、卷积、帕塞瓦尔当时记是记住了但说实话没几个是真证过的。等到后来自己做项目发现很多结论用起来不对味回头重新翻书才意识到“会用”和“真懂”之间的差距有多大。这篇文章我不想堆公式而是挑离散系统傅里叶变换里最常用的几组结论把证明过程掰开揉碎了讲清楚。重点放在为什么这些结论长这样、证明的关键步骤卡在哪里、以及实际做题和写代码时怎么用它们不出错。适合正在学信号与系统的学生、考研复习党以及工作中需要补一补理论基础的工程师。先列一个清单这就是我们这篇文章要逐个攻克的常用结论DTFT的定义与存在条件以及它和离散时间周期信号的关系线性性质、时移性质、频移性质的证明卷积定理时域卷积对应频域相乘相乘性质时域相乘对应频域卷积带周期性修正帕塞瓦尔定理能量守恒对称性结论实信号的幅度谱偶对称、相位谱奇对称三角脉冲的傅里叶变换以及一个好用的记忆方法相位问题为什么很多教科书上的结论“丢了相位”实际计算时怎么找回来这些结论在教科书里往往是零散给出的每一条单独看都不难但串起来用的时候很容易在细节上翻车。我后面会按照“先定义、再性质、后应用”的顺序来展开每一步都给出完整的推导并标注出那些容易被忽略的前提条件。有人可能会问现在都用FFT算了Matlab一个fft()下去什么都出来了还学这些手推的东西干什么我的回答是FFT算出来的是一个有限长序列的离散傅里叶变换DFT而不是DTFT的完整频谱。你用FFT看到的谱线、泄漏、栅栏效应这些现象全部源于DTFT和DFT之间的关系。不懂DTFT你就永远搞不明白为什么加窗、为什么补零、为什么频谱会“糊”成一团。所以说这些“纸面功夫”恰恰是工程直觉的地基。2. 从定义出发DTFT的表达式与存在条件DTFT的定义式是这样的[ X(e^{j\omega}) \sum_{n-\infty}^{\infty} x[n] e^{-j\omega n} ]其中 (x[n]) 是离散时间序列(\omega) 是归一化数字角频率单位是弧度/样本。注意这里(\omega)是一个连续变量所以即便(x[n])是离散的它的频谱(X(e^{j\omega}))也是连续函数而且一定是周期的周期是(2\pi)。为什么是周期函数很简单[ X(e^{j(\omega2\pi)}) \sum_{n-\infty}^{\infty} x[n] e^{-j(\omega2\pi)n} \sum_{n-\infty}^{\infty} x[n] e^{-j\omega n} e^{-j2\pi n} ]因为(e^{-j2\pi n}1)对所有整数(n)成立所以(X(e^{j(\omega2\pi)})X(e^{j\omega}))。这就是DTFT周期性的来源。这个周期性的结论看起来不起眼但它解释了一个初学者很容易困惑的问题为什么数字频率只有(0\sim 2\pi)或者(-\pi\sim\pi)而模拟频率可以一直往上加因为数字频率本身就是“归一化”过的它跟模拟频率的换算是(\omega \Omega T_s)(T_s)是采样周期。一旦采样高于奈奎斯特频率的成分就会折叠回来这在频谱上就表现为周期性延拓。2.1 存在条件绝对可和与能量有限DTFT不是对所有序列都有定义的。最常用的存在条件是绝对可和[ \sum_{n-\infty}^{\infty} |x[n]| \infty ]这个条件保证了级数逐点收敛(X(e^{j\omega}))是连续的。如果只是能量有限也就是[ \sum_{n-\infty}^{\infty} |x[n]|^2 \infty ]那DTFT是均方意义下收敛的频谱可能存在间断点。这两种收敛的差别很微妙但工程上经常用到。比如单位阶跃序列(u[n])它既不绝对可和也不能量有限严格来说DTFT不存在。但我们在实际信号处理里经常要给阶跃、符号等信号“强行”写一个频谱表达式这时候就要引入冲激函数。教科书上对这类信号的处理方式是用极限定义或者通过指数衰减序列取极限来逼近。我个人的经验是做题的时候先看一眼序列长什么样如果它是指数衰减型的那放心大胆地用定义算如果是常数、阶跃、周期序列这类就得小心结果里往往藏着一个冲激项或者说若干个冲激串。2.2 逆变换从频谱回到序列DTFT的逆变换IDTFT定义是[ x[n] \frac{1}{2\pi} \int_{-\pi}^{\pi} X(e^{j\omega}) e^{j\omega n} d\omega ]这个式子从直观上理解非常漂亮它告诉我们任意一个离散序列都可以分解成无数个频率为(\omega)、幅度为(X(e^{j\omega}))的复指数信号的叠加。积分区间只在(-\pi\sim\pi)里面取因为超出这个范围的频率跟区间内的某个频率是“一回事”。证明IDTFT可以这样走把DTFT的定义式代入IDTFT[ \frac{1}{2\pi} \int_{-\pi}^{\pi} \left[\sum_{m-\infty}^{\infty} x[m] e^{-j\omega m}\right] e^{j\omega n} d\omega ]交换积分和求和的次序在绝对可和条件下合法[ \sum_{m-\infty}^{\infty} x[m] \cdot \frac{1}{2\pi} \int_{-\pi}^{\pi} e^{j\omega(n-m)} d\omega ]积分那一项是可以直接算出来的[ \frac{1}{2\pi} \int_{-\pi}^{\pi} e^{j\omega(n-m)} d\omega \frac{\sin[\pi(n-m)]}{\pi(n-m)} ]当(nm)的时候这个值等于1当(n\neq m)的时候因为(\sin[\pi(n-m)]0)所以等于0。换句话说这个积分就是离散域的单位冲激(\delta[n-m])。代回去就得到[ \sum_{m} x[m] \delta[n-m] x[n] ]整个证明到这里就闭合了逻辑链完整且干净。写代码的时候我们很少直接做IDTFT积分都是用IDFT逆离散傅里叶变换来近似。但理解IDTFT的意义对做滤波器设计很有帮助FIR滤波器设计里的窗函数法本质上就是“先算理想滤波器的无限长冲激响应再用窗函数截断近似为有限长”中间那一步用的就是IDTFT的积分。3. 五大基本性质的证明与工程含义这一节进入正题把最常用的几个性质逐一证明。它们不是孤立的知识点而是后面推导卷积定理、帕塞瓦尔公式的工具。3.1 线性性质最基础也是最能出错的地方如果(x[n]\leftrightarrow X(e^{j\omega}))(y[n]\leftrightarrow Y(e^{j\omega}))那么[ a x[n] b y[n] \leftrightarrow a X(e^{j\omega}) b Y(e^{j\omega}) ]证明只用一步把线性组合代入定义然后利用求和可拆分的性质即可。线性性质看起来简单到不值一提但实际用的时候有两个坑值得注意。第一个坑是ROC收敛域问题。虽然DTFT不像z变换那样有一块明显的收敛域但“绝对可和”这个条件本质上是依赖序列的衰减速度快慢的。两个各自都绝对可和的序列做线性组合之后仍然绝对可和这个没问题。但如果一个序列不绝对可和是靠冲激项扩展定义的比如常数序列两个这样的序列相减可能抵消掉冲激项也可能产生新的冲激项处理起来非常容易错。第二个坑跟“叠加”有关。我们做系统分析时经常说“线性系统满足叠加定理”所以对输入信号分解后用频谱逐个处理再合起来。这个思路本身没错但只适用于线性时不变系统。如果系统里带非线性环节比如平方律检波、比较器就不能用DTFT直接做线性拆分了。这类问题我建议改用频域卷积的思路来处理或者直接在时域做数值仿真。3.2 时移性质为什么是乘上(e^{-j\omega n_0})而非其他形式若(y[n] x[n-n_0])则[ Y(e^{j\omega)} e^{-j\omega n_0} X(e^{j\omega}) ]证明代入定义[ Y(e^{j\omega}) \sum_{n-\infty}^{\infty} x[n-n_0] e^{-j\omega n} ]令(mn-n_0)则(nmn_0)代入得[ Y(e^{j\omega}) \sum_{m-\infty}^{\infty} x[m] e^{-j\omega(mn_0)} e^{-j\omega n_0} \sum_{m-\infty}^{\infty} x[m] e^{-j\omega m} e^{-j\omega n_0} X(e^{j\omega}) ]这里只有一个细节需要注意新的求和变量(m)的取值范围仍然是整个整数集因为(n-n_0)遍历所有整数所以不需要修改求和上下限。很多初学者在这个地方会犹豫“要不要改求和范围”答案是“不用”。工程上时移性质最常见的用途有两个。一个是分析滤波器相频响应一个长度有限、系数对称的FIR滤波器其相位响应对应一个固定时延((N-1)/2)这个时延就是从时移性质来的。另一个是分析波束形成里的相控阵每个阵元接收的信号由于到达时间不同在频域上就是乘了一个与角度相关的相位因子波束扫描的核心公式就是从时移性质里推出来的。3.3 频移性质理解调制与变频的钥匙若(y[n] e^{j\omega_0 n} x[n])则[ Y(e^{j\omega}) X(e^{j(\omega-\omega_0)}) ]证明直接代入定义[ Y(e^{j\omega}) \sum_{n} x[n] e^{j\omega_0 n} e^{-j\omega n} \sum_{n} x[n] e^{-j(\omega-\omega_0) n} X(e^{j(\omega-\omega_0)}) ]这个性质在通信里的地位极高。数字调制、频谱搬移、正交混频全部都是在用频移性质。但这里必须提醒一个工程上经常犯的错误频谱搬移不是“免费”的。离散系统的频谱是(2\pi)周期的搬移后原来的频谱一片一片地平移一旦搬移量太大就会发生混叠。很多人在做数字上变频的时候直接把基带信号乘一个高频载波序列结果频谱混叠得一塌糊涂就是因为忽视了频移后的周期性重叠问题。具体来说假设基带信号的频谱集中在(-\pi/2 \sim \pi/2)现在要搬到(\omega_0 2\pi \times 0.3)的位置上去那么搬移后频谱的中心在(2\pi \times 0.3)处向两边延伸在周期延拓的时候就会跟相邻周期重叠。解决办法一般是在搬移前先做插值提高采样率这个操作的数学本质就是给频谱在周期内留出足够的安全间隔避免搬移后的频谱混到一起。3.4 卷积定理时域卷积对应频域相乘若(y[n] x[n] * h[n])则[ Y(e^{j\omega}) X(e^{j\omega}) H(e^{j\omega}) ]证明过程是[ Y(e^{j\omega}) \sum_{n} \left[\sum_{k} x[k] h[n-k]\right] e^{-j\omega n} ]交换求和顺序绝对可和条件下合法[ Y(e^{j\omega}) \sum_{k} x[k] \sum_{n} h[n-k] e^{-j\omega n} ]对内层和式用时移性质得到[ \sum_{n} h[n-k] e^{-j\omega n} e^{-j\omega k} H(e^{j\omega}) ]代回去[ Y(e^{j\omega}) \sum_{k} x[k] e^{-j\omega k} H(e^{j\omega}) X(e^{j\omega}) H(e^{j\omega}) ]整个证明最核心的“机关”就是内层求和用时移性质换成了(e^{-j\omega k}H(e^{j\omega}))剩下的就是把常数因子(H(e^{j\omega}))从求和里提出来。卷积定理是整个线性系统频域分析法的基石。滤波器设计、信道建模、系统辨识全部建立在这个结论上。工程上线性卷积可以用FFT加分段重叠相加法来快速实现其理论依据正是卷积定理先在频域相乘再逆变换回时域。3.5 相乘性质频域卷积定理非线性的入口若(y[n] x_1[n] x_2[n])则有[ Y(e^{j\omega}) \frac{1}{2\pi} \int_{-\pi}^{\pi} X_1(e^{j\theta}) X_2(e^{j(\omega-\theta)}) d\theta ]这个性质的证明比卷积定理稍微麻烦一点因为它需要利用IDTFT把(x_1[n])表示成频谱积分再代入(y[n])的定义中最后交换积分求和次序。[ Y(e^{j\omega}) \sum_{n} x_1[n] x_2[n] e^{-j\omega n} ]把(x_1[n] \frac{1}{2\pi}\int_{-\pi}^{\pi} X_1(e^{j\theta}) e^{j\theta n} d\theta)代进去[ Y(e^{j\omega}) \sum_{n} \left[\frac{1}{2\pi}\int_{-\pi}^{\pi} X_1(e^{j\theta}) e^{j\theta n} d\theta\right] x_2[n] e^{-j\omega n} ]交换积分与求和[ Y(e^{j\omega}) \frac{1}{2\pi}\int_{-\pi}^{\pi} X_1(e^{j\theta}) \left[\sum_{n} x_2[n] e^{-j(\omega-\theta)n}\right] d\theta ]中括号里正好是(X_2(e^{j(\omega-\theta)}))因此结论成立。相乘性质在工程上意味着时域相乘调制、加窗、信号相乘会在频域上产生频谱卷积直观表现就是频谱被“抹平”或者“搬移”。这就是为什么乘一个窗函数后频谱会出现主瓣变宽、旁瓣泄漏。很多人做频谱分析时看到泄漏就头疼其实根源就在这个定理你把一段无限长信号乘上矩形窗等效于在频域把原信号的频谱与(\mathrm{sinc})函数的频谱做卷积每个频点都被(\mathrm{sinc})的旁瓣“污染”了。理解了这一点你对窗函数的选择就会变得有方向感而不是盲目试几个窗就完事。4. 帕塞瓦尔定理与能量谱的关系帕塞瓦尔定理也是“常用结论”里的高频考点。它的表述是[ \sum_{n-\infty}^{\infty} |x[n]|^2 \frac{1}{2\pi} \int_{-\pi}^{\pi} |X(e^{j\omega})|^2 d\omega ]翻译成人话就是时域算出来的总能量等于频域算出来的总能量。这里的(|X(e^{j\omega})|^2)称为能量谱密度单位频率上的能量分布。4.1 证明过程从时域能量出发[ \sum_{n} |x[n]|^2 \sum_{n} x[n] x^*[n] ]其中(x^[n])是共轭。利用IDTFT写出(x[n])的表达式同时利用共轭性质得到(x^[n])的频域表示。具体写法是[ x[n] \frac{1}{2\pi}\int_{-\pi}^{\pi} X(e^{j\omega}) e^{j\omega n} d\omega ][ x^[n] \frac{1}{2\pi}\int_{-\pi}^{\pi} X^(e^{j\omega}) e^{-j\omega n} d\omega ]代回能量式[ \sum_{n} |x[n]|^2 \sum_{n} \frac{1}{2\pi}\int X(e^{j\omega}) e^{j\omega n} d\omega \cdot \frac{1}{2\pi}\int X^*(e^{j\theta}) e^{-j\theta n} d\theta ]交换积分和求和顺序后对(n)的求和等于(2\pi\delta(\omega-\theta))可以消掉一个积分最后就得到[ \sum_{n} |x[n]|^2 \frac{1}{2\pi} \int_{-\pi}^{\pi} X(e^{j\omega}) X^*(e^{j\omega}) d\omega \frac{1}{2\pi} \int_{-\pi}^{\pi} |X(e^{j\omega})|^2 d\omega ]证明本身不复杂关键是注意共轭的处理频域共轭对应时域取共轭后的时间反转不要把它跟一般复数运算搞混。4.2 帕塞瓦尔定理的使用心得做工程的时候我用这个定理做过两件比较实在的事。第一件是验证FFT算法的正确性算完FFT后把频域各个点的幅度平方加起来跟时域序列的平方和做一个比较误差应该非常小。如果这个校验不过那基本可以确定是FFT实现有bug或者有数据越界的问题。第二件是估计信噪比把信号能量的实测值跟理论频谱积分的值比对可以反过来推测噪声能量占了多少评估系统底噪是否异常。另外有一个常见认知误区我必须提一下帕塞瓦尔定理说的是总能量守恒但不代表每个频点的能量都不变。经过一个非理想滤波器后通带内频点能量下降通带外的能量被滤除总能量自然减小这是正常的。不要拿帕塞瓦尔定理去验证“信号通过滤波器后每个频点幅度是否还等于原幅度”那是两回事。5. 对称性结论与相位问题的陷阱5.1 实信号的幅度谱偶对称、相位谱奇对称对于实序列(x[n])它的DTFT满足[ X(e^{j\omega}) X^*(e^{-j\omega}) ]把这个式子拆成实部和虚部来看。设(X(e^{j\omega})A(\omega)jB(\omega))那么(X^*(e^{-j\omega})A(-\omega)-jB(-\omega))。两边对照可以得到[ A(\omega)A(-\omega) ] [ B(\omega)-B(-\omega) ]也就是说实部是偶函数虚部是奇函数。进一步可以推出幅度谱(|X(e^{j\omega})|)是偶函数相位谱(\angle X(e^{j\omega}))是奇函数这个结论在画频谱图时非常方便你只需要画出(0\sim\pi)范围内的幅度谱和相位谱另一半自然对称或反对称地补全。证明的关键在于实序列的共轭和原序列相等因为实数的共轭就是它自己求DTFT后得到(X(e^{j\omega})X^*(e^{-j\omega}))。5.2 相位谱“失常”的常见原因实际使用MATLAB的angle()函数画相位谱时你会发现相位曲线不是平滑的直线而是锯齿状跳变反复在(\pi)和(-\pi)之间跌宕。很多人以为这是“bug”其实这是因为相位被折叠到主值区间((-\pi,\pi])内了。举例来说一个纯延迟系统(H(e^{j\omega})e^{-j\omega n_0})的相位是(-\omega n_0)。当(n_0)比较大时这个相位在(-\pi\sim\pi)范围内来回绕圈画出来就是锯齿。要还原真实的线性相位你需要用相位解缠绕unwrap算法MATLAB里有unwrap()函数。更隐蔽的一个坑是数字滤波器在阻带内的相位响应几乎无意义。因为阻带内幅度接近0相位是由数值噪声主导的angle()算出来的值在(-\pi)和(\pi)之间随机跳变。看到这种相位图千万别慌它不是系统坏了而是数值精度问题。正确的做法是只在通带内讨论相位响应或者使用幅度加权相位来评估。5.3 对称性结论在滤波器设计中的活用实系数FIR滤波器的频率响应满足上述对称性。设计带通滤波器时用频率取样法构造目标响应只需要在正频率部分定义幅度值负频率部分自动镜像生成。这个操作在代码里就是频域数组拼接先构造正频率部分再翻转共轭出负频率部分。我见过不少新手在写频率取样法时忘了构造负频率部分直接把目标频谱丢给ifft()结果出来的时域序列是复数的滤波器系数根本不是实的。后来我习惯在ifft之后加一行断言检查实部共轭对称性是否满足若不过就立刻报错。这样能尽早发现问题不用等仿真结果乱套了才回头查。6. 三角脉冲的傅里叶变换一个背起来很爽的记忆方法三角脉冲的傅里叶变换是考点里的常客很多同学觉得它难背因为它要么算出一个(\mathrm{sinc}^2)形式的表达式要么算出一个带平方倒数的表达式前前后后推导挺麻烦的。这里分享一个我用了很多年的记忆方法简洁实用。6.1 核心思路两次差分把三角脉冲变成三个冲激设离散时间三角脉冲定义为高度递减的序列比如[ x[n] \begin{cases} 1 - \frac{|n|}{N}, |n| \leq N \ 0, \text{otherwise} \end{cases} ]这个序列的样子就是一个以(n0)为顶点的等腰三角形。在离散域里三角脉冲和矩形脉冲之间有天然的“二阶差分”关系对三角脉冲做二阶差分会在顶点和两个端点处冒出一正一负的冲激对。具体来说记(r[n])为长度为(2N1)的三角脉冲。将它做一阶差分(r[n]-r[n-1])会得到一个阶梯形序列再做一次差分最终得到的是三个冲激[ r[n]-2r[n-1]r[n-2] \delta[nN] - 2\delta[n] \delta[n-N] ]注意我这里写的是“广义”差分形式用移位和冲激来表示。根据DTFT的线性性质和时移性质对上式两边取DTFT。右边直接可以写出来[ e^{j\omega N} - 2 e^{-j\omega N} 2\cos(\omega N) - 2 -4\sin^2\left(\frac{\omega N}{2}\right) ]左边呢差分运算对应于频域乘以((1-e^{-j\omega})^2)所以[ (1-e^{-j\omega})^2 X(e^{j\omega}) -4\sin^2\left(\frac{\omega N}{2}\right) ]因此[ X(e^{j\omega}) \frac{-4\sin^2\left(\frac{\omega N}{2}\right)}{(1-e^{-j\omega})^2} ]再化简一下。注意(1-e^{-j\omega} e^{-j\omega/2}\cdot 2j\sin(\omega/2))所以[ (1-e^{-j\omega})^2 -4 e^{-j\omega} \sin^2(\omega/2) ]代进去负号消掉[ X(e^{j\omega}) \frac{\sin^2\left(\frac{\omega N}{2}\right)}{e^{-j\omega}\sin^2(\omega/2)} e^{j\omega} \left[\frac{\sin(\omega N/2)}{\sin(\omega/2)}\right]^2 ]这里多出来的(e^{j\omega})因子是差分操作的边界效应带来的它不改变幅度谱的形状只影响相位。很多教材会忽略这个线性相位因子说三角脉冲的频谱是(\sin^2(\omega N/2)/\sin^2(\omega/2))大家也习惯了。6.2 记忆锚点把推导过程浓缩成三个关键词第一次出现“分子的平方”因为三角脉冲是矩形脉冲卷积自己得到的卷积定理要求频域相乘而矩形脉冲的DTFT是一个Dirichlet核所以三角脉冲的频谱是它的平方。第二次出现“分母的sin”分母的(\sin(\omega/2))来源于离散域差分的频域对应它专门负责把“离散”的味道带出来。连续域的类比连续域的三角脉冲傅里叶变换是(\mathrm{sinc}^2)离散域只是把(\mathrm{sinc})换成Dirichlet核采样形式本质是一样的。要用一句话记住的话矩形卷积矩形等于三角所以频谱是一个(\sin)除以另一个(\sin)的平方。这个方法我用了好几年做题时几乎不用翻书直接在脑子里搭出频谱的结构。6.3 配套的“相位”记忆有人可能会问“为什么有的书上写三角脉冲频谱是正的有的书带一个相位因子”这取决于差分运算的起点。用中心差分定义的时候推导会自然带出一个(e^{j\omega})用对称定义直接算积分则会避开。实际上对于对称的实信号幅度谱才是我们更关心的相位谱通常在信号完全对称时是线性的且斜率和时间中心的位置相关。做题的时候我的习惯是这样的先判断三角脉冲的对称轴在哪里对称轴在(n0)处则频谱是实偶函数没有多余相位项如果对称轴在某个非零位置需要乘一个对应的时移相位因子。这个习惯避免了大量的符号错误。7. 对称对称再对称共轭对称在离散频谱中的角色我一直觉得离散傅里叶变换的性质里最容易被低估的就是共轭对称性。它不仅是理论上的美丽结论更是工程实践的“高效工具”。7.1 通用共轭对称结论对于任意复序列(x[n])可以拆成共轭对称分量和共轭反对称分量。话说回来DTFT也有类似的分解但工程上更常用的是那么一句话如果时域序列是实序列频域一定满足共轭对称。这个结论我已经在前面证明过了。进一步地如果时域序列是实偶序列即(x[n]x[-n])那么它的DTFT也是实偶函数[ X(e^{j\omega}) \sum_{n} x[n] \cos(\omega n) - j\sum_{n} x[n] \sin(\omega n) ]因为(x[n])偶对称(\sin(\omega n))奇对称关于(n)乘积的奇函数项求和为0虚部消失剩下的是偶函数形式的实部[ X(e^{j\omega}) \sum_{n} x[n]\cos(\omega n) x[0] 2\sum_{n1}^{\infty} x[n]\cos(\omega n) ]如果时域序列是实奇序列(x[n]-x[-n])则它的DTFT是纯虚奇函数。这两条结论在分析窗函数、滤波器冲激响应时使用频率极高。7.2 工程上的“半频谱”技巧实信号的频谱共轭对称意味着负频率部分的信息是完全冗余的。在做FFT后处理时我们通常只取前一半(0\sim N/2)的频谱数据来分析后一半是需要丢弃或者用共轭对称性来校验的。这不仅省存储也省计算。有一次我在调试一个振动信号分析程序时发现时域数据明明是实数但FFT出来的虚部不为零而且幅度谱也不对称。排查了半天最后发现问题出在数据采集模块某一路AD通道的零点漂移导致信号叠加了一个缓变趋势项。这个趋势项本质上不是一个纯实数序列在做FFT时破坏了共轭对称性。后来我在预处理阶段加了一阶差分去趋势再配合平滑滤波频谱立刻变得规整了。可见“共轭对称”还可以当异常检测的判据用。7.3 与希尔伯特变换的关联共轭对称性的一个延伸是解析信号。一个实信号(x[n])的解析信号(z[n]x[n]j\hat{x}[n])其频谱只保留正频率部分正频率幅度加倍负频率部分为零。这个操作的极点是利用了频谱的共轭对称因为原实信号的负频率部分可以通过正频率共轭推出来所以丢掉负频率不会损失信息反而能去除镜像频率方便后续的包络提取和瞬时频率计算。在工程中我经常用Matlab的hilbert()函数提取窄带信号的包络。这个函数的内部原理就是把FFT后的负半边谱置零再做IFFT。理解了共轭对称你就明白为什么它能用“砍一半频谱”的方式得到包络了。8. 傅里叶变换与相位一组容易“翻车”的操作细节把“傅里叶变换相位”作为关键词提出来说明相位问题是大家实际使用中的高频痛点。我这里集中讲几个最常踩的坑以及对应的处理办法。8.1 零点附近的相位跳动计算一个实偶信号的相位谱时理论上相位应该恒为0但实际用angle()算出来在频谱过零点附近会出现剧烈的相位跳变。原因很简单当(|X(e^{j\omega})|)接近0时实部和虚部的小数值噪声主导了整个比值arctan的结果就变成了噪声。这种情况在频谱零点处尤其明显。处理办法有三个一是画相位谱时把幅度小于某个阈值比如最大幅度的千分之一的频点置为不显示或者置为0二是使用相位解缠绕并配合幅度加权三是用群延迟来替代相位做系统分析群延迟的定义是相位对频率的负导数它对幅度极小值点的敏感度低一些。8.2 开方运算带来的相位二义性傅里叶变换在某些应用里需要做“频谱开方”比如设计匹配滤波器、计算倒谱。问题在于复数开方在数学上是有二义性的结果可以选择两个相差(\pi)的相位。不加处理的话IFFT会得到错误的时域信号。我在做最小相位滤波器恢复时遇到过一次这样的问题从幅度谱出发想恢复最小相位冲激响应。如果我直接在频域里对复频谱做log再IFFT求倒谱然后做窗函数截断这一系列操作中log运算会把相位信息转换为一种连续的形式但如果原始相位有跳变log后就会产生伪迹。解决办法是先对相位做解缠绕再参与后续运算或者在频域定义域上保证相位连续。8.3 频谱插值与相位的关系做FFT时经常要补零来“提高频谱分辨率”。注意补零本身不会增加任何新的信息它只能让频谱图更平滑看起来更“细腻”。补零后频谱曲线在原有的频率采样点处的值不变但两个采样点之间的值是通过隐含的插值计算出来的。由于相位是频率的连续函数补零后画出来的相位谱曲线看起来更连续于是很多人误以为补零能“把相位测准”。实际上真正的相位值取决于信号的物理特性补零改不了它。要想获得真实的相位测量关键是确保时间同步和窗函数选择正确。对周期信号做FFT时建议信号长度尽量包含整数个信号周期否则频谱泄漏会造成幅度和相位的双偏差。个中原因还是出在矩形窗截断对应的频域卷积这个基本结论上。8.4 相位解缠绕的操作要诀MATLAB的unwrap()用起来很简单但它有个默认的阈值——当相邻相位跳变超过(\pi)时才进行修正。如果相位跳变恰好接近(\pi)unwrap可能会误判把本不该解的跳变也解了或者该解的跳变漏掉。这个时候可以先用interp1把相位网格加密再unwrap然后重采样回来效果会好不少。还有一种更稳妥的做法用复指数的比值来计算相位变化量即[ \Delta\theta[n] \text{angle}\left(e^{j\theta[n]} / e^{j\theta[n-1]}\right) ]这样计算出来的相位增量天然落在((-\pi,\pi])区间内再做累积求和就不容易出错。9. 我自己做证明题时的一套固定流程学完这些性质证明题到底该怎么做我总结了一个流程基本适用于教科书里绝大多数“证明某某性质”的题目。第一步先写定义式。不管是证明左边还是右边总得有一个起点。定义式是最保险的起点因为它只需要你把变换式抄一遍就能写出来。第二步寻找可以交换运算顺序的地方。傅里叶变换的证明里最常用的操作就是交换求和与积分、交换求和与求和。理论上这需要函数满足一定的收敛条件但考试和习题里给出的序列通常都满足绝对可和所以放心大胆地用。第三步想尽一切办法把内层表达式凑成一个已知变换对。比如证明卷积定理时内层求和正好用时移性质证明相乘性质时内层求和正好是另一个信号的DTFT。如果你发现凑不出来多半是因为少用了一个时移或者频移的变体。第四步化简到最后一步如果得到了目标表达式就收尾。如果多了或少了系数先检查(1/2\pi)的系数有没有漏掉。DTFT和IDTFT定义里的系数是最容易出错的地方好在不同教材的定义基本统一逆变换前有一个(1/2\pi)。第五步也是我最想强调的就是验证边界条件。证明完一个公式后代一个简单信号进去验证一下。比如证明时移性质后取(x[n]1)看看(x[n-n_0]1)时频谱是不是还是原来的周期冲激串。这种验证做多了对公式的记忆会特别牢固。10. 从结论到系统这些性质怎么支撑线性时不变系统分析系统分析的终极目标是给定一个输入信号和一个系统通常用冲激响应(h[n])或频率响应(H(e^{j\omega}))来描述求出输出信号。有了卷积定理这个问题就变成[ y[n] x[n] * h[n] \quad \leftrightarrow \quad Y(e^{j\omega}) X(e^{j\omega}) H(e^{j\omega}) ]频域相乘比时域卷积好算得多而且物理意义清晰系统的幅频响应(|H(e^{j\omega})|)决定了输入信号各频率分量的放大或衰减程度相频响应(\angle H(e^{j\omega}))决定了各频率分量的时延。这个关系让人直观地理解了“滤波”的本质。用这个关系分析系统时需要注意几个边界问题。一个是系统稳定性的概念通过检查(H(e^{j\omega}))是否对所有(\omega)有界可以判断系统的BIBO稳定性。这一点跟z变换的收敛域检查是等价的但用DTFT检查更直接——因为它是沿着单位圆取值的如果单位圆在收敛域内说明系统稳定。第二个是对实际的物理信号来说输入频谱往往不是绝对可和的因为很多信号的频谱里带有冲激成分。此时卷积定理两边都包含冲激项的乘积和卷积需要特别留意混叠项。我之前写过一个求两个余弦信号乘积频谱的程序直接用相乘性质时忘了处理冲激卷积产生的副本结果画出来的频谱多了好几根孤立的谱线调试了半天才醒悟过来。第三个是一个经常被忽视的结论线性时不变系统的输出频谱等于输入频谱乘以系统频率响应这个结论隐含了系统初始状态为零的前提。如果你要分析的系统有非零初始状态比如电容初始电压不为零那么时域卷积的表达式就不完整必须在系统方程的差分方程里补充初始条件对应的项。很多刚学Z变换的同学在这里踩坑其实在DTFT的框架下也是一样的道理。从更加工程化的角度看这些性质组合在一起构成了数字信号处理的基本工作流。设计滤波器时先用理想滤波器频率响应做IDTFT求出无限长冲激响应再用窗函数截断并评估泄漏实现快速卷积时用FFT做循环卷积再修正为线性卷积分析调制系统时用频移性质和相乘性质理解频谱搬移。整个过程环环相扣每一条都是后面一步的基石。我个人的体会是不要把这些结论当公式背而是当工具熟练使用。背下来的公式过段时间就模糊了但如果你亲手推导过两遍并且在代码里验证过你会非常自然地知道“什么时候该用哪一条性质”。就像我是一个木匠工具箱里的每把锯子我都亲手上过油试过硬度的用起来心里才踏实。最后再分享一个小技巧。当你在做题或者做项目时发现傅里叶变换的结果跟预期不一致先别急着怀疑变换本身。老办法取一个极端简单的情形比如单一冲激、单一边沿或者常数序列把边界条件代进去算一遍。这个习惯帮我找到了很多自己计算里的低级错误也能帮你快速定位到底是公式弄错了还是代码的索引没对齐。