zpk2sos#
- scipy.signal.zpk2sos(z, p, k, pairing=None, *, analog=False)[源代码]#
从系统的零点、极点和增益返回二阶节
- 参数:
- zarray_like
传递函数的零点。
- parray_like
传递函数的极点。
- kfloat
系统增益。
- pairing{None, ‘nearest’, ‘keep_odd’, ‘minimal’}, 可选
用于将极点和零点配对成节的方法。如果 analog 为 False 且 pairing 为 None,则 pairing 设置为 ‘nearest’;如果 analog 为 True,则 pairing 必须为 ‘minimal’,如果为 None,则将其设置为 ‘minimal’。
- analogbool, 可选
如果为 True,则系统为模拟系统,否则为离散系统。
在 1.8.0 版本中添加。
- 返回:
- sosndarray
二阶滤波器系数数组,形状为
(n_sections, 6)
。有关 SOS 滤波器格式规范,请参阅sosfilt
。
另请参阅
注释
用于将 ZPK 转换为 SOS 格式的算法旨在最大限度地减少由于数值精度问题引起的误差。配对算法尝试最小化每个双二次节的峰值增益。这是通过将极点与最近的零点配对来实现的,首先是离散时间系统中最接近单位圆的极点,以及连续时间系统中最接近虚轴的极点。
pairing='minimal'
的输出可能不适用于sosfilt
,并且analog=True
的输出永远不适用于sosfilt
。算法
pairing='nearest'
、pairing='keep_odd'
和pairing='minimal'
算法中的步骤大多是共享的。'nearest'
算法尝试最小化峰值增益,而'keep_odd'
在奇数阶系统应保留一个节作为一阶的约束下最小化峰值增益。'minimal'
与'keep_odd'
类似,但不会引入额外的极点或零点算法步骤如下
作为
pairing='nearest'
和pairing='keep_odd'
的预处理步骤,根据需要向原点添加极点或零点,以获得相同数量的极点和零点进行配对。如果pairing == 'nearest'
并且有奇数个极点,则在原点添加一个额外的极点和一个零点。然后迭代执行以下步骤,直到没有更多的极点或零点为止
取(下一个剩余的)最接近单位圆(或虚轴,对于
analog=True
)的极点(复数或实数)以开始新的滤波器节。如果极点是实数,并且没有其他剩余的实极点 [1],则将最近的实零点添加到该节,并将其保留为一阶节。请注意,在此步骤之后,我们保证将剩余偶数个实极点、复极点、实零点和复零点,用于后续的配对迭代。
否则
如果极点是复数,并且零点是唯一剩余的实零点*,则将极点与下一个最近的零点配对(保证是复数)。这是必要的,以确保将有一个实零点保留,最终创建一个一阶节(从而保持奇数阶)。
否则,将极点与最近的剩余零点(复数或实数)配对。
通过向当前节中的极点和零点添加另一个极点和零点来完成二阶节
如果当前极点和零点都是复数,则添加它们的共轭。
否则,如果极点是复数且零点是实数,则添加共轭极点和下一个最近的实零点。
否则,如果极点是实数且零点是复数,则添加共轭零点和最接近这些零点的实极点。
否则(我们必须有实极点和实零点),添加下一个最接近单位圆的实极点,然后添加最接近该极点的实零点。
在 0.16.0 版本中添加。
示例
为采样率为 8000 Hz 的系统设计一个 6 阶低通椭圆数字滤波器,该滤波器的通带截止频率为 1000 Hz。通带中的纹波不应超过 0.087 dB,并且阻带中的衰减应至少为 90 dB。
在以下对
ellip
的调用中,我们可以使用output='sos'
,但在此示例中,我们将使用output='zpk'
,然后使用zpk2sos
转换为 SOS 格式>>> from scipy import signal >>> import numpy as np >>> z, p, k = signal.ellip(6, 0.087, 90, 1000/(0.5*8000), output='zpk')
现在转换为 SOS 格式。
>>> sos = signal.zpk2sos(z, p, k)
各节分子系数
>>> sos[:, :3] array([[0.0014152 , 0.00248677, 0.0014152 ], [1. , 0.72976874, 1. ], [1. , 0.17607852, 1. ]])
系数的对称性是因为所有零点都在单位圆上。
各节分母的系数
>>> sos[:, 3:] array([[ 1. , -1.32544025, 0.46989976], [ 1. , -1.26118294, 0.62625924], [ 1. , -1.2570723 , 0.8619958 ]])
下一个示例显示了 pairing 选项的效果。我们有一个具有三个极点和三个零点的系统,因此 SOS 数组的形状将为 (2, 6)。这意味着在 SOS 表示中实际上在原点有一个额外的极点和一个额外的零点。
>>> z1 = np.array([-1, -0.5-0.5j, -0.5+0.5j]) >>> p1 = np.array([0.75, 0.8+0.1j, 0.8-0.1j])
使用
pairing='nearest'
(默认值),我们得到>>> signal.zpk2sos(z1, p1, 1) array([[ 1. , 1. , 0.5 , 1. , -0.75, 0. ], [ 1. , 1. , 0. , 1. , -1.6 , 0.65]])
第一节的零点为 {-0.5-0.05j, -0.5+0.5j},极点为 {0, 0.75},第二节的零点为 {-1, 0},极点为 {0.8+0.1j, 0.8-0.1j}。请注意,原点处的额外极点和零点已分配给不同的节。
使用
pairing='keep_odd'
,我们得到>>> signal.zpk2sos(z1, p1, 1, pairing='keep_odd') array([[ 1. , 1. , 0. , 1. , -0.75, 0. ], [ 1. , 1. , 0.5 , 1. , -1.6 , 0.65]])
原点处的额外极点和零点位于同一节中。第一节实际上是一阶节。
使用
pairing='minimal'
,一阶节在原点处没有额外的极点和零点>>> signal.zpk2sos(z1, p1, 1, pairing='minimal') array([[ 0. , 1. , 1. , 0. , 1. , -0.75], [ 1. , 1. , 0.5 , 1. , -1.6 , 0.65]])