scipy.signal.

firls#

scipy.signal.firls(numtaps, bands, desired, *, weight=None, fs=None)[源代码][源代码]#

使用最小二乘误差最小化的FIR滤波器设计。

计算线性相位有限脉冲响应(FIR)滤波器的滤波器系数,该滤波器在最小二乘意义上对由 bandsdesired 描述的期望频率响应有最佳近似(即,在指定频带内加权均方误差的积分最小化)。

参数:
numtaps整数

FIR 滤波器中的抽头数。numtaps 必须是奇数。

乐队array_like

一个单调非递减的序列,包含以赫兹为单位的频带边缘。所有元素必须为非负且小于或等于由 nyq 给出的奈奎斯特频率。频带以频率对的形式指定,因此,如果使用一维数组,其长度必须是偶数,例如 np.array([0, 1, 2, 3, 4, 5])。或者,频带可以指定为一个 nx2 大小的二维数组,其中 n 是频带的数量,例如 np.array([[0, 1], [2, 3], [4, 5]])

期望的array_like

一个与 bands 大小相同的序列,包含每个频带起始点和结束点所需的增益。

重量类似数组, 可选

在求解最小二乘问题时,给予每个频带区域的相对权重。weight 的大小必须是 bands 的一半。

fsfloat, 可选

信号的采样频率。bands 中的每个频率必须在 0 和 fs/2 之间(包括 0 和 fs/2)。默认值为 2。

返回:
系数ndarray

最优(在最小二乘意义上)FIR滤波器的系数。

注释

此实现遵循 [1] 中给出的算法。如所述,最小二乘设计具有多个优点:

  1. 在最小二乘意义上最优。

  2. 简单,非迭代方法。

  3. 一般解可以通过求解线性方程组获得。

  4. 允许使用频率相关的加权函数。

此函数构造一个I型线性相位FIR滤波器,它包含奇数个 coeffs 满足对于 \(n < numtaps\) 的条件:

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

奇数个系数和滤波器对称性避免了在奈奎斯特频率和0频率处可能出现的边界条件(例如,对于类型II、III或IV变体)。

Added in version 0.18.

参考文献

[1]

Ivan Selesnick, 线性相位FIR滤波器设计通过最小二乘法。OpenStax CNX。2005年8月9日。http://cnx.org/contents/eb1ecb35-03a9-4610-ba87-41cd771c95f2@7

示例

我们想要构建一个带通滤波器。注意,在我们的阻带和通带之间的频率范围内的行为是未指定的,因此可能会根据我们滤波器的参数出现超调:

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