scipy.signal.
czt#
- scipy.signal.czt(x, m=None, w=None, a=1 + 0j, *, axis=-1)[源代码]#
计算 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]Steve Alan Shilling,“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 变换,例如半径小于 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()