scipy.signal.

zpk2sos#

scipy.signal.zpk2sos(z, p, k, pairing=None, *, analog=False)[原始碼]#

從系統的零點、極點和增益返回二階sections

參數:
zarray_like

傳遞函數的零點。

parray_like

傳遞函數的極點。

kfloat

系統增益。

pairing{None, ‘nearest’, ‘keep_odd’, ‘minimal’}, 選項性

用於將極點和零點對組合成sections的方法。如果 analog 為 False 且 pairing 為 None,則 pairing 設定為 ‘nearest’;如果 analog 為 True,則 pairing 必須為 ‘minimal’,如果為 None,則設定為該值。

analogbool, 選項性

如果為 True,系統為類比系統,否則為離散系統。

在版本 1.8.0 中新增。

返回:
sosndarray

二階濾波器係數陣列,形狀為 (n_sections, 6)。 有關 SOS 濾波器格式規範,請參閱 sosfilt

另請參閱

sosfilt

註解

用於將 ZPK 轉換為 SOS 格式的演算法旨在最大限度地減少由於數值精度問題造成的誤差。配對演算法嘗試最小化每個雙二次 section 的峰值增益。 這是透過將極點與最接近的零點配對來完成的,從最接近單位圓的離散時間系統極點開始,以及最接近連續時間系統虛軸的極點開始。

pairing='minimal' 的輸出可能不適用於 sosfilt,而 analog=True 的輸出將永遠不適用於 sosfilt

演算法

pairing='nearest'pairing='keep_odd'pairing='minimal' 演算法中的步驟大多是共用的。'nearest' 演算法嘗試最小化峰值增益,而 'keep_odd' 在奇數階系統應將一個 section 保留為一階的約束下最小化峰值增益。'minimal' 類似於 'keep_odd',但不引入額外的極點或零點

演算法步驟如下

作為 pairing='nearest'pairing='keep_odd' 的預處理步驟,根據需要向原點添加極點或零點,以獲得相同數量的極點和零點以進行配對。 如果 pairing == 'nearest' 且極點數量為奇數,則在原點添加一個額外的極點和一個零點。

然後迭代以下步驟,直到沒有剩餘的極點或零點

  1. 取 (下一個剩餘的) 最靠近單位圓 (或對於 analog=True 而言為虛軸) 的極點 (複數或實數) 以開始新的濾波器 section。

  2. 如果極點是實數且沒有其他剩餘的實數極點 [1],則將最接近的實數零點添加到 section 並將其保留為一階 section。 請注意,在此步驟之後,我們保證剩餘偶數個實數極點、複數極點、實數零點和複數零點,以進行後續的配對迭代。

  3. 否則

    1. 如果極點是複數且零點是唯一剩餘的實數零點*,則將極點與下一個最接近的零點 (保證為複數) 配對。 這是必要的,以確保將有一個實數零點剩餘,最終建立一階 section (從而保持奇數階)。

    2. 否則將極點與最接近的剩餘零點 (複數或實數) 配對。

    3. 透過在 section 中將另一個極點和零點添加到目前的極點和零點,繼續完成二階 section

      1. 如果目前的極點和零點都是複數,則添加它們的共軛複數。

      2. 否則,如果極點是複數且零點是實數,則添加共軛複數極點和下一個最接近的實數零點。

      3. 否則,如果極點是實數且零點是複數,則添加共軛複數零點和最接近這些零點的實數極點。

      4. 否則 (我們一定有一個實數極點和實數零點),添加下一個最接近單位圓的實數極點,然後添加最接近該極點的實數零點。

在版本 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)

sections 的分子係數

>>> sos[:, :3]
array([[0.0014152 , 0.00248677, 0.0014152 ],
       [1.        , 0.72976874, 1.        ],
       [1.        , 0.17607852, 1.        ]])

係數中的對稱性是因為所有零點都在單位圓上。

sections 的分母係數

>>> 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]])

第一個 section 的零點為 {-0.5-0.05j, -0.5+0.5j},極點為 {0, 0.75},第二個 section 的零點為 {-1, 0},極點為 {0.8+0.1j, 0.8-0.1j}。 請注意,原點處的額外極點和零點已分配給不同的 sections。

使用 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]])

原點處的額外極點和零點在同一個 section 中。 第一個 section 實際上是一個一階 section。

使用 pairing='minimal',一階 section 沒有原點處的額外極點和零點

>>> signal.zpk2sos(z1, p1, 1, pairing='minimal')
array([[ 0.  ,  1.  ,  1.  ,  0.  ,  1.  , -0.75],
       [ 1.  ,  1.  ,  0.5 ,  1.  , -1.6 ,  0.65]])