scipy.signal.

remez#

scipy.signal.remez(numtaps, bands, desired, *, weight=None, type='bandpass', maxiter=25, grid_density=16, fs=None)[source]#

使用 Remez 交換演算法計算極小化極大值最佳濾波器。

計算有限脈衝響應 (FIR) 濾波器的濾波器係數,該濾波器的傳遞函數在使用 Remez 交換演算法的指定頻帶中,將期望增益和實現增益之間的最大誤差最小化。

參數:
numtapsint

濾波器中所需的抽頭數量。抽頭數量是濾波器中的項數,或濾波器階數加一。

bandsarray_like

包含頻帶邊緣的單調序列。所有元素必須是非負的,且小於取樣頻率的一半,如 fs 所給定。

desiredarray_like

一個長度為 bands 一半的序列,包含每個指定頻帶中所需的增益。

weightarray_like, optional

給予每個頻帶區域的相對權重。weight 的長度必須是 bands 長度的一半。

type{‘bandpass’, ‘differentiator’, ‘hilbert’}, optional

濾波器類型

  • ‘bandpass’ : 頻帶中的平坦響應。這是預設值。

  • ‘differentiator’ : 頻帶中與頻率成比例的響應。

  • ‘hilbert’具有奇數對稱性的濾波器,即 III 型

    (對於偶數階) 或 IV 型 (對於奇數階) 線性相位濾波器。

maxiterint, optional

演算法的最大迭代次數。預設值為 25。

grid_densityint, optional

網格密度。在 remez 中使用的密集網格大小為 (numtaps + 1) * grid_density。預設值為 16。

fsfloat, optional

訊號的取樣頻率。預設值為 1。

回傳值:
outndarray

一個 rank-1 陣列,包含最佳(以極小化極大值意義而言)濾波器的係數。

參考文獻

[1]

J. H. McClellan 和 T. W. Parks,“設計最佳 FIR 線性相位數位濾波器的統一方法”,IEEE Trans. 電路理論,卷。CT-20,第 697-701 頁,1973 年。

[2]

J. H. McClellan、T. W. Parks 和 L. R. Rabiner,“用於設計最佳 FIR 線性相位數位濾波器的電腦程式”,IEEE Trans. 音頻聲學電子學,卷。AU-21,第 506-525 頁,1973 年。

範例

在這些範例中,remez 用於設計低通、高通、帶通和帶阻濾波器。定義每個濾波器的參數是濾波器階數、頻帶邊界、邊界的過渡寬度、每個頻帶中所需的增益以及取樣頻率。

在所有範例中,我們將使用 22050 Hz 的取樣頻率。在每個範例中,每個頻帶中所需的增益為 0(對於阻帶)或 1(對於通帶)。

freqz 用於計算每個濾波器的頻率響應,而下面定義的實用函數 plot_response 用於繪製響應。

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> fs = 22050   # Sample rate, Hz
>>> def plot_response(w, h, title):
...     "Utility function to plot response functions"
...     fig = plt.figure()
...     ax = fig.add_subplot(111)
...     ax.plot(w, 20*np.log10(np.abs(h)))
...     ax.set_ylim(-40, 5)
...     ax.grid(True)
...     ax.set_xlabel('Frequency (Hz)')
...     ax.set_ylabel('Gain (dB)')
...     ax.set_title(title)

第一個範例是低通濾波器,截止頻率為 8 kHz。濾波器長度為 325,從通帶到阻帶的過渡寬度為 100 Hz。

>>> cutoff = 8000.0    # Desired cutoff frequency, Hz
>>> trans_width = 100  # Width of transition from pass to stop, Hz
>>> numtaps = 325      # Size of the FIR filter.
>>> taps = signal.remez(numtaps, [0, cutoff, cutoff + trans_width, 0.5*fs],
...                     [1, 0], fs=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
>>> plot_response(w, h, "Low-pass Filter")
>>> plt.show()
../../_images/scipy-signal-remez-1_00_00.png

此範例顯示高通濾波器

>>> cutoff = 2000.0    # Desired cutoff frequency, Hz
>>> trans_width = 250  # Width of transition from pass to stop, Hz
>>> numtaps = 125      # Size of the FIR filter.
>>> taps = signal.remez(numtaps, [0, cutoff - trans_width, cutoff, 0.5*fs],
...                     [0, 1], fs=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
>>> plot_response(w, h, "High-pass Filter")
>>> plt.show()
../../_images/scipy-signal-remez-1_01_00.png

此範例顯示帶通濾波器,其通帶從 2 kHz 到 5 kHz。過渡寬度為 260 Hz,濾波器長度為 63,小於其他範例中的長度

>>> band = [2000, 5000]  # Desired pass band, Hz
>>> trans_width = 260    # Width of transition from pass to stop, Hz
>>> numtaps = 63         # Size of the FIR filter.
>>> edges = [0, band[0] - trans_width, band[0], band[1],
...          band[1] + trans_width, 0.5*fs]
>>> taps = signal.remez(numtaps, edges, [0, 1, 0], fs=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
>>> plot_response(w, h, "Band-pass Filter")
>>> plt.show()
../../_images/scipy-signal-remez-1_02_00.png

低階數導致更高的漣波和較不陡峭的過渡。

下一個範例顯示帶阻濾波器。

>>> band = [6000, 8000]  # Desired stop band, Hz
>>> trans_width = 200    # Width of transition from pass to stop, Hz
>>> numtaps = 175        # Size of the FIR filter.
>>> edges = [0, band[0] - trans_width, band[0], band[1],
...          band[1] + trans_width, 0.5*fs]
>>> taps = signal.remez(numtaps, edges, [1, 0, 1], fs=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
>>> plot_response(w, h, "Band-stop Filter")
>>> plt.show()
../../_images/scipy-signal-remez-1_03_00.png