FIR滤波器相位响应计算中的不连续性问题排查
数字滤波器相位响应计算的不连续性问题
我在嵌入式系统中实现了一款数字滤波器,需要生成幅频和相频响应数据。幅度数据已经通过多种方法搞定,但相位数据的计算卡壳了。
在Octave里,我用freqz_plot(W_hz, H, 0)生成的幅频和相频响应图完全符合预期:
但手动用下面的公式计算相位时:
phase_deg = rad2deg(angle(H));
得到的相位曲线却满是不连续的跳变(横轴为频率Hz,纵轴为相位度):
我搞不懂该用什么数学方法消除这些跳变,复现出freqz生成的平滑曲线。观察到跳变有的是180度,有的是90度,但不知道怎么判断修正的方向和大小,自己生成正确的数据。
问题根源
angle()函数返回的相位范围被限制在**[-π, π](对应-180°到180°),当实际相位随频率变化超出这个区间时,会自动"卷绕"到区间内,导致曲线出现跳变。而Octave的freqz内部会对相位做无卷绕(unwrap)**处理,通过给跳变点的相位加减360°的整数倍,让曲线保持连续。
解决代码
直接用Octave的unwrap()函数处理弧度相位,再转成角度即可:
phase_rad = unwrap(angle(H)); phase_deg = rad2deg(phase_rad);
原理说明
unwrap()会遍历相位序列,检查相邻两个点的相位差:
- 如果差值的绝对值大于π(180°),就给当前相位加上或减去2π(360°),把相位差拉回合理范围,从而消除跳变。
- 你遇到的90°跳变,大概率是采样或计算导致的小幅度卷绕,unwrap同样能处理这类情况,只要跳变的本质是相位超出了
angle()的返回范围。
内容的提问来源于stack exchange,提问作者user23322927
相关产品推荐
相关产品推荐

