scipy.signal.minimum_phase

scipy.signal.minimum_phase(h, method='homomorphic', n_fft=None)[源代码]

将线性相位FIR过滤转换为最小相位

参数
h阵列

线性相位FIR过滤系数。

method{‘希尔伯特’,‘同态’}

要使用的方法:

“同态”(默认)

这种方法 [4] [5] 与抽头数为奇数的滤波器配合使用效果最好,生成的最小相位过滤的幅值响应将近似于原始过滤幅值响应的平方根。

“希尔伯特”

这种方法 [1] 设计成与等波纹滤波器一起使用(例如,从 remez 具有单位增益区或零增益区)。

n_fft集成

用于FFT的点数。应至少比信号长度大几倍(参见注释)。

退货
h_minimum阵列

过滤的最小相位版本,长度 (length(h) + 1) // 2

注意事项

希尔伯特夫妇 [1] 或同态的 [4] [5] 这些方法需要选择快速傅立叶变换的长度来估计过滤的复倒频谱。

在希尔伯特方法的情况下,与理想谱的偏差 epsilon 与阻带零点的数目有关 n_stop 和FFT长度 n_fft AS::

epsilon = 2. * n_stop / n_fft

例如,利用100个阻带零和2048的FFT长度, epsilon = 0.0976 。如果我们保守地假设阻带零的数目比过滤长度小1,我们可以将fft长度取为满足条件的2的下一个幂 epsilon=0.01 AS::

n_fft = 2 ** int(np.ceil(np.log2(2 * (len(h) - 1) / 0.01)))

这给出了希尔伯特方法和同态方法的合理结果,并给出了在以下情况下使用的值 n_fft=None

存在用于创建最小相位滤波器的替代实现,包括零反转 [2] 和谱因式分解 [3] [4] 。有关详细信息,请参阅:

参考文献

1(1,2)

N.Damera-Venkata和B.L.Evans,“实数和复数最小相位数字FIR滤波器的优化设计”,“声学、语音和信号处理”,1999。论文集,1999年IEEE国际会议,凤凰城,亚利桑那州,1999年,第1145-1148页,第3卷。 DOI:10.1109/ICASSP.1999.756179

2

陈锡文和T.W.Parks,“基于直接因式分解的最优最小相位FIR滤波器的设计”,“信号处理”,第一卷。1986年6月,第10期,第4期,第369-383页。

3

萨拉马基,“有限脉冲响应过滤设计”,“数字信号处理手册”,第4章,纽约:威利国际科学出版社,1993年。

4(1,2,3)

林俊生,信号处理高级专题。恩格尔伍德·克里夫斯,新泽西州:普伦蒂斯·霍尔出版社,1988。

5(1,2)

A.V.Oppenheim,R.W.Schafer和J.R.Buck,“离散时间信号处理”,第2版。马鞍河上游,新泽西州:Prentice Hall,1999。

示例

创建最佳线性相位过滤,然后将其转换为最小相位:

>>> from scipy.signal import remez, minimum_phase, freqz, group_delay
>>> import matplotlib.pyplot as plt
>>> freq = [0, 0.2, 0.3, 1.0]
>>> desired = [1, 0]
>>> h_linear = remez(151, freq, desired, Hz=2.)

将其转换为最小相位:

>>> h_min_hom = minimum_phase(h_linear, method='homomorphic')
>>> h_min_hil = minimum_phase(h_linear, method='hilbert')

比较这三个筛选器:

>>> fig, axs = plt.subplots(4, figsize=(4, 8))
>>> for h, style, color in zip((h_linear, h_min_hom, h_min_hil),
...                            ('-', '-', '--'), ('k', 'r', 'c')):
...     w, H = freqz(h)
...     w, gd = group_delay((h, 1))
...     w /= np.pi
...     axs[0].plot(h, color=color, linestyle=style)
...     axs[1].plot(w, np.abs(H), color=color, linestyle=style)
...     axs[2].plot(w, 20 * np.log10(np.abs(H)), color=color, linestyle=style)
...     axs[3].plot(w, gd, color=color, linestyle=style)
>>> for ax in axs:
...     ax.grid(True, color='0.5')
...     ax.fill_between(freq[1:3], *ax.get_ylim(), color='#ffeeaa', zorder=1)
>>> axs[0].set(xlim=[0, len(h_linear) - 1], ylabel='Amplitude', xlabel='Samples')
>>> axs[1].legend(['Linear', 'Min-Hom', 'Min-Hil'], title='Phase')
>>> for ax, ylim in zip(axs[1:], ([0, 1.1], [-150, 10], [-60, 60])):
...     ax.set(xlim=[0, 1], ylim=ylim, xlabel='Frequency')
>>> axs[1].set(ylabel='Magnitude')
>>> axs[2].set(ylabel='Magnitude (dB)')
>>> axs[3].set(ylabel='Group delay')
>>> plt.tight_layout()
../../_images/scipy-signal-minimum_phase-1.png