firls#
- scipy.signal.firls(numtaps, bands, desired, *, weight=None, fs=None)[原始碼]#
使用最小平方法誤差最小化設計 FIR 濾波器。
計算線性相位有限脈衝響應 (FIR) 濾波器的濾波器係數,該濾波器在最小平方法意義上最逼近由 bands 和 desired 描述的期望頻率響應(即,在指定頻帶內加權均方誤差的積分被最小化)。
- 參數:
- 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] 中給出的演算法。如其中所述,最小平方法設計有多個優點
在最小平方法意義上最佳。
簡單、非迭代方法。
一般解可以通過解線性方程組獲得。
允許使用頻率相關的加權函數。
此函數建構 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()