scipy.signal.

chirp#

scipy.signal.chirp(t, f0, t1, f1, method='linear', phi=0, vertex_zero=True, *, complex=False)[源代码]#

扫频余弦波形生成器。

在下文中,‘Hz’应被解释为‘每单位周期数’;这里不要求单位是秒。重要的区别是旋转的单位是周期,而不是弧度。同样,t 可以是空间而不是时间的度量。

参数:
tarray_like

评估波形的时间点。

f0float

t=0 时的频率(例如,赫兹)。

t1float

指定 f1 的时间点。

f1float

t1 时刻波形的频率(例如,赫兹)。

method{‘linear’, ‘quadratic’, ‘logarithmic’, ‘hyperbolic’}, 可选

频率扫描的类型。如果未给出,则假定为 linear。有关更多详细信息,请参阅下面的“备注”部分。

phifloat, 可选

相位偏移,单位为度。默认值为 0。

vertex_zerobool, 可选

此参数仅在 method 为 ‘quadratic’ 时使用。它决定了频率图的抛物线顶点是在 t=0 还是 t=t1。

complexbool, 可选

此参数生成一个复值解析信号而不是实值信号。它允许使用复基带(在通信领域)。默认值为 False。

在 1.15.0 版本中新增。

返回值:
yndarray

一个 NumPy 数组,包含在 t 时刻评估的具有指定时变频率的信号。更准确地说,如果 complex 为真,则函数返回 exp(1j*phase + 1j*(pi/180)*phi),否则返回 cos(phase + (pi/180)*phi),其中 phase2*pi*f(t) 从 0 到 t 的积分。瞬时频率 f(t) 定义如下。

另请参见

sweep_poly

备注

参数 method 有四种可能的选项,它们具有(长)标准形式和一些允许的缩写。生成信号的瞬时频率 \(f(t)\) 公式如下:

  1. 参数 method('linear', 'lin', 'li')

    \[f(t) = f_0 + \beta\, t \quad\text{with}\quad \beta = \frac{f_1 - f_0}{t_1}\]

    频率 \(f(t)\) 随时间线性变化,变化率为常数 \(\beta\)

  2. 参数 method('quadratic', 'quad', 'q')

    \[\begin{split}f(t) = \begin{cases} f_0 + \beta\, t^2 & \text{if vertex_zero is True,}\\ f_1 + \beta\, (t_1 - t)^2 & \text{otherwise,} \end{cases} \quad\text{with}\quad \beta = \frac{f_1 - f_0}{t_1^2}\end{split}\]

    频率 f(t) 的图形是经过 \((0, f_0)\)\((t_1, f_1)\) 的抛物线。默认情况下,抛物线的顶点在 \((0, f_0)\) 处。如果 vertex_zeroFalse,则顶点在 \((t_1, f_1)\) 处。要使用更通用的二次函数或任意多项式,请使用函数 scipy.signal.sweep_poly

  3. 参数 method('logarithmic', 'log', 'lo')

    \[f(t) = f_0 \left(\frac{f_1}{f_0}\right)^{t/t_1}\]

    \(f_0\)\(f_1\) 必须是非零且同号的。此信号也称为几何啁啾或指数啁啾。

  4. 参数 method('hyperbolic', 'hyp')

    \[f(t) = \frac{\alpha}{\beta\, t + \gamma} \quad\text{with}\quad \alpha = f_0 f_1 t_1, \ \beta = f_0 - f_1, \ \gamma = f_1 t_1\]

    \(f_0\)\(f_1\) 必须是非零的。

示例

第一个示例绘制了一个在 10 秒内从 6 赫兹到 1 赫兹的线性啁啾。

>>> import numpy as np
>>> from matplotlib.pyplot import tight_layout
>>> from scipy.signal import chirp, square, ShortTimeFFT
>>> from scipy.signal.windows import gaussian
>>> import matplotlib.pyplot as plt
...
>>> N, T = 1000, 0.01  # number of samples and sampling interval for 10 s signal
>>> t = np.arange(N) * T  # timestamps
...
>>> x_lin = chirp(t, f0=6, f1=1, t1=10, method='linear')
...
>>> fg0, ax0 = plt.subplots()
>>> ax0.set_title(r"Linear Chirp from $f(0)=6\,$Hz to $f(10)=1\,$Hz")
>>> ax0.set(xlabel="Time $t$ in Seconds", ylabel=r"Amplitude $x_\text{lin}(t)$")
>>> ax0.plot(t, x_lin)
>>> plt.show()
../../_images/scipy-signal-chirp-1_00_00.png

以下四个图分别显示了参数 method(和 vertex_zero)取不同值时,从 45 赫兹到 5 赫兹的啁啾的短时傅里叶变换。

>>> x_qu0 = chirp(t, f0=45, f1=5, t1=N*T, method='quadratic', vertex_zero=True)
>>> x_qu1 = chirp(t, f0=45, f1=5, t1=N*T, method='quadratic', vertex_zero=False)
>>> x_log = chirp(t, f0=45, f1=5, t1=N*T, method='logarithmic')
>>> x_hyp = chirp(t, f0=45, f1=5, t1=N*T, method='hyperbolic')
...
>>> win = gaussian(50, std=12, sym=True)
>>> SFT = ShortTimeFFT(win, hop=2, fs=1/T, mfft=800, scale_to='magnitude')
>>> ts = ("'quadratic', vertex_zero=True", "'quadratic', vertex_zero=False",
...       "'logarithmic'", "'hyperbolic'")
>>> fg1, ax1s = plt.subplots(2, 2, sharex='all', sharey='all',
...                          figsize=(6, 5),  layout="constrained")
>>> for x_, ax_, t_ in zip([x_qu0, x_qu1, x_log, x_hyp], ax1s.ravel(), ts):
...     aSx = abs(SFT.stft(x_))
...     im_ = ax_.imshow(aSx, origin='lower', aspect='auto', extent=SFT.extent(N),
...                      cmap='plasma')
...     ax_.set_title(t_)
...     if t_ == "'hyperbolic'":
...         fg1.colorbar(im_, ax=ax1s, label='Magnitude $|S_z(t,f)|$')
>>> _ = fg1.supxlabel("Time $t$ in Seconds")  # `_ =` is needed to pass doctests
>>> _ = fg1.supylabel("Frequency $f$ in Hertz")
>>> plt.show()
../../_images/scipy-signal-chirp-1_01_00.png

最后,描绘了一个从 -30 赫兹到 30 赫兹的复值线性啁啾的短时傅里叶变换。

>>> z_lin = chirp(t, f0=-30, f1=30, t1=N*T, method="linear", complex=True)
>>> SFT.fft_mode = 'centered'  # needed to work with complex signals
>>> aSz = abs(SFT.stft(z_lin))
...
>>> fg2, ax2 = plt.subplots()
>>> ax2.set_title(r"Linear Chirp from $-30\,$Hz to $30\,$Hz")
>>> ax2.set(xlabel="Time $t$ in Seconds", ylabel="Frequency $f$ in Hertz")
>>> im2 = ax2.imshow(aSz, origin='lower', aspect='auto',
...                  extent=SFT.extent(N), cmap='viridis')
>>> fg2.colorbar(im2, label='Magnitude $|S_z(t,f)|$')
>>> plt.show()
../../_images/scipy-signal-chirp-1_02_00.png

请注意,负频率仅对复值信号有意义。此外,复指数函数的幅值为一,而实值余弦函数的幅值仅为 1/2。