scipy.signal.

firls#

scipy.signal.firls(numtaps, bands, desired, *, weight=None, fs=None)[原始碼]#

使用最小平方法誤差最小化設計 FIR 濾波器。

計算線性相位有限脈衝響應 (FIR) 濾波器的濾波器係數,該濾波器在最小平方法意義上最逼近由 bandsdesired 描述的期望頻率響應(即,在指定頻帶內加權均方誤差的積分被最小化)。

參數:
numtapsint

FIR 濾波器中的抽頭數。numtaps 必須是奇數。

bandsarray_like

一個單調非遞減序列,包含以 Hz 為單位的頻帶邊緣。所有元素都必須是非負數且小於或等於奈奎斯特頻率 nyq。頻帶指定為頻率對,因此,如果使用一維陣列,則其長度必須為偶數,例如,np.array([0, 1, 2, 3, 4, 5])。或者,頻帶可以指定為 nx2 大小的二維陣列,其中 n 是頻帶數,例如 np.array([[0, 1], [2, 3], [4, 5]])

desiredarray_like

bands 大小相同的序列,包含每個頻帶起點和終點的期望增益。

weightarray_like,選用

在解決最小平方法問題時,給予每個頻帶區域的相對權重。weight 的大小必須是 bands 的一半。

fsfloat,選用

訊號的取樣頻率。bands 中的每個頻率都必須介於 0 和 fs/2(含)之間。預設值為 2。

返回:
coeffsndarray

最佳(在最小平方法意義上)FIR 濾波器的係數。

註解

此實作遵循 [1] 中給出的演算法。如其中所述,最小平方法設計有多個優點

  1. 在最小平方法意義上最佳。

  2. 簡單、非迭代方法。

  3. 一般解可以通過解線性方程組獲得。

  4. 允許使用頻率相關的加權函數。

此函數建構 I 型線性相位 FIR 濾波器,其中包含奇數個 coeffs,對於 \(n < numtaps\) 滿足

\[coeffs(n) = coeffs(numtaps - 1 - n)\]

奇數個係數和濾波器對稱性避免了可能在奈奎斯特和 0 頻率下發生的邊界條件(例如,對於 II 型、III 型或 IV 型變體)。

在版本 0.18 中新增。

參考文獻

[1]

Ivan Selesnick,線性相位 FIR 濾波器的最小平方法設計。OpenStax CNX。2005 年 8 月 9 日。https://eeweb.engineering.nyu.edu/iselesni/EL713/firls/firls.pdf

範例

我們想要建構一個帶通濾波器。請注意,在我們的阻帶和通帶之間的頻率範圍內的行為是未指定的,因此可能會根據我們的濾波器參數而過衝

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> fig, axs = plt.subplots(2)
>>> fs = 10.0  # Hz
>>> desired = (0, 0, 1, 1, 0, 0)
>>> for bi, bands in enumerate(((0, 1, 2, 3, 4, 5), (0, 1, 2, 4, 4.5, 5))):
...     fir_firls = signal.firls(73, bands, desired, fs=fs)
...     fir_remez = signal.remez(73, bands, desired[::2], fs=fs)
...     fir_firwin2 = signal.firwin2(73, bands, desired, fs=fs)
...     hs = list()
...     ax = axs[bi]
...     for fir in (fir_firls, fir_remez, fir_firwin2):
...         freq, response = signal.freqz(fir)
...         hs.append(ax.semilogy(0.5*fs*freq/np.pi, np.abs(response))[0])
...     for band, gains in zip(zip(bands[::2], bands[1::2]),
...                            zip(desired[::2], desired[1::2])):
...         ax.semilogy(band, np.maximum(gains, 1e-7), 'k--', linewidth=2)
...     if bi == 0:
...         ax.legend(hs, ('firls', 'remez', 'firwin2'),
...                   loc='lower center', frameon=False)
...     else:
...         ax.set_xlabel('Frequency (Hz)')
...     ax.grid(True)
...     ax.set(title='Band-pass %d-%d Hz' % bands[2:4], ylabel='Magnitude')
...
>>> fig.tight_layout()
>>> plt.show()
../../_images/scipy-signal-firls-1.png