scipy.signal.
czt#
- scipy.signal.czt(x, m=None, w=None, a=1 + 0j, *, axis=-1)[源代码][源代码]#
计算Z平面中围绕螺旋线的频率响应。
- 参数:
- x数组
要转换的信号。
- mint, 可选
所需输出点的数量。默认值为输入数据的长度。
- w复杂,可选
每个步骤中点之间的比率。这必须精确,否则累积误差将降低输出序列的尾部。默认在整个单位圆上等间距分布点。
- a复杂,可选
复平面中的起点。默认值为 1+0j。
- 轴int, 可选
要计算FFT的轴。如果没有给出,则使用最后一个轴。
- 返回:
- 出ndarray
与 x 具有相同维度的数组,但变换轴的长度设置为 m。
注释
默认设置使得
signal.czt(x)
等同于fft.fft(x)
,并且,如果m > len(x)
,那么signal.czt(x, m)
等同于fft.fft(x, m)
。如果需要重复变换,使用
CZT
来构建一个专门的变换函数,该函数可以重复使用而无需重新计算常量。一个应用示例是在系统识别中,反复评估系统z变换的小片段,围绕预期存在极点的区域,以精确定位极点的真实位置。 [1]
参考文献
[1]Steve Alan Shilling, “A study of the chirp z-transform and its applications”, pg 20 (1970) https://krex.k-state.edu/dspace/bitstream/handle/2097/7844/LD2668R41972S43.pdf
示例
生成一个正弦波:
>>> import numpy as np >>> f1, f2, fs = 8, 10, 200 # Hz >>> t = np.linspace(0, 1, fs, endpoint=False) >>> x = np.sin(2*np.pi*t*f2) >>> import matplotlib.pyplot as plt >>> plt.plot(t, x) >>> plt.axis([0, 1, -1.1, 1.1]) >>> plt.show()
它的离散傅里叶变换在单个频率区间内集中了所有能量:
>>> from scipy.fft import rfft, rfftfreq >>> from scipy.signal import czt, czt_points >>> plt.plot(rfftfreq(fs, 1/fs), abs(rfft(x))) >>> plt.margins(0, 0.1) >>> plt.show()
然而,如果正弦波是按对数衰减的:
>>> x = np.exp(-t*f1) * np.sin(2*np.pi*t*f2) >>> plt.plot(t, x) >>> plt.axis([0, 1, -1.1, 1.1]) >>> plt.show()
DFT 将会有频谱泄漏:
>>> plt.plot(rfftfreq(fs, 1/fs), abs(rfft(x))) >>> plt.margins(0, 0.1) >>> plt.show()
虽然DFT总是在单位圆周围采样z变换,但chirp z变换允许我们在任何对数螺旋上采样Z变换,例如半径小于1的圆:
>>> M = fs // 2 # Just positive frequencies, like rfft >>> a = np.exp(-f1/fs) # Starting point of the circle, radius < 1 >>> w = np.exp(-1j*np.pi/M) # "Step size" of circle >>> points = czt_points(M + 1, w, a) # M + 1 to include Nyquist >>> plt.plot(points.real, points.imag, '.') >>> plt.gca().add_patch(plt.Circle((0,0), radius=1, fill=False, alpha=.3)) >>> plt.axis('equal'); plt.axis([-1.05, 1.05, -0.05, 1.05]) >>> plt.show()
使用正确的半径,这可以转换衰减的正弦波(以及其他具有相同衰减率的波)而不会发生频谱泄漏:
>>> z_vals = czt(x, M + 1, w, a) # Include Nyquist for comparison to rfft >>> freqs = np.angle(points)*fs/(2*np.pi) # angle = omega, radius = sigma >>> plt.plot(freqs, abs(z_vals)) >>> plt.margins(0, 0.1) >>> plt.show()