scipy.signal.zpk2sos

scipy.signal.zpk2sos(z, p, k, pairing='nearest')[源代码]

从系统的零点、极点和增益返回二阶部分

参数
zarray_like

传递函数的零点。

parray_like

传递函数的极点。

k浮动

系统增益。

pairing{‘NEAREST’,‘KEEP_ODD’},可选

用于将极点和零点对组合成区段的方法。请参阅下面的注释。

退货
sosndarray

具有形状的二阶过滤系数数组 (n_sections, 6) 。看见 sosfilt 用于SOS型过滤格式规范。

参见

sosfilt

注意事项

用于将ZPK转换为SOS格式的算法旨在最小化由于数值精度问题引起的误差。配对算法试图最小化每个双二次段的峰值增益。这是通过将极点与最近的零配对来实现的,从最接近单位圆的极点开始。

算法

当前的算法是专门为与数字滤波器一起使用而设计的。(模拟滤波器的输出系数不正确。)

中的步骤 pairing='nearest'pairing='keep_odd' 算法大多是共享的。这个 nearest 算法试图最小化峰值增益,而 'keep_odd' 在奇数阶系统应保留一段为一阶的约束下最小化峰值增益。算法的步骤和如下所示:

作为预处理步骤,根据需要向原点添加极点或零点,以获得用于配对的相同数量的极点和零点。如果 pairing == 'nearest' 如果有奇数个极点,在原点加一个额外的极点和一个零。

然后重复以下步骤,直到不再剩下极点或零点:

  1. 走(下一个剩余的)最接近单位圆的(复数或实数)杆子,开始新的过滤版块。

  2. 如果极点是真实的,并且没有其他真正的极点 1, 将最接近的实数零添加到该区段,并将其保留为一阶区段。请注意,在此步骤之后,保证为后续的配对迭代留下偶数个实极点、复极点、实零点和复零点。

  3. 其他:

    1. 如果极点是复数,并且零点是唯一剩余的实零点 ,然后将杆子与 下一个*最近的零(保证是复数)。这对于确保最终创建一阶部分(从而保持奇数顺序)将有真正的零剩余是必要的。

    2. 否则,将极点与最接近的剩余零(复数或实数)配对。

    3. 继续完成二阶部分,方法是将另一个极点和零添加到电流极点,并在该部分中添加零:

      1. 如果电流极点和零点都是复数,则将它们的共轭值相加。

      2. 否则,如果极点是复数,而零点是实数,则将共轭极点和下一个最接近的实数零相加。

      3. 否则,如果极点是实数,而零是复数,则将共轭零和最接近这些零的实极相加。

      4. 否则(我们必须有一个实极和实零)添加离单位圆最近的下一个实极,然后添加离该极最近的实零。

1

参数的特定奇数阶输入才能满足此条件 pairing == 'keep_odd' 方法。

0.16.0 新版功能.

示例

针对通带拐角频率为10 0 0 Hz、采样率为80 0 0 Hz的系统,设计了6阶低通椭圆数字过滤。通带内的纹波不应超过0.087 dB,阻带内的衰减应至少为90 dB。

在以下对 signal.ellip ,我们可以利用 output='sos' ,但对于本例,我们将使用 output='zpk' ,然后使用转换为SOS格式 zpk2sos

>>> from scipy import signal
>>> 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.0014154 ,  0.00248707,  0.0014154 ],
       [ 1.        ,  0.72965193,  1.        ],
       [ 1.        ,  0.17594966,  1.        ]])

系数的对称性是因为所有的零都在单位圆上。

各部分的分母系数:

>>> sos[:, 3:]
array([[ 1.        , -1.32543251,  0.46989499],
       [ 1.        , -1.26117915,  0.6262586 ],
       [ 1.        , -1.25707217,  0.86199667]])

下一个示例显示了 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]])

原点的额外极点和零点在同一部分。第一节实际上是一级节。