scipy.signal.
czt#
- scipy.signal.czt(x, m=None, w=None, a=1 + 0j, *, axis=-1)[source]#
计算 Z 平面中沿螺旋方向的频率响应。
- 参数:
- xarray
要转换的信号。
- mint, 可选
期望的输出点数。默认值为输入数据的长度。
- wcomplex, 可选
每一步中点数之间的比率。必须精确,否则累积错误会降低输出序列尾部。
- acomplex, 可选
复平面的起始点。默认为 1+0j。
- axisint, 可选
使用该轴计算 FFT。如果未给定此参数,则将使用最后一个轴。
- 返回:
- outndarray
一个与x相同的维度数组,但转换轴的长度设置为m。
注释
选择默认值,以便
signal.czt(x)
等于fft.fft(x)
且,如果m > len(x)
,则signal.czt(x, m)
等于fft.fft(x, m)
。如果需要重复变换,请使用
CZT
构造一个专门的变换函数,该函数可以在不重新计算常量的情况下重复使用。一个示例应用程序在系统识别中,重复评估系统 z 变换的小片段,在预计极点存在的位置附近,以细化对极点真实位置的估计。 [1]
参考文献
[1]史蒂夫·艾伦·希林格, “对 chirp z 变换及其应用的研究”,第 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 变换进行采样,例如半径小于单位圆的圆
>>> 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()