SciPy-1-12-中文文档-三十二-

246 阅读33分钟

SciPy 1.12 中文文档(三十二)

原文:docs.scipy.org/doc/scipy-1.12.0/index.html

scipy.signal.StateSpace

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.StateSpace.html#scipy.signal.StateSpace

class scipy.signal.StateSpace(*system, **kwargs)

线性时不变系统的状态空间形式。

表示系统为连续时间的一阶微分方程 (\dot{x} = A x + B u) 或离散时间的差分方程 (x[k+1] = A x[k] + B u[k])。状态空间 系统继承了 ltidlti 类的额外功能,取决于所使用的系统表示形式。

参数:

*系统:参数

状态空间 类可以用 1 个或 4 个参数进行实例化。以下给出了输入参数的数量及其解释:

  • 1: ltidlti 系统:(状态空间传递函数零极点增益
  • 4: array_like: (A, B, C, D)

dt: float, optional

离散时间系统的采样时间 [s]。默认为 None(连续时间)。必须作为关键字参数指定,例如,dt=0.1

另见

传递函数零极点增益ltidlti

ss2zpkss2tfzpk2sos

备注

修改不属于 状态空间 系统表示的属性值(如 零点极点)非常低效且可能导致数值不准确。最好先转换为特定的系统表示。例如,在访问/修改零点、极点或增益之前调用 sys = sys.to_zpk()

示例

>>> from scipy import signal
>>> import numpy as np
>>> a = np.array([[0, 1], [0, 0]])
>>> b = np.array([[0], [1]])
>>> c = np.array([[1, 0]])
>>> d = np.array([[0]]) 
>>> sys = signal.StateSpace(a, b, c, d)
>>> print(sys)
StateSpaceContinuous(
array([[0, 1],
 [0, 0]]),
array([[0],
 [1]]),
array([[1, 0]]),
array([[0]]),
dt: None
) 
>>> sys.to_discrete(0.1)
StateSpaceDiscrete(
array([[1\. , 0.1],
 [0\. , 1\. ]]),
array([[0.005],
 [0.1  ]]),
array([[1, 0]]),
array([[0]]),
dt: 0.1
) 
>>> a = np.array([[1, 0.1], [0, 1]])
>>> b = np.array([[0.005], [0.1]]) 
>>> signal.StateSpace(a, b, c, d, dt=0.1)
StateSpaceDiscrete(
array([[1\. , 0.1],
 [0\. , 1\. ]]),
array([[0.005],
 [0.1  ]]),
array([[1, 0]]),
array([[0]]),
dt: 0.1
) 

属性:

A

StateSpace 系统的状态矩阵。

B

StateSpace 系统的输入矩阵。

C

StateSpace 系统的输出矩阵。

D

StateSpace 系统的传递矩阵。

dt

返回系统的采样时间,对于 lti 系统返回 None

poles

系统的极点。

zeros

系统的零点。

方法

__mul__(other)对另一个系统或标量进行后乘操作。
to_ss()返回当前 StateSpace 系统的副本。
to_tf(**kwargs)将系统表示转换为 TransferFunction
to_zpk(**kwargs)将系统表示转换为 ZerosPolesGain

scipy.signal.TransferFunction

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.TransferFunction.html#scipy.signal.TransferFunction

class scipy.signal.TransferFunction(*system, **kwargs)

传递函数形式的线性时不变系统类。

表示系统为连续时间传递函数 (H(s)=\sum_{i=0}^N b[N-i] s^i / \sum_{j=0}^M a[M-j] s^j) 或离散时间传递函数 (H(z)=\sum_{i=0}^N b[N-i] z^i / \sum_{j=0}^M a[M-j] z^j),其中 (b) 是分子的元素 num,(a) 是分母的元素 den,且 N == len(b) - 1M == len(a) - 1TransferFunction 系统从 ltidlti 类继承附加功能,具体取决于所使用的系统表示形式。

参数:

*系统:参数

TransferFunction 类可以用 1 或 2 个参数实例化。以下是输入参数的数量及其解释:

  • 1:ltidlti 系统:(StateSpaceTransferFunctionZerosPolesGain)
  • 2:array_like:(分子,分母)

dt:float,可选

离散时间系统的采样时间 [s]。默认为 None(连续时间)。必须作为关键字参数指定,例如,dt=0.1

另请参见

ZerosPolesGainStateSpaceltidlti

tf2sstf2zpktf2sos

注意事项

更改不属于TransferFunction系统表示的属性值(如ABCD状态空间矩阵)效率非常低且可能导致数值不准确。最好先转换为特定的系统表示。例如,在访问/更改 A、B、C、D 系统矩阵之前调用sys = sys.to_ss()

如果对于*system传入了(numerator, denominator),则分子和分母的系数应以降幂顺序指定(例如s² + 3s + 5z² + 3z + 5应表示为[1, 3, 5])

示例

构建传递函数(H(s) = \frac{s² + 3s + 3}{s² + 2s + 1}):

>>> from scipy import signal 
>>> num = [1, 3, 3]
>>> den = [1, 2, 1] 
>>> signal.TransferFunction(num, den)
TransferFunctionContinuous(
array([1., 3., 3.]),
array([1., 2., 1.]),
dt: None
) 

构建采样时间为 0.1 秒的传递函数(H(z) = \frac{z² + 3z + 3}{z² + 2z + 1}):

>>> signal.TransferFunction(num, den, dt=0.1)
TransferFunctionDiscrete(
array([1., 3., 3.]),
array([1., 2., 1.]),
dt: 0.1
) 

属性:

den

TransferFunction系统的分母。

dt

返回系统的采样时间,对于lti系统返回None

num

TransferFunction系统的分子。

poles

系统的极点。

zeros

系统的零点。

方法

to_ss()将系统表示转换为StateSpace
to_tf()返回当前TransferFunction系统的副本。
to_zpk()将系统表示转换为ZerosPolesGain

scipy.signal.ZerosPolesGain

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.ZerosPolesGain.html#scipy.signal.ZerosPolesGain

class scipy.signal.ZerosPolesGain(*system, **kwargs)

线性时不变系统类以零点、极点、增益形式表示。

表示系统的连续或离散时间传递函数 (H(s)=k \prod_i (s - z[i]) / \prod_j (s - p[j])),其中 (k) 是增益,(z) 是零点,(p) 是极点ZerosPolesGain 系统从 ltidlti 类继承额外的功能,具体取决于所使用的系统表示。

参数:

*系统参数

ZerosPolesGain 类可以使用 1 个或 3 个参数实例化。以下给出了输入参数的数量及其解释:

dt: float, optional

离散时间系统的采样时间 [s]。默认为 None(连续时间)。必须作为关键字参数指定,例如,dt=0.1

另见

TransferFunctionStateSpaceltidlti

zpk2sszpk2tfzpk2sos

注意事项

更改不属于 ZerosPolesGain 系统表示的属性值(如 A, B, C, D 状态空间矩阵)非常低效,可能导致数值不准确。最好先转换为特定的系统表示。例如,在访问/更改 A、B、C、D 系统矩阵之前调用 sys = sys.to_ss()

示例

构建传递函数 (H(s) = \frac{5(s - 1)(s - 2)}{(s - 3)(s - 4)}):

>>> from scipy import signal 
>>> signal.ZerosPolesGain([1, 2], [3, 4], 5)
ZerosPolesGainContinuous(
array([1, 2]),
array([3, 4]),
5,
dt: None
) 

使用采样时间为 0.1 秒构建传递函数 (H(z) = \frac{5(z - 1)(z - 2)}{(z - 3)(z - 4)}):

>>> signal.ZerosPolesGain([1, 2], [3, 4], 5, dt=0.1)
ZerosPolesGainDiscrete(
array([1, 2]),
array([3, 4]),
5,
dt: 0.1
) 

属性:

dt

返回系统的采样时间,对于 lti 系统返回 None

gain

ZerosPolesGain 系统的增益。

poles

ZerosPolesGain 系统的极点。

zeros

ZerosPolesGain 系统的零点。

方法

to_ss()将系统表示转换为StateSpace
to_tf()将系统表示转换为TransferFunction
to_zpk()返回当前 'ZerosPolesGain' 系统的副本。

scipy.signal.dlsim

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.dlsim.html#scipy.signal.dlsim

scipy.signal.dlsim(system, u, t=None, x0=None)

模拟离散时间线性系统的输出。

参数:

systemarray_like 或dlti实例的元组

描述系统的元组。以下给出了元组中元素的数量和解释:

  • 1:(dlti的实例)
  • 3:(num,den,dt)
  • 4:(zeros,poles,gain,dt)
  • 5:(A,B,C,D,dt)

uarray_like

描述每个时间t处输入的输入数组(假定在给定时间之间进行插值)。如果有多个输入,则二维数组的每列表示一个输入。

tarray_like,可选

定义输入的时间步长。如果给定了t,则它必须与u的长度相同,并且t中的最后一个值确定输出中返回的步数。

x0array_like,可选

状态向量的初始条件(默认为零)。

返回:

toutndarray

输出的时间值,作为一维数组。

youtndarray

系统响应,作为一维数组。

xoutndarray,可选

状态向量的时间演化。仅当输入为StateSpace系统时生成。

参见

lsimdstepdimpulsecont2discrete

示例

一个简单的积分器传递函数,离散时间步长为 1.0,可以实现为:

>>> import numpy as np
>>> from scipy import signal
>>> tf = ([1.0,], [1.0, -1.0], 1.0)
>>> t_in = [0.0, 1.0, 2.0, 3.0]
>>> u = np.asarray([0.0, 0.0, 1.0, 1.0])
>>> t_out, y = signal.dlsim(tf, u, t=t_in)
>>> y.T
array([[ 0.,  0.,  0.,  1.]]) 

scipy.signal.dimpulse

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.dimpulse.html#scipy.signal.dimpulse

scipy.signal.dimpulse(system, x0=None, t=None, n=None)

离散时间系统的冲激响应。

参数:

system tuple of array_like or instance of dlti

描述系统的元组。以下是元组中元素的数量和解释:

  • 1: (instance of dlti)
  • 3: (num, den, dt)
  • 4: (zeros, poles, gain, dt)
  • 5: (A, B, C, D, dt)

x0 array_like, 可选

初始状态向量。默认为零。

t array_like, 可选

时间点。如果未给出,则计算。

n int, 可选

要计算的时间点数量(如果未给出 t)。

返回:

tout ndarray

输出的时间值,作为一维数组。

yout tuple of ndarray

系统的冲激响应。元组的每个元素代表每个输入中的冲激系统的输出。

另请参阅

impulse, dstep, dlsim, cont2discrete

示例

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt 
>>> butter = signal.dlti(*signal.butter(3, 0.5))
>>> t, y = signal.dimpulse(butter, n=25)
>>> plt.step(t, np.squeeze(y))
>>> plt.grid()
>>> plt.xlabel('n [samples]')
>>> plt.ylabel('Amplitude') 

../../_images/scipy-signal-dimpulse-1.png

scipy.signal.dstep

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.dstep.html#scipy.signal.dstep

scipy.signal.dstep(system, x0=None, t=None, n=None)

离散时间系统的阶跃响应。

参数:

systemarray_like 元组

描述系统的元组。以下提供元组中元素的数量及其解释:

  • 1: (实例dlti)
  • 3: (num, den, dt)
  • 4: (zeros, poles, gain, dt)
  • 5: (A, B, C, D, dt)

x0array_like, optional

初始状态向量,默认为零。

tarray_like, optional

时间点。如果未给出,则计算。

nint, optional

计算时间点的数量(如果未给出t)。

返回:

toutndarray

输出时间点,作为 1-D 数组。

youtndarray 元组

系统的阶跃响应。元组的每个元素表示基于每个输入的阶跃响应的系统输出。

另请参见

step, dimpulse, dlsim, cont2discrete

示例

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt 
>>> butter = signal.dlti(*signal.butter(3, 0.5))
>>> t, y = signal.dstep(butter, n=25)
>>> plt.step(t, np.squeeze(y))
>>> plt.grid()
>>> plt.xlabel('n [samples]')
>>> plt.ylabel('Amplitude') 

../../_images/scipy-signal-dstep-1.png

scipy.signal.dfreqresp

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.dfreqresp.html#scipy.signal.dfreqresp

scipy.signal.dfreqresp(system, w=None, n=10000, whole=False)

计算离散时间系统的频率响应。

参数:

systemdlti类的一个实例或描述系统的元组。

以下内容给出元组中的元素数量及其解释:

  • 1 (一个实例dlti的)
  • 2 (分子、分母、采样时间)
  • 3 (零点、极点、增益、采样时间)
  • 4 (A、B、C、D、采样时间)

warray_like, 可选

频率数组(以弧度/样本表示)。将为此数组中的每个值计算幅度和相位数据。如果未给出一个合理的集合将被计算。

nint, 可选

如果未给出w,计算的频率点数。n频率在一个被选择的区间内对数间隔地分布,该区间包括系统的极点和零点的影响。

wholebool, 可选

通常情况下,如果未提供‘w’,则从 0 到奈奎斯特频率 pi 弧度/样本(单位圆的上半部分)计算频率。如果whole为 True,则从 0 到 2*pi 弧度/样本计算。

返回:

w1D ndarray

频率数组[弧度/样本]

H1D ndarray

复数幅值数组

注意事项

如果system传递(num, den),则应在降序指数顺序(例如,z² + 3z + 5表示为[1, 3, 5])中指定分子和分母的系数。

0.18.0 版本中的新内容。

示例

生成传递函数的奈奎斯特图

>>> from scipy import signal
>>> import matplotlib.pyplot as plt 

使用采样时间为 0.05 秒构造传递函数 (H(z) = \frac{1}{z² + 2z + 3}):

>>> sys = signal.TransferFunction([1], [1, 2, 3], dt=0.05) 
>>> w, H = signal.dfreqresp(sys) 
>>> plt.figure()
>>> plt.plot(H.real, H.imag, "b")
>>> plt.plot(H.real, -H.imag, "r")
>>> plt.show() 

../../_images/scipy-signal-dfreqresp-1.png

scipy.signal.dbode

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.dbode.html#scipy.signal.dbode

scipy.signal.dbode(system, w=None, n=100)

计算离散时间系统的波德幅度和相位数据。

参数:

systemLTI 类的实例或描述系统的元组。

以下内容给出元组中的元素数和其解释:

  • 1(dlti的实例)
  • 2(num、den、dt)
  • 3(zeros、poles、gain、dt)
  • 4(A、B、C、D、dt)

warray_like,可选

频率数组(以弧度/样本表示)。将为该数组中的每个值计算幅度和相位数据。如果未提供,将计算一个合理的集合。

nint,可选

如果未提供w,则计算的频率点数。这n个频率在选择的间隔内对数间隔分布,以包括系统的极点和零点的影响。

返回:

w1D ndarray

频率数组 [rad/time_unit]

mag1D ndarray

幅度数组 [dB]

phase1D ndarray

相位数组 [deg]

注:

如果对于system传入(num, den),则分子和分母的系数应按降幂顺序指定(例如,z² + 3z + 5表示为[1, 3, 5])。

从版本 0.18.0 开始新增。

示例

>>> from scipy import signal
>>> import matplotlib.pyplot as plt 

用采样时间为 0.05 秒构造传递函数 (H(z) = \frac{1}{z² + 2z + 3}):

>>> sys = signal.TransferFunction([1], [1, 2, 3], dt=0.05) 

等效:sys.bode()

>>> w, mag, phase = signal.dbode(sys) 
>>> plt.figure()
>>> plt.semilogx(w, mag)    # Bode magnitude plot
>>> plt.figure()
>>> plt.semilogx(w, phase)  # Bode phase plot
>>> plt.show() 

../../_images/scipy-signal-dbode-1_00.png../../_images/scipy-signal-dbode-1_01.png

scipy.signal.tf2zpk

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.tf2zpk.html#scipy.signal.tf2zpk

scipy.signal.tf2zpk(b, a)

从线性滤波器的分子、分母表示返回零点、极点、增益(z, p, k)的表示。

参数:

barray_like

分子多项式系数。

aarray_like

分母多项式系数。

返回:

zndarray

传输函数的零点。

pndarray

传输函数的极点。

kfloat

系统增益。

笔记

如果b的某些值太接近 0,则它们将被移除。在这种情况下,会发出 BadCoefficients 警告。

数组ba被解释为传输函数变量的正向递减幂的系数。因此,输入(b = [b_0, b_1, ..., b_M])和(a =[a_0, a_1, ..., a_N])可以表示形如以下模拟滤波器:

[H(s) = \frac {b_0 s^M + b_1 s^{(M-1)} + \cdots + b_M} {a_0 s^N + a_1 s^{(N-1)} + \cdots + a_N}]

或形如以下离散时间滤波器:

[H(z) = \frac {b_0 z^M + b_1 z^{(M-1)} + \cdots + b_M} {a_0 z^N + a_1 z^{(N-1)} + \cdots + a_N}]

这种“正幂”形式在控制工程中更为常见。如果MN相等(这对所有通过双线性变换生成的滤波器都成立),那么这等同于 DSP 中更受青睐的“负幂”离散时间形式:

[H(z) = \frac {b_0 + b_1 z^{-1} + \cdots + b_M z^{-M}} {a_0 + a_1 z^{-1} + \cdots + a_N z^{-N}}]

尽管对于常见的滤波器是如此,但请记住这在一般情况下并非如此。如果MN不相等,则必须先将离散时间传输函数系数转换为“正幂”形式,然后再找到极点和零点。

示例

找到具有传输函数的零点、极点和增益

[H(s) = \frac{3s²}{s² + 5s + 13}]

>>> from scipy.signal import tf2zpk
>>> tf2zpk([3, 0, 0], [1, 5, 13])
(   array([ 0\.               ,  0\.              ]), 
 array([ -2.5+2.59807621j ,  -2.5-2.59807621j]), 
 3.0) 

scipy.signal.tf2sos

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.tf2sos.html#scipy.signal.tf2sos

scipy.signal.tf2sos(b, a, pairing=None, *, analog=False)

返回传递函数表示的二阶段节

参数:

barray_like

分子多项式系数。

aarray_like

分母多项式系数。

pairing{None, ‘nearest’, ‘keep_odd’, ‘minimal’}, 可选的

用于将极点和零点对成节的方法。有关pairinganalog参数的信息和限制,请参见zpk2sos

analogbool, 可选的

如果为 True,则系统为模拟系统,否则为离散系统。

新版本 1.8.0.

返回:

sosndarray

形状为(n_sections, 6)的二阶滤波器系数数组。有关 SOS 滤波器格式规范,请参见sosfilt

参见

zpk2sos, sosfilt

注意

通常不建议将 TF 格式转换为 SOS 格式,因为这样做通常不会改善数值精度误差。相反,考虑直接在 ZPK 格式中设计滤波器,然后直接转换为 SOS 格式。TF 首先转换为 ZPK 格式,然后将 ZPK 转换为 SOS 格式。

新版本 0.16.0.

示例

使用其多项式表示找到传递函数 H(s)的“sos”(二阶段节)。

[H(s) = \frac{s² - 3.5s - 2}{s⁴ + 3s³ - 15s² - 19s + 30}]

>>> from scipy.signal import tf2sos
>>> tf2sos([1, -3.5, -2], [1, 3, -15, -19, 30], analog=True)
array([[  0\. ,   0\. ,   1\. ,   1\. ,   2\. , -15\. ],
 [  1\. ,  -3.5,  -2\. ,   1\. ,   1\. ,  -2\. ]]) 

scipy.signal.tf2ss

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.tf2ss.html#scipy.signal.tf2ss

scipy.signal.tf2ss(num, den)

将传递函数转换为状态空间表示。

参数:

num, den array_like

表示分子和分母多项式系数的序列,按降幂排序。分母长度至少应与分子相同。

返回:

A, B, C, D ndarray

控制器标准形式的系统状态空间表示。

示例

转换传递函数:

[H(s) = \frac{s² + 3s + 3}{s² + 2s + 1}]

>>> num = [1, 3, 3]
>>> den = [1, 2, 1] 

转换为状态空间表示:

[ \begin{align}\begin{aligned}\begin{split}\dot{\textbf{x}}(t) = \begin{bmatrix} -2 & -1 \ 1 & 0 \end{bmatrix} \textbf{x}(t) + \begin{bmatrix} 1 \ 0 \end{bmatrix} \textbf{u}(t) \\end{split}\\textbf{y}(t) = \begin{bmatrix} 1 & 2 \end{bmatrix} \textbf{x}(t) + \begin{bmatrix} 1 \end{bmatrix} \textbf{u}(t)\end{aligned}\end{align} ]

>>> from scipy.signal import tf2ss
>>> A, B, C, D = tf2ss(num, den)
>>> A
array([[-2., -1.],
 [ 1.,  0.]])
>>> B
array([[ 1.],
 [ 0.]])
>>> C
array([[ 1.,  2.]])
>>> D
array([[ 1.]]) 

scipy.signal.zpk2tf

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.zpk2tf.html#scipy.signal.zpk2tf

scipy.signal.zpk2tf(z, p, k)

从零点和极点返回多项式传递函数表示

参数:

zarray_like

传递函数的零点。

parray_like

传递函数的极点。

kfloat

系统增益。

返回:

bndarray

分子多项式系数。

andarray

分母多项式系数。

示例

使用其‘zpk’(零极点增益)表示法找到传递函数 H(s)的多项式表示。

[H(z) = 5 \frac { (s - 2)(s - 6) } { (s - 1)(s - 8) }]

>>> from scipy.signal import zpk2tf
>>> z   = [2,   6]
>>> p   = [1,   8]
>>> k   = 5
>>> zpk2tf(z, p, k)
(   array([  5., -40.,  60.]), array([ 1., -9.,  8.])) 

scipy.signal.zpk2sos

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.zpk2sos.html#scipy.signal.zpk2sos

scipy.signal.zpk2sos(z, p, k, pairing=None, *, analog=False)

返回系统的零极点和增益的二阶节

参数:

zarray_like

传递函数的零点。

parray_like

传递函数的极点。

kfloat

系统增益。

pairing{None, ‘nearest’, ‘keep_odd’, ‘minimal’},可选

用于将极点和零点对组合成节的方法。如果 analog 是 False 并且 pairing 是 None,则将 pairing 设置为 'nearest';如果 analog 是 True,则 pairing 必须是 'minimal',如果为 None,则设置为该值。

analogbool,可选

如果为 True,则系统为模拟系统,否则为离散系统。

新版本 1.8.0 中新增。

返回:

sosndarray

具有形状 (n_sections, 6) 的二阶滤波器系数数组。有关 SOS 滤波器格式规范,请参见 sosfilt

另请参见

sosfilt

注释

用于将 ZPK 转换为 SOS 格式的算法旨在最小化由数值精度问题引起的误差。配对算法试图最小化每个二阶节的峰值增益。这是通过将最接近单位圆的极点与最接近虚轴的极点配对开始的,适用于离散时间系统和连续时间系统。

pairing='minimal' 输出可能不适用于 sosfilt,而 analog=True 的输出永远不适用于 sosfilt

算法

pairing='nearest'pairing='keep_odd'pairing='minimal' 算法中的步骤大部分是共享的。 'nearest' 算法试图最小化峰值增益,而 'keep_odd' 在保持奇阶系统应保留一个节作为一阶的约束条件下最小化峰值增益。 'minimal' 类似于 'keep_odd',但不引入额外的极点或零点。

算法步骤如下:

作为 pairing='nearest'pairing='keep_odd' 的预处理步骤,根据需要向原点添加极点或零点,以获取相同数量的极点和零点进行配对。如果极点数量为奇数且 pairing == 'nearest',则在原点处添加一个额外的极点和零点。

然后迭代以下步骤,直到不再有极点或零点:

  1. 取最靠近单位圆(或对于 analog=True,虚轴)的(下一个剩余)极点(复数或实数),以开始一个新的滤波器节。

  2. 如果极点是实数且没有其他剩余的实数极点[1],则将最接近的实数零点添加到该部分,并将其保留为一阶部分。请注意,在此步骤之后,我们保证会留下偶数个实数极点、复数极点、实数零点和复数零点,以供后续配对迭代使用。

  3. 否则:

    1. 如果极点是复数且零点是唯一剩余的实数零点*,则将极点与下一个最接近的零点(保证为复数)配对。这是必要的,以确保最终将保留一个实数零点,以创建一个一阶部分(从而保持奇序)。
    2. 否则,将极点与最接近的剩余零点(复数或实数)配对。
    3. 继续通过为当前部分中的当前极点和零点添加另一个极点和零点来完成第二阶段:
      1. 如果当前极点和零点都是复数,则添加它们的共轭。
      2. 否则,如果极点是复数且零点是实数,则添加共轭极点和下一个最接近的实数零点。
      3. 否则,如果极点是实数且零点是复数,则添加共轭零点和最接近这些零点的实数极点。
      4. 否则(我们必须有一个实数极点和实数零点),则添加最接近单位圆的下一个实数极点,然后添加最接近该极点的实数零点。

从版本 0.16.0 开始。

示例

为具有 8000 Hz 采样率的系统设计一个 6 阶低通椭圆数字滤波器,其通带角频率为 1000 Hz。通带中的波动不应超过 0.087 dB,而阻带的衰减应至少为 90 dB。

在接下来的ellip调用中,我们可以使用output='sos',但是对于此示例,我们将使用output='zpk',然后使用zpk2sos转换为 SOS 格式:

>>> from scipy import signal
>>> import numpy as np
>>> z, p, k = signal.ellip(6, 0.087, 90, 1000/(0.5*8000), output='zpk') 

现在转换为 SOS 格式。

>>> sos = signal.zpk2sos(z, p, k) 

各部分分子的系数:

>>> sos[:, :3]
array([[0.0014152 , 0.00248677, 0.0014152 ],
 [1\.        , 0.72976874, 1\.        ],
 [1\.        , 0.17607852, 1\.        ]]) 

系数中的对称性是因为所有零点都在单位圆上。

各部分分母的系数:

>>> sos[:, 3:]
array([[ 1\.        , -1.32544025,  0.46989976],
 [ 1\.        , -1.26118294,  0.62625924],
 [ 1\.        , -1.2570723 ,  0.8619958 ]]) 

下一个示例展示了pairing选项的效果。我们的系统有三个极点和三个零点,因此 SOS 数组的形状为(2, 6)。这意味着在 SOS 表示中,事实上存在额外的极点和原点处的额外零点。

>>> z1 = np.array([-1, -0.5-0.5j, -0.5+0.5j])
>>> p1 = np.array([0.75, 0.8+0.1j, 0.8-0.1j]) 

使用pairing='nearest'(默认),我们得到:

>>> signal.zpk2sos(z1, p1, 1)
array([[ 1\.  ,  1\.  ,  0.5 ,  1\.  , -0.75,  0\.  ],
 [ 1\.  ,  1\.  ,  0\.  ,  1\.  , -1.6 ,  0.65]]) 

第一部分具有零点{-0.5-0.05j,-0.5+0.5j}和极点{0,0.75},第二部分具有零点{-1,0}和极点{0.8+0.1j,0.8-0.1j}。请注意,原点处的额外极点和零点已分配到不同的部分。

使用pairing='keep_odd',我们得到:

>>> signal.zpk2sos(z1, p1, 1, pairing='keep_odd')
array([[ 1\.  ,  1\.  ,  0\.  ,  1\.  , -0.75,  0\.  ],
 [ 1\.  ,  1\.  ,  0.5 ,  1\.  , -1.6 ,  0.65]]) 

原点处的额外极点和零点位于同一部分。事实上,第一部分是一个一阶部分。

使用pairing='minimal',第一阶段不包括原点处的额外极点和零点:

>>> signal.zpk2sos(z1, p1, 1, pairing='minimal')
array([[ 0\.  ,  1\.  ,  1\.  ,  0\.  ,  1\.  , -0.75],
 [ 1\.  ,  1\.  ,  0.5 ,  1\.  , -1.6 ,  0.65]]) 

scipy.signal.zpk2ss

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.zpk2ss.html#scipy.signal.zpk2ss

scipy.signal.zpk2ss(z, p, k)

零极点增益表示转换为状态空间表示

参数:

z, p 序列

零点和极点。

k 浮点数

系统增益。

返回:

A, B, C, D 数组

系统的状态空间表示,处于控制规范形式。

scipy.signal.ss2tf

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.ss2tf.html#scipy.signal.ss2tf

scipy.signal.ss2tf(A, B, C, D, input=0)

从状态空间到传递函数。

A、B、C、D 定义了一个具有p个输入、q个输出和n个状态变量的线性状态空间系统。

参数:

Aarray_like

形状为(n, n)的状态(或系统)矩阵。

Barray_like

形状为(n, p)的输入矩阵。

Carray_like

形状为(q, n)的输出矩阵。

Darray_like

形状为(q, p)的馈送矩阵(或前馈矩阵)。

inputint,可选

对于多输入系统,使用的输入索引。

返回:

num2-D ndarray

结果传递函数的分子。num每行对应系统输出。每行是分子多项式的序列表示。

den1-D ndarray

结果传递函数的分母。den是分母多项式的序列表示。

示例

转换状态空间表示:

[ \begin{align}\begin{aligned}\begin{split}\dot{\textbf{x}}(t) = \begin{bmatrix} -2 & -1 \ 1 & 0 \end{bmatrix} \textbf{x}(t) + \begin{bmatrix} 1 \ 0 \end{bmatrix} \textbf{u}(t) \\end{split}\\textbf{y}(t) = \begin{bmatrix} 1 & 2 \end{bmatrix} \textbf{x}(t) + \begin{bmatrix} 1 \end{bmatrix} \textbf{u}(t)\end{aligned}\end{align} ]

>>> A = [[-2, -1], [1, 0]]
>>> B = [[1], [0]]  # 2-D column vector
>>> C = [[1, 2]]    # 2-D row vector
>>> D = 1 

到传递函数:

[H(s) = \frac{s² + 3s + 3}{s² + 2s + 1}]

>>> from scipy.signal import ss2tf
>>> ss2tf(A, B, C, D)
(array([[1., 3., 3.]]), array([ 1.,  2.,  1.])) 

scipy.signal.ss2zpk

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.ss2zpk.html#scipy.signal.ss2zpk

scipy.signal.ss2zpk(A, B, C, D, input=0)

将状态空间表示转换为零极点增益表示。

A, B, C, D 定义了具有p个输入,q个输出和n个状态变量的线性状态空间系统。

参数:

Aarray_like

形状为(n, n)的状态(或系统)矩阵。

Barray_like

形状为(n, p)的输入矩阵。

Carray_like

形状为(q, n)的输出矩阵。

Darray_like

形状为(q, p)的递送(或前馈)矩阵。

inputint, optional

对于多输入系统,使用的输入索引。

返回:

z, psequence

零点和极点。

kfloat

系统增益。

scipy.signal.sos2zpk

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.sos2zpk.html#scipy.signal.sos2zpk

scipy.signal.sos2zpk(sos)

返回一系列第二阶段的零点、极点和增益

参数:

sosarray_like

第二阶滤波器系数的数组,必须具有形状(n_sections, 6)。参见sosfilt以获取 SOS 滤波器格式规范。

返回:

zndarray

传递函数的零点。

pndarray

传递函数的极点。

kfloat

系统增益。

注意事项

即使某些零点和极点(实际上)为零,返回的零点和极点数量将为n_sections * 2

自版本 0.16.0 新增。

scipy.signal.sos2tf

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.sos2tf.html#scipy.signal.sos2tf

scipy.signal.sos2tf(sos)

从一系列二阶段得到单一传递函数

参数:

sosarray_like

必须具有形状(n_sections, 6)的二阶滤波器系数数组。请参阅sosfilt以获取 SOS 滤波器格式规范。

返回:

bndarray

分子多项式系数。

andarray

分母多项式系数。

注意事项

新版本 0.16.0 中的新增内容。

示例

找到椭圆滤波器的多项式表示,使用其‘sos’(二阶段形式)格式。

>>> from scipy.signal import sos2tf
>>> from scipy import signal
>>> sos = signal.ellip(1, 0.001, 50, 0.1, output='sos')
>>> sos2tf(sos)
(   array([0.91256522, 0.91256522, 0\.        ]),
 array([1\.        , 0.82513043, 0\.        ])) 

scipy.signal.cont2discrete

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.cont2discrete.html#scipy.signal.cont2discrete

scipy.signal.cont2discrete(system, dt, method='zoh', alpha=None)

将连续状态空间系统转换为离散系统。

参数:

system:描述系统的元组或 lti 的实例

以下内容给出元组中的元素数量和解释:

  • 1: (lti 的实例)
  • 2: (分子,分母)
  • 3: (零点,极点,增益)
  • 4: (A, B, C, D)

dt:浮点数

离散化时间步长。

method:字符串,可选

使用哪种方法:

  • gbt:广义双线性变换
  • bilinear:Tustin 逼近法(“gbt” with alpha=0.5)
  • euler: 欧拉(或向前差分)方法(“gbt” with alpha=0)
  • backward_diff:后向差分(“gbt” with alpha=1.0)
  • zoh:零阶保持(默认)
  • foh:一阶保持(versionadded: 1.3.0
  • impulse:等效冲激响应(versionadded: 1.3.0

alpha:在 [0, 1] 范围内的浮点数,可选

应仅在 method=”gbt” 时指定的广义双线性变换加权参数,否则将被忽略

返回:

sysd:包含离散系统的元组

根据输入类型,输出将采用以下形式

  • (num, den, dt):用于传递函数输入

  • (zeros, poles, gain, dt):用于零点-极点-增益输入

  • (A, B, C, D, dt):用于状态空间系统输入

注意事项

默认情况下,该例程使用零阶保持(zoh)方法执行转换。也可以使用广义双线性变换,其中包括常见的 Tustin 双线性逼近法、欧拉方法技术或后向差分技术。

零阶保持(zoh)方法基于 [1],广义双线性逼近基于 [2][3],一阶保持(foh)方法基于 [4]

参考文献

[1]

en.wikipedia.org/wiki/Discretization#Discretization_of_linear_state_space_models

[2]

techteach.no/publications/discretetime_signals_systems/discrete.pdf

[3]

G. Zhang, X. Chen 和 T. Chen,《Digital redesign via the generalized bilinear transformation》,Int. J. Control,第 82 卷,第 4 期,2009 年,页码 741-754。(www.mypolyuweb.hk/~magzhang/Research/ZCC09_IJC.pdf)

[4]

G. F. Franklin, J. D. Powell 和 M. L. Workman,《Digital control of dynamic systems》,第 3 版,Menlo Park, Calif: Addison-Wesley,1998 年,页码 204-206。

示例

我们可以将连续状态空间系统转换为离散系统:

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy.signal import cont2discrete, lti, dlti, dstep 

定义一个连续状态空间系统。

>>> A = np.array([[0, 1],[-10., -3]])
>>> B = np.array([[0],[10.]])
>>> C = np.array([[1., 0]])
>>> D = np.array([[0.]])
>>> l_system = lti(A, B, C, D)
>>> t, x = l_system.step(T=np.linspace(0, 5, 100))
>>> fig, ax = plt.subplots()
>>> ax.plot(t, x, label='Continuous', linewidth=3) 

使用多种方法将其转换为离散状态空间系统。

>>> dt = 0.1
>>> for method in ['zoh', 'bilinear', 'euler', 'backward_diff', 'foh', 'impulse']:
...    d_system = cont2discrete((A, B, C, D), dt, method=method)
...    s, x_d = dstep(d_system)
...    ax.step(s, np.squeeze(x_d), label=method, where='post')
>>> ax.axis([t[0], t[-1], x[0], 1.4])
>>> ax.legend(loc='best')
>>> fig.tight_layout()
>>> plt.show() 

../../_images/scipy-signal-cont2discrete-1.png

scipy.signal.place_poles

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.place_poles.html#scipy.signal.place_poles

scipy.signal.place_poles(A, B, poles, method='YT', rtol=0.001, maxiter=30)

计算 K,使得特征值(A - dot(B, K))=poles

K 是增益矩阵,使得由线性系统AX+BU描述的过程的闭环极点,即特征值A - B*K,尽可能接近所要求的极点。

支持 SISO、MISO 和 MIMO 系统。

参数:

A, Bndarray

线性系统AX + BU的状态空间表示。

polesarray_like

所需的实部极点和/或共轭复极点。仅支持method="YT"(默认)的复极点。

method: {‘YT’, ‘KNV0’}, optional

选择用于找到增益矩阵 K 的方法之一:

  • ‘YT’:Yang Tits
  • ‘KNV0’:Kautsky、Nichols、Van Dooren 更新方法 0

有关算法的详细信息,请参见参考文献和注释。

rtol: float, optional

每次迭代后,比较A - B*K的特征向量的行列式与其先前值,当这两个值之间的相对误差低于rtol时,算法停止。默认值为 1e-3。

maxiter: int, optional

计算增益矩阵的最大迭代次数。默认值为 30。

返回:

full_state_feedbackBunch 对象

full_state_feedback 由以下组成:

gain_matrix1-D ndarray

闭环矩阵 K,使得A-BK的特征值尽可能接近要求的极点。

computed_poles1-D ndarray

A-BK对应的极点,首先按升序排列实部极点,然后按字典顺序排列共轭复极点。

requested_poles1-D ndarray

算法要求的极点如上所述排序,可能与实际实现的不同。

X2-D ndarray

传递矩阵如X * diag(poles) = (A - B*K)*X(参见注释)

rtolfloat

实现在det(X)上实现的相对容差(参见注释)。如果能够解决系统diag(poles) = (A - B*K),则rtol将为 NaN;当优化算法无法做任何事情,即B.shape[1] == 1时,为 0。

nb_iterint

在收敛之前执行的迭代次数。如果能够解决系统diag(poles) = (A - B*K),则nb_iter将为 NaN;当优化算法无法做任何事情,即B.shape[1] == 1时,为 0。

注释

Tits 和 Yang(YT)论文[2]是 Kautsky 等人(KNV)原始论文[1]的更新。KNV 依赖于秩-1 更新,以找到传递矩阵 X,使得X * diag(poles) = (A - B*K)*X,而 YT 使用秩-2 更新。这通常会产生更为健壮的解决方案(参见[2]第 21-22 页),此外 YT 算法支持复极点,而 KNV 原始版本不支持。此处仅实现了 KNV 提出的更新方法 0,因此命名为'KNV0'。

KNV 扩展到复极点被用于 Matlab 的place函数,YT 以非自由许可证由 Slicot 发布,名称为robpole。目前尚不清楚和未记录如何将 KNV0 扩展到复极点(Tits 和 Yang 在其论文第 14 页声称他们的方法不能用于扩展 KNV 到复极点),因此只有 YT 在这个实现中支持它们。

由于对于 MIMO 系统来说,极点配置问题的解并不唯一,因此两种方法都从一个试探性的传递矩阵开始,该矩阵以不同的方式改变以增加其行列式。已经证明这两种方法都会收敛到一个稳定的解,然而,根据初始传递矩阵的选择方式,它们将收敛到不同的解,因此使用'KNV0'不能保证产生与 Matlab 或任何其他实现这些算法的结果相似。

在大多数情况下,使用默认方法'YT'应该是可以的;'KNV0'仅提供是因为在某些特定情况下'YT'需要。此外,'YT'比使用绝对值abs(det(X))作为鲁棒性指标时,'KNV0'平均提供更稳健的结果。

[2] 可作为技术报告在以下网址获取:hdl.handle.net/1903/5598

参考文献

[1] (1,2)

J. Kautsky, N.K. Nichols 和 P. van Dooren,“线性状态反馈中的鲁棒极点分配”,《国际控制杂志》,第 41 卷,第 1129-1155 页,1985 年。

[2] (1,2,3)

A.L. Tits 和 Y. Yang,“用于鲁棒状态反馈极点分配的全局收敛算法”,《IEEE 自动控制杂志》,第 41 卷,第 1432-1452 页,1996 年。

示例

一个简单的示例,展示了使用 KNV 和 YT 算法进行实际极点配置的方法。这是参考 KNV 出版物第四部分中的示例 1(1):

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt 
>>> A = np.array([[ 1.380,  -0.2077,  6.715, -5.676  ],
...               [-0.5814, -4.290,   0,      0.6750 ],
...               [ 1.067,   4.273,  -6.654,  5.893  ],
...               [ 0.0480,  4.273,   1.343, -2.104  ]])
>>> B = np.array([[ 0,      5.679 ],
...               [ 1.136,  1.136 ],
...               [ 0,      0,    ],
...               [-3.146,  0     ]])
>>> P = np.array([-0.2, -0.5, -5.0566, -8.6659]) 

现在使用 KNV 方法 0 计算 K,使用默认的 YT 方法以及使用强制算法 100 次迭代的 YT 方法,并在每次调用后打印一些结果。

>>> fsf1 = signal.place_poles(A, B, P, method='KNV0')
>>> fsf1.gain_matrix
array([[ 0.20071427, -0.96665799,  0.24066128, -0.10279785],
 [ 0.50587268,  0.57779091,  0.51795763, -0.41991442]]) 
>>> fsf2 = signal.place_poles(A, B, P)  # uses YT method
>>> fsf2.computed_poles
array([-8.6659, -5.0566, -0.5   , -0.2   ]) 
>>> fsf3 = signal.place_poles(A, B, P, rtol=-1, maxiter=100)
>>> fsf3.X
array([[ 0.52072442+0.j, -0.08409372+0.j, -0.56847937+0.j,  0.74823657+0.j],
 [-0.04977751+0.j, -0.80872954+0.j,  0.13566234+0.j, -0.29322906+0.j],
 [-0.82266932+0.j, -0.19168026+0.j, -0.56348322+0.j, -0.43815060+0.j],
 [ 0.22267347+0.j,  0.54967577+0.j, -0.58387806+0.j, -0.40271926+0.j]]) 

X 的行列式的绝对值是检查结果鲁棒性的良好指标,'KNV0''YT'都旨在最大化它。以下是上述结果鲁棒性的比较:

>>> abs(np.linalg.det(fsf1.X)) < abs(np.linalg.det(fsf2.X))
True
>>> abs(np.linalg.det(fsf2.X)) < abs(np.linalg.det(fsf3.X))
True 

现在是一个复极点的简单示例:

>>> A = np.array([[ 0,  7/3.,  0,   0   ],
...               [ 0,   0,    0,  7/9. ],
...               [ 0,   0,    0,   0   ],
...               [ 0,   0,    0,   0   ]])
>>> B = np.array([[ 0,  0 ],
...               [ 0,  0 ],
...               [ 1,  0 ],
...               [ 0,  1 ]])
>>> P = np.array([-3, -1, -2-1j, -2+1j]) / 3.
>>> fsf = signal.place_poles(A, B, P, method='YT') 

我们可以在复平面上绘制期望和计算的极点:

>>> t = np.linspace(0, 2*np.pi, 401)
>>> plt.plot(np.cos(t), np.sin(t), 'k--')  # unit circle
>>> plt.plot(fsf.requested_poles.real, fsf.requested_poles.imag,
...          'wo', label='Desired')
>>> plt.plot(fsf.computed_poles.real, fsf.computed_poles.imag, 'bx',
...          label='Placed')
>>> plt.grid()
>>> plt.axis('image')
>>> plt.axis([-1.1, 1.1, -1.1, 1.1])
>>> plt.legend(bbox_to_anchor=(1.05, 1), loc=2, numpoints=1) 

../../_images/scipy-signal-place_poles-1.png

scipy.signal.chirp

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.chirp.html#scipy.signal.chirp

scipy.signal.chirp(t, f0, t1, f1, method='linear', phi=0, vertex_zero=True)

频率扫描余弦发生器。

在下文中,“Hz”应理解为“每单位的循环次数”;这里没有要求单位必须为一秒。重要的区别在于旋转的单位是循环,而不是弧度。同样,t 可能是空间的度量,而不是时间的度量。

参数:

t:类似数组

评估波形的时间点。

f0:浮点数

时间 t=0 时的频率(例如 Hz)。

t1:浮点数

指定 f1 的时间。

f1:浮点数

时间 t1 处波形的频率(例如 Hz)。

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

频率扫描类型。如果未给出,则假定为 linear。有关更多详细信息,请参见下面的注意事项。

phi:浮点数,可选

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

vertex_zero:布尔值,可选

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

返回:

y:ndarray

包含在 t 上评估请求的时变频率信号的 numpy 数组。更精确地说,函数返回 cos(phase + (pi/180)*phi),其中 phase2*pi*f(t) 的积分(从 0 到 t)。f(t) 如下定义。

另请参见

sweep_poly

注意

method 有四个选项。以下公式给出了由 chirp() 生成的信号的瞬时频率(以 Hz 为单位)。为方便起见,下面显示的较短名称也可以使用。

linear、lin、li:

f(t) = f0 + (f1 - f0) * t / t1

quadratic、quad、q:

频率 f(t) 的图形是通过点 (0, f0) 和 (t1, f1) 的抛物线。默认情况下,抛物线顶点位于 (0, f0) 处。如果 vertex_zero 为 False,则顶点位于 (t1, f1) 处。公式如下:

如果 vertex_zero 为 True:

f(t) = f0 + (f1 - f0) * t**2 / t1**2

else:

f(t) = f1 - (f1 - f0) * (t1 - t)**2 / t1**2

要使用更一般的二次函数或任意多项式,请使用函数 scipy.signal.sweep_poly

logarithmic、log、lo:

f(t) = f0 * (f1/f0)**(t/t1)

f0 和 f1 必须非零,并且符号相同。

该信号也称为几何或指数啁啾。

hyperbolic、hyp:

f(t) = f0*f1*t1 / ((f0 - f1)*t + f1*t1)

f0 和 f1 必须非零。

示例

在示例中将使用以下内容:

>>> import numpy as np
>>> from scipy.signal import chirp, spectrogram
>>> import matplotlib.pyplot as plt 

首个示例中,我们将绘制从 6 Hz 到 1 Hz 的线性啁啾波形,时长为 10 秒:

>>> t = np.linspace(0, 10, 1500)
>>> w = chirp(t, f0=6, f1=1, t1=10, method='linear')
>>> plt.plot(t, w)
>>> plt.title("Linear Chirp, f(0)=6, f(10)=1")
>>> plt.xlabel('t (sec)')
>>> plt.show() 

../../_images/scipy-signal-chirp-1_00_00.png

对于其余示例,我们将使用更高的频率范围,并使用scipy.signal.spectrogram来展示结果。我们将使用 7200 Hz 采样的 4 秒间隔。

>>> fs = 7200
>>> T = 4
>>> t = np.arange(0, int(T*fs)) / fs 

我们将使用此函数在每个示例中绘制频谱图。

>>> def plot_spectrogram(title, w, fs):
...     ff, tt, Sxx = spectrogram(w, fs=fs, nperseg=256, nfft=576)
...     fig, ax = plt.subplots()
...     ax.pcolormesh(tt, ff[:145], Sxx[:145], cmap='gray_r',
...                   shading='gouraud')
...     ax.set_title(title)
...     ax.set_xlabel('t (sec)')
...     ax.set_ylabel('Frequency (Hz)')
...     ax.grid(True)
... 

从 1500 Hz 到 250 Hz 的二次啁啾(频率抛物线曲线的顶点在 t=0):

>>> w = chirp(t, f0=1500, f1=250, t1=T, method='quadratic')
>>> plot_spectrogram(f'Quadratic Chirp, f(0)=1500, f({T})=250', w, fs)
>>> plt.show() 

../../_images/scipy-signal-chirp-1_01_00.png

从 1500 Hz 到 250 Hz 的二次啁啾(频率抛物线曲线的顶点在 t=T):

>>> w = chirp(t, f0=1500, f1=250, t1=T, method='quadratic',
...           vertex_zero=False)
>>> plot_spectrogram(f'Quadratic Chirp, f(0)=1500, f({T})=250\n' +
...                  '(vertex_zero=False)', w, fs)
>>> plt.show() 

../../_images/scipy-signal-chirp-1_02_00.png

从 1500 Hz 到 250 Hz 的对数啁啾:

>>> w = chirp(t, f0=1500, f1=250, t1=T, method='logarithmic')
>>> plot_spectrogram(f'Logarithmic Chirp, f(0)=1500, f({T})=250', w, fs)
>>> plt.show() 

../../_images/scipy-signal-chirp-1_03_00.png

从 1500 Hz 到 250 Hz 的双曲线啁啾:

>>> w = chirp(t, f0=1500, f1=250, t1=T, method='hyperbolic')
>>> plot_spectrogram(f'Hyperbolic Chirp, f(0)=1500, f({T})=250', w, fs)
>>> plt.show() 

../../_images/scipy-signal-chirp-1_04_00.png

scipy.signal.gausspulse

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.gausspulse.html#scipy.signal.gausspulse

scipy.signal.gausspulse(t, fc=1000, bw=0.5, bwr=-6, tpr=-60, retquad=False, retenv=False)

返回一个高斯调制的正弦波:

exp(-a t²) exp(1j*2*pi*fc*t).

如果 retquad 为 True,则返回实部和虚部(同相和象限)。如果 retenv 为 True,则返回包络(未调制信号)。否则,返回调制正弦波的实部。

参数:

tndarray 或字符串 'cutoff'

输入数组。

fcfloat,可选

中心频率(例如 Hz)。默认为 1000。

bwfloat,可选

脉冲在频率域的分数带宽(例如 Hz)。默认为 0.5。

bwrfloat,可选

用于计算分数带宽的参考级别(dB)。默认为 -6。

tprfloat,可选

如果 t 为 'cutoff',则函数返回脉冲幅度下降至 tpr(以 dB 为单位)的截止时间。默认为 -60。

retquadbool,可选

如果为 True,则返回信号的象限(虚部)以及实部。默认为 False。

retenvbool,可选

如果为 True,则返回信号的包络。默认为 False。

返回:

yIndarray

信号的实部。始终返回。

yQndarray

信号的虚部。仅在 retquad 为 True 时返回。

yenvndarray

信号的包络。仅在 retenv 为 True 时返回。

另请参阅

scipy.signal.morlet

示例

绘制实部、虚部和 5 Hz 脉冲的包络,以 100 Hz 采样 2 秒:

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> t = np.linspace(-1, 1, 2 * 100, endpoint=False)
>>> i, q, e = signal.gausspulse(t, fc=5, retquad=True, retenv=True)
>>> plt.plot(t, i, t, q, t, e, '--') 

../../_images/scipy-signal-gausspulse-1.png

scipy.signal.max_len_seq

原文链接:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.max_len_seq.html#scipy.signal.max_len_seq

scipy.signal.max_len_seq(nbits, state=None, length=None, taps=None)

最大长度序列(MLS)生成器。

参数:

nbitsint

要使用的位数。生成的序列长度将为 (2**nbits) - 1。请注意,生成长序列(例如大于 nbits == 16)可能需要很长时间。

statearray_like,可选

如果是数组,则必须是 nbits 长度,并将被转换为二进制(bool)表示。如果为 None,则使用全 1 的种子,生成可重复的表示。如果 state 全为零,则会引发错误,因为这是无效的。默认值:None。

lengthint,可选

要计算的样本数。如果为 None,则计算整个长度 (2**nbits) - 1

tapsarray_like,可选

用于生成多项式 taps(例如 [7, 6, 1] 用于 8 位序列)。如果为 None,则会自动选择 taps(最多支持 nbits == 32)。

返回:

seqarray

结果的 MLS 序列,由 0 和 1 组成。

statearray

移位寄存器的最终状态。

笔记

MLS 生成算法在以下面描述:

en.wikipedia.org/wiki/Maximum_length_sequence

taps 的默认值专门取自每个 nbits 值的第一个选项:

web.archive.org/web/20181001062252/http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm

0.15.0 版中的新功能。

示例

MLS 使用二进制约定:

>>> from scipy.signal import max_len_seq
>>> max_len_seq(4)[0]
array([1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0], dtype=int8) 

MLS 具有白色频谱(除了直流分量):

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from numpy.fft import fft, ifft, fftshift, fftfreq
>>> seq = max_len_seq(6)[0]*2-1  # +1 and -1
>>> spec = fft(seq)
>>> N = len(seq)
>>> plt.plot(fftshift(fftfreq(N)), fftshift(np.abs(spec)), '.-')
>>> plt.margins(0.1, 0.1)
>>> plt.grid(True)
>>> plt.show() 

../../_images/scipy-signal-max_len_seq-1_00_00.png

MLS 的循环自相关是一个冲激:

>>> acorrcirc = ifft(spec * np.conj(spec)).real
>>> plt.figure()
>>> plt.plot(np.arange(-N/2+1, N/2+1), fftshift(acorrcirc), '.-')
>>> plt.margins(0.1, 0.1)
>>> plt.grid(True)
>>> plt.show() 

../../_images/scipy-signal-max_len_seq-1_01_00.png

MLS 的线性自相关大致上是一个冲激:

>>> acorr = np.correlate(seq, seq, 'full')
>>> plt.figure()
>>> plt.plot(np.arange(-N+1, N), acorr, '.-')
>>> plt.margins(0.1, 0.1)
>>> plt.grid(True)
>>> plt.show() 

../../_images/scipy-signal-max_len_seq-1_02_00.png

scipy.signal.sawtooth

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.sawtooth.html#scipy.signal.sawtooth

scipy.signal.sawtooth(t, width=1)

返回一个周期性的锯齿波或三角波形。

锯齿波形的周期是 2*pi,在区间 0 到 width*2*pi 上升从-1 到 1,然后在区间 width*2*pi2*pi 下降从 1 到-1。width 必须在区间 [0, 1] 内。

请注意这不是带限制的。它产生无限多的谐波,这些谐波在频率谱上来回反射。

参数:

tarray_like

时间。

widtharray_like, 可选

上升斜坡的宽度,作为总周期的比例。默认为 1,生成上升斜坡,而 0 生成下降斜坡。width = 0.5 生成三角波。如果是一个数组,则导致波形随时间变化,并且必须与 t 具有相同的长度。

返回:

yndarray

包含锯齿波形的输出数组。

示例

以 500 Hz 对 1 秒钟进行采样的 5 Hz 波形:

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> t = np.linspace(0, 1, 500)
>>> plt.plot(t, signal.sawtooth(2 * np.pi * 5 * t)) 

../../_images/scipy-signal-sawtooth-1.png