使用 scipy.signal.butter 设计带通时,SOS 矩阵的顺序与给定参数不对应

信息处理 过滤器设计 Python 带通 巴特沃思
2022-01-27 20:44:32

我不明白为什么这个scipy操作:

from scipy import signal as sg
import numpy as np

fs = 48000
order = 4

# create bandpass from 100Hz to 200Hz:
sos_test = sg.butter(N=order, 
                     Wn=np.array([100, 200]) / (fs / 2),
                     btype='bandpass', 
                     analog=False, 
                     output='sos')

print(f'sanity check sos-matrix of order {order}:\n{sos_test}')

产生:

sanity check sos-matrix of order 4:
[[ 1.80397952e-09  3.60795904e-09  1.80397952e-09  1.00000000e+00
  -1.98583686e+00  9.86289427e-01]
 [ 1.00000000e+00  2.00000000e+00  1.00000000e+00  1.00000000e+00
  -1.98941516e+00  9.89671541e-01]
 [ 1.00000000e+00 -2.00000000e+00  1.00000000e+00  1.00000000e+00
  -1.99279291e+00  9.93445454e-01]
 [ 1.00000000e+00 -2.00000000e+00  1.00000000e+00  1.00000000e+00
  -1.99638455e+00  9.96563613e-01]]

SOS - “二阶部分”,意味着每个 6 个系数的数组的阶数为 2。看着print告诉我第一个数组是 2 阶,而其余的是 1 阶,这意味着我总共有 5 个阶。sos-matrix 不应该包含其订单大小的一半吗?我希望:

[[b10 b11 b12 a10 a11 a12]    # 2nd order
 [b20 b21 b22 a20 a21 a22]]   # 2nd order

对于 4 阶的 sos 矩阵。

2个回答

你的期望是合理的。然而,order设计例程中的定义令人困惑。在 Matlab/Octave 中也是如此。对于低通或高通滤波器,order确实是滤波器阶数。但是,对于带通或带阻滤波器,得到的滤波器阶数是 的两倍order

这样做的原因是order指定用于设计带通或带阻滤波器的(低通)原型滤波器的阶数。从原型低通滤波器到所需带通或带阻滤波器的转换使滤波器阶数加倍。

总之,order仅在低通和高通滤波器的情况下才等于滤波器阶数。对于带通和带阻滤波器,得到的滤波器阶数为2*order

Doc-fix 被取消,请在此处查看新文档