使用Remez交換算法計算minimax最優濾波器。
為有限脈沖響應(FIR)濾波器計算filter-coefficients,該濾波器的傳遞函數使用Remez交換算法将指定頻帶中期望增益和已實作增益之間的最大誤差最小化。
參數:
numtaps:int過濾器中所需的抽頭數。抽頭數是過濾器中的項數,或過濾器順序加一。
bands:array_like包含帶邊的單調序列。所有元素必須為非負且小于fs給出的采樣頻率的一半。
desired:array_like在每個指定頻段中包含所需增益的頻段大小的一半序列。
weight:array_like, 可選參數賦予每個頻段區域的相對權重。重量的長度必須是帶子長度的一半。
Hz:scalar, 可選參數不推薦使用。請改用`fs`。采樣頻率(機關:Hz)。預設值為1。
type:{‘bandpass’, ‘differentiator’, ‘hilbert’}, 可選參數過濾器類型:
‘bandpass’:flat response in bands. This is the default.
‘differentiator’:frequency proportional response in bands.
‘hilbert’filter with odd symmetry, that is, type III(for even order) or type IV (for odd order)
linear phase filters.
maxiter:int, 可選參數算法的最大疊代次數。預設值為25。
grid_density:int, 可選參數網格密度。用于的密集網格remez大小(numtaps + 1) * grid_density。預設值為16。
fs:float, 可選參數信号的采樣頻率。預設值為1。
傳回值:
out:ndarray包含最佳(在極小意義上)濾波器系數的等級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。音頻Electroacoust。,第一卷。 AU-21,第506-525頁,1973年。
例子:
在這些例子中remez用于建立帶通,帶阻,低通和高通濾波器。使用的參數是濾波器階數,具有相應頻率邊界的陣列,所需的衰減值和采樣頻率。使用freqz計算并繪制相應的頻率響應。
>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> def plot_response(fs, w, h, title):
... "Utility function to plot response functions"
... fig = plt.figure()
... ax = fig.add_subplot(111)
... ax.plot(0.5*fs*w/np.pi, 20*np.log10(np.abs(h)))
... ax.set_ylim(-40, 5)
... ax.set_xlim(0, 0.5*fs)
... ax.grid(True)
... ax.set_xlabel('Frequency (Hz)')
... ax.set_ylabel('Gain (dB)')
... ax.set_title(title)
此示例根據小過渡寬度和高濾波器階數顯示了陡峭的低通過渡:
>>> fs = 22050.0 # Sample rate, Hz
>>> cutoff = 8000.0 # Desired cutoff frequency, Hz
>>> trans_width = 100 # Width of transition from pass band to stop band, Hz
>>> numtaps = 400 # Size of the FIR filter.
>>> taps = signal.remez(numtaps, [0, cutoff, cutoff + trans_width, 0.5*fs], [1, 0], Hz=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000)
>>> plot_response(fs, w, h, "Low-pass Filter")
此示例顯示了一個高通濾波器:
>>> fs = 22050.0 # Sample rate, Hz
>>> cutoff = 2000.0 # Desired cutoff frequency, Hz
>>> trans_width = 250 # Width of transition from pass band to stop band, Hz
>>> numtaps = 125 # Size of the FIR filter.
>>> taps = signal.remez(numtaps, [0, cutoff - trans_width, cutoff, 0.5*fs],
... [0, 1], Hz=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000)
>>> plot_response(fs, w, h, "High-pass Filter")
對于以22 kHz采樣的信号,使用Remez算法可計算出通帶為2-5 kHz的帶通濾波器。過渡寬度為260 Hz,濾波器階數為10:
>>> fs = 22000.0 # Sample rate, Hz
>>> band = [2000, 5000] # Desired pass band, Hz
>>> trans_width = 260 # Width of transition from pass band to stop band, Hz
>>> numtaps = 10 # 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], Hz=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000)
>>> plot_response(fs, w, h, "Band-pass Filter")
可以看出,對于該帶通濾波器,低階會導緻較高的紋波和較不陡峭的過渡。阻帶的衰減非常低,通帶的過沖很小。當然,所需的增益可以通過較高的濾波器階數更好地近似。
下一個示例顯示了一個帶阻濾波器。由于濾波器階數較高,是以過渡非常陡峭:
>>> fs = 20000.0 # Sample rate, Hz
>>> band = [6000, 8000] # Desired stop band, Hz
>>> trans_width = 200 # Width of transition from pass band to stop band, 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], Hz=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000)
>>> plot_response(fs, w, h, "Band-stop Filter")
>>> plt.show()