SciPy-1-12-中文文档-十七-

89 阅读26分钟

SciPy 1.12 中文文档(十七)

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

scipy.linalg.hessenberg

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

scipy.linalg.hessenberg(a, calc_q=False, overwrite_a=False, check_finite=True)

计算矩阵的 Hessenberg 形式。

Hessenberg 分解为:

A = Q H Q^H 

其中 Q 是单位 ary/正交的,H 除了第一个次对角线以下的元素外都为零。

参数:

a(M, M) array_like

要转换为 Hessenberg 形式的矩阵。

calc_qbool, 可选

是否计算变换矩阵。默认为 False。

overwrite_abool, 可选

是否覆盖 a;可能提高性能。默认为 False。

check_finitebool, 可选

是否检查输入矩阵仅包含有限数字。禁用可能提高性能,但如果输入包含无穷大或 NaN,可能导致问题(崩溃、非终止)。

返回:

H(M, M) ndarray

a 的 Hessenberg 形式。

Q(M, M) ndarray

单位 ary/正交相似变换矩阵 A = Q H Q^H。仅在 calc_q=True 时返回。

示例

>>> import numpy as np
>>> from scipy.linalg import hessenberg
>>> A = np.array([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]])
>>> H, Q = hessenberg(A, calc_q=True)
>>> H
array([[  2\.        , -11.65843866,   1.42005301,   0.25349066],
 [ -9.94987437,  14.53535354,  -5.31022304,   2.43081618],
 [  0\.        ,  -1.83299243,   0.38969961,  -0.51527034],
 [  0\.        ,   0\.        ,  -3.83189513,   1.07494686]])
>>> np.allclose(Q @ H @ Q.conj().T - A, np.zeros((4, 4)))
True 

scipy.linalg.cdf2rdf

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

scipy.linalg.cdf2rdf(w, v)

将复数特征值w和特征向量v转换为实块对角形式的实特征值wr及相关的实特征向量vr,使得:

vr @ wr = X @ vr 

保持不变,其中Xwv是其特征值和特征向量的原始数组。

1.1.0 版本新增。

参数:

w(…, M) array_like

复数或实特征值,数组或数组堆栈

如果交错排列共轭对,将会产生错误结果。因此,[1+1j, 1, 1-1j]将给出正确结果,但[1+1j, 2+1j, 1-1j, 2-1j]则不会。

v(…, M, M) array_like

复数或实特征向量,方阵或方阵堆栈。

返回:

wr(…, M, M) ndarray

特征值的实对角块形式

vr(…, M, M) ndarray

wr相关的实特征向量

参见

eig函数

对于非对称数组的特征值和右特征向量

rsf2csf函数

将实舒尔形式转换为复舒尔形式

注释

wv必须是某些矩阵X的特征结构,例如通过w, v = scipy.linalg.eig(X)w, v = numpy.linalg.eig(X)获得,其中X也可以表示为堆叠的数组。

1.1.0 版本新增。

示例

>>> import numpy as np
>>> X = np.array([[1, 2, 3], [0, 4, 5], [0, -5, 4]])
>>> X
array([[ 1,  2,  3],
 [ 0,  4,  5],
 [ 0, -5,  4]]) 
>>> from scipy import linalg
>>> w, v = linalg.eig(X)
>>> w
array([ 1.+0.j,  4.+5.j,  4.-5.j])
>>> v
array([[ 1.00000+0.j     , -0.01906-0.40016j, -0.01906+0.40016j],
 [ 0.00000+0.j     ,  0.00000-0.64788j,  0.00000+0.64788j],
 [ 0.00000+0.j     ,  0.64788+0.j     ,  0.64788-0.j     ]]) 
>>> wr, vr = linalg.cdf2rdf(w, v)
>>> wr
array([[ 1.,  0.,  0.],
 [ 0.,  4.,  5.],
 [ 0., -5.,  4.]])
>>> vr
array([[ 1\.     ,  0.40016, -0.01906],
 [ 0\.     ,  0.64788,  0\.     ],
 [ 0\.     ,  0\.     ,  0.64788]]) 
>>> vr @ wr
array([[ 1\.     ,  1.69593,  1.9246 ],
 [ 0\.     ,  2.59153,  3.23942],
 [ 0\.     , -3.23942,  2.59153]])
>>> X @ vr
array([[ 1\.     ,  1.69593,  1.9246 ],
 [ 0\.     ,  2.59153,  3.23942],
 [ 0\.     , -3.23942,  2.59153]]) 

scipy.linalg.cossin

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.cossin.html#scipy.linalg.cossin

scipy.linalg.cossin(X, p=None, q=None, separate=False, swap_sign=False, compute_u=True, compute_vh=True)

计算正交/酉矩阵的余弦-正弦(CS)分解。

X 是一个(m, m)正交/酉矩阵,分块如下,其中左上角块的形状为(p, q)

 ┌                   ┐
                           │ I  0  00  0  0 │
┌           ┐   ┌         ┐│ 0  C  00 -S  0 │┌         ┐*
│ X11 │ X12 │   │ U1 │    ││ 0  0  00  0 -I ││ V1 │    │
│ ────┼──── │ = │────┼────││─────────┼─────────││────┼────│
│ X21 │ X22 │   │    │ U2 ││ 0  0  0 │ I  0  0 ││    │ V2 │
└           ┘   └         ┘│ 0  S  00  C  0 │└         ┘
                           │ 0  0  I │ 0  0  0 │
                           └                   ┘ 

U1, U2, V1, V2 是维度分别为(p,p)(m-p,m-p)(q,q)(m-q,m-q) 的方正交/酉矩阵,CS 是满足 C² + S² = I(r,r)非负对角矩阵,其中 r = min(p, m-p, q, m-q)

此外,单位矩阵的秩分别为min(p, q) - rmin(p, m - q) - rmin(m - p, q) - rmin(m - p, m - q) - r

X 可以通过其自身和块规格 p, q 或其子块的可迭代对象提供。参见下面的示例。

参数:

X类数组,可迭代对象

要分解的复数酉或实正交矩阵,或子块 X11, X12, X21, X22 的可迭代对象,当省略 p, q 时。

p整数,可选

左上角块 X11 的行数,仅在给定 X 作为数组时使用。

q整数,可选

左上角块 X11 的列数,仅在给定 X 作为数组时使用。

separate布尔值,可选

如果为True,则返回低级组件而不是矩阵因子,即 (u1,u2), theta, (v1h,v2h) 而不是 u, cs, vh

swap_sign布尔值,可选

如果为True,则-S-I块将位于左下角,否则(默认情况下)它们将位于右上角。

compute_u布尔值,可选

如果为Falseu将不会被计算,并返回一个空数组。

compute_vh布尔值,可选

如果为Falsevh将不会被计算,并返回一个空数组。

返回:

u数组

compute_u=True时,包含由块对角线正交/酉矩阵组成的块 U1 (p x p) 和 U2 (m-p x m-p)。如果separate=True,则包含元组(U1, U2)

cs数组

具有上述结构的余弦-正弦因子。

如果separate=True,则包含角度以弧度表示的theta数组。

vh数组

pycompute_vh=True`, contains the block diagonal orthogonal/unitary matrix consisting of the blocks ``V1H (q x q) 和 V2H (m-q x m-q) 正交/酉矩阵。如果separate=True,则包含元组(V1H, V2H)

参考文献

[1]

Brian D. Sutton. 计算完整的 CS 分解。Numer. Algorithms, 50(1):33-65, 2009.

示例

>>> import numpy as np
>>> from scipy.linalg import cossin
>>> from scipy.stats import unitary_group
>>> x = unitary_group.rvs(4)
>>> u, cs, vdh = cossin(x, p=2, q=2)
>>> np.allclose(x, u @ cs @ vdh)
True 

也可以通过子块输入,无需 pq。还让我们跳过 u 的计算。

>>> ue, cs, vdh = cossin((x[:2, :2], x[:2, 2:], x[2:, :2], x[2:, 2:]),
...                      compute_u=False)
>>> print(ue)
[]
>>> np.allclose(x, u @ cs @ vdh)
True 

scipy.linalg.expm

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.expm.html#scipy.linalg.expm

scipy.linalg.expm(A)

计算数组的矩阵指数。

参数:

Andarray

输入的最后两个维度是方形的(..., n, n)

返回:

eAndarray

结果矩阵指数与A的形状相同

注意

实现了在[1]中给出的算法,这实质上是一种带有基于数组数据决定的可变阶数的 Pade 逼近。

对于大小为n的输入,在最坏情况下,内存使用量是8*(n**2)的数量级。如果输入数据不是单精度和双精度的实数和复数数据类型,则将其复制到一个新的数组。

对于n >= 400的情况,精确的 1-范数计算成本与 1-范数估计持平,并且从那一点开始,使用[2]中给出的估计方案来决定逼近阶数。

参考文献

[1]

Awad H. Al-Mohy 和 Nicholas J. Higham(2009),"矩阵指数的新缩放和平方算法",SIAM J. Matrix Anal. Appl. 31(3):970-989,DOI:10.1137/09074721X

[2]

Nicholas J. Higham 和 Francoise Tisseur(2000),"用于矩阵 1-范数估计的块算法,及其在 1-范数伪谱中的应用",SIAM J. Matrix Anal. Appl. 21(4):1185-1201,DOI:10.1137/S0895479899356080

示例

>>> import numpy as np
>>> from scipy.linalg import expm, sinm, cosm 

公式 exp(0) = 1 的矩阵版本:

>>> expm(np.zeros((3, 2, 2)))
array([[[1., 0.],
 [0., 1.]],

 [[1., 0.],
 [0., 1.]],

 [[1., 0.],
 [0., 1.]]]) 

欧拉恒等式(exp(itheta) = cos(theta) + isin(theta))应用于矩阵:

>>> a = np.array([[1.0, 2.0], [-1.0, 3.0]])
>>> expm(1j*a)
array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
 [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])
>>> cosm(a) + 1j*sinm(a)
array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
 [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]]) 

scipy.linalg.logm

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.logm.html#scipy.linalg.logm

scipy.linalg.logm(A, disp=True)

计算矩阵对数。

矩阵对数是 expm 的逆:expm(logm(A)) == A

参数:

A(N, N) 类似数组

要评估其对数的矩阵

disp 布尔值,可选项

如果估计的结果误差较大,则打印警告,而不是返回估计的误差。 (默认:True)

返回:

logm(N, N) ndarray

A 的矩阵对数

errest 浮点数

(如果 disp == False)

估计误差的 1-范数,||err||_1 / ||A||_1

参考文献

[1]

Awad H. Al-Mohy 和 Nicholas J. Higham (2012) “矩阵对数的改进逆缩放和平方算法。”《SIAM 科学计算杂志》,34 (4). C152-C169. ISSN 1095-7197

[2]

Nicholas J. Higham (2008) “矩阵函数:理论与计算” ISBN 978-0-898716-46-7

[3]

Nicholas J. Higham 和 Lijing lin (2011) “矩阵的分数幂的 Schur-Pade 算法。”《SIAM 矩阵分析和应用杂志》,32 (3). pp. 1056-1078. ISSN 0895-4798

示例

>>> import numpy as np
>>> from scipy.linalg import logm, expm
>>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
>>> b = logm(a)
>>> b
array([[-1.02571087,  2.05142174],
 [ 0.68380725,  1.02571087]])
>>> expm(b)         # Verify expm(logm(a)) returns a
array([[ 1.,  3.],
 [ 1.,  4.]]) 

scipy.linalg.cosm

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

scipy.linalg.cosm(A)

计算矩阵余弦。

这个 这个例程使用 expm 来计算矩阵指数。

参数:

A(N, N) array_like

输入数组

返回值:

cosm(N, N) ndarray

A 的矩阵余弦

例子

>>> import numpy as np
>>> from scipy.linalg import expm, sinm, cosm 

应用于矩阵的欧拉恒等式(exp(itheta) = cos(theta) + isin(theta)):

>>> a = np.array([[1.0, 2.0], [-1.0, 3.0]])
>>> expm(1j*a)
array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
 [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])
>>> cosm(a) + 1j*sinm(a)
array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
 [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]]) 

scipy.linalg.sinm

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.sinm.html#scipy.linalg.sinm

scipy.linalg.sinm(A)

计算矩阵正弦。

此例程使用expm来计算矩阵的指数。

参数:

A(N, N) array_like

输入数组。

返回:

sinm(N, N) ndarray

A 的矩阵正弦

示例

>>> import numpy as np
>>> from scipy.linalg import expm, sinm, cosm 

Euler’s identity (exp(i*theta) = cos(theta) + i*sin(theta)) 应用于矩阵:

>>> a = np.array([[1.0, 2.0], [-1.0, 3.0]])
>>> expm(1j*a)
array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
 [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])
>>> cosm(a) + 1j*sinm(a)
array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
 [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]]) 

scipy.linalg.tanm

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.tanm.html#scipy.linalg.tanm

scipy.linalg.tanm(A)

计算矩阵的切线。

此例程使用 expm 计算矩阵指数。

参数:

A(N, N) 数组样式

输入数组。

返回:

tanm(N, N) ndarray

A 的矩阵切线

示例

>>> import numpy as np
>>> from scipy.linalg import tanm, sinm, cosm
>>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
>>> t = tanm(a)
>>> t
array([[ -2.00876993,  -8.41880636],
 [ -2.80626879, -10.42757629]]) 

验证 tanm(a) = sinm(a).dot(inv(cosm(a)))

>>> s = sinm(a)
>>> c = cosm(a)
>>> s.dot(np.linalg.inv(c))
array([[ -2.00876993,  -8.41880636],
 [ -2.80626879, -10.42757629]]) 

scipy.linalg.coshm

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.coshm.html#scipy.linalg.coshm

scipy.linalg.coshm(A)

计算双曲矩阵余弦。

此例程使用 expm 来计算矩阵指数。

参数:

A(N, N) 数组类似物

输入数组。

返回:

coshm(N, N) 数组形状

A 的双曲矩阵余弦

示例

>>> import numpy as np
>>> from scipy.linalg import tanhm, sinhm, coshm
>>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
>>> c = coshm(a)
>>> c
array([[ 11.24592233,  38.76236492],
 [ 12.92078831,  50.00828725]]) 

验证 tanhm(a) = sinhm(a).dot(inv(coshm(a)))

>>> t = tanhm(a)
>>> s = sinhm(a)
>>> t - s.dot(np.linalg.inv(c))
array([[  2.72004641e-15,   4.55191440e-15],
 [  0.00000000e+00,  -5.55111512e-16]]) 

scipy.linalg.sinhm

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

scipy.linalg.sinhm(A)

计算双曲矩阵正弦。

此例程使用 expm 计算矩阵指数。

参数:

A(N, N) array_like

输入数组。

返回:

sinhm(N, N) ndarray

A 的双曲矩阵正弦

示例

>>> import numpy as np
>>> from scipy.linalg import tanhm, sinhm, coshm
>>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
>>> s = sinhm(a)
>>> s
array([[ 10.57300653,  39.28826594],
 [ 13.09608865,  49.86127247]]) 

验证 tanhm(a) = sinhm(a).dot(inv(coshm(a)))

>>> t = tanhm(a)
>>> c = coshm(a)
>>> t - s.dot(np.linalg.inv(c))
array([[  2.72004641e-15,   4.55191440e-15],
 [  0.00000000e+00,  -5.55111512e-16]]) 

scipy.linalg.tanhm

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.tanhm.html#scipy.linalg.tanhm

scipy.linalg.tanhm(A)

计算双曲矩阵切线。

该例程使用 expm 计算矩阵指数。

参数:

A(N, N) array_like

输入数组

返回:

tanhm(N, N) ndarray

A 的双曲矩阵切线

示例

>>> import numpy as np
>>> from scipy.linalg import tanhm, sinhm, coshm
>>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
>>> t = tanhm(a)
>>> t
array([[ 0.3428582 ,  0.51987926],
 [ 0.17329309,  0.86273746]]) 

验证 tanhm(a) = sinhm(a).dot(inv(coshm(a)))

>>> s = sinhm(a)
>>> c = coshm(a)
>>> t - s.dot(np.linalg.inv(c))
array([[  2.72004641e-15,   4.55191440e-15],
 [  0.00000000e+00,  -5.55111512e-16]]) 

scipy.linalg.signm

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.signm.html#scipy.linalg.signm

scipy.linalg.signm(A, disp=True)

矩阵签名函数。

标量 sign(x)对矩阵的扩展。

参数:

A(N, N) 数组型

评估签名函数的矩阵

disp布尔值,可选

打印警告,如果结果中估计的误差较大而不是返回估计的错误。(默认:True)

返回:

signm(N, N) 数组型

签名函数在A处的值

errest浮点数

(如果 disp == False)

1-范数的估计误差,||err||_1 / ||A||_1

示例

>>> from scipy.linalg import signm, eigvals
>>> a = [[1,2,3], [1,2,1], [1,1,1]]
>>> eigvals(a)
array([ 4.12488542+0.j, -0.76155718+0.j,  0.63667176+0.j])
>>> eigvals(signm(a))
array([-1.+0.j,  1.+0.j,  1.+0.j]) 

scipy.linalg.sqrtm

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.sqrtm.html#scipy.linalg.sqrtm

scipy.linalg.sqrtm(A, disp=True, blocksize=64)

矩阵平方根。

参数:

A(N, N) array_like

要评估其平方根的矩阵

disp布尔值,可选

如果结果中的误差估计较大,则打印警告,而不是返回估计的误差。(默认:True)

blocksize整数,可选

如果块大小与输入数组的大小不同,则使用块算法。(默认:64)

返回:

sqrtm(N, N) ndarray

A处的 sqrt 函数值。数据类型为 float 或 complex。精度(数据大小)基于输入A的精度。当数据类型为 float 时,精度与A相同。当数据类型为 complex 时,精度是A的两倍。每种数据类型的精度可能会被各自的精度范围所限制。

errest浮点数

(如果 disp == False)

估计误差的 Frobenius 范数,||err||_F / ||A||_F

参考文献

[1]

Edvin Deadman, Nicholas J. Higham, Rui Ralha (2013) “Blocked Schur Algorithms for Computing the Matrix Square Root, Lecture Notes in Computer Science, 7782. pp. 171-182.

示例

>>> import numpy as np
>>> from scipy.linalg import sqrtm
>>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
>>> r = sqrtm(a)
>>> r
array([[ 0.75592895,  1.13389342],
 [ 0.37796447,  1.88982237]])
>>> r.dot(r)
array([[ 1.,  3.],
 [ 1.,  4.]]) 

scipy.linalg.funm

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

scipy.linalg.funm(A, func, disp=True)

评估由可调用对象指定的矩阵函数。

返回函数 fA 处的矩阵值。函数 f 是将标量函数 func 推广到矩阵的扩展。

参数:

A(N, N) array_like

用于评估函数的矩阵

funccallable

评估标量函数 f 的可调用对象。必须是矢量化的(例如,使用 vectorize)。

dispbool, 可选

如果结果中的误差估计较大,则打印警告而不是返回估计的误差。(默认:True)

返回:

funm(N, N) ndarray

A 处评估的由 func 指定的矩阵函数的值

errestfloat

(如果 disp == False)

估计误差的 1-范数,||err||_1 / ||A||_1

注意

该函数实现了基于舒尔分解的一般算法(算法 9.1.1 在 [1] 中)。

如果已知输入矩阵可对角化,则依赖于特征分解可能更快。例如,如果你的矩阵是埃尔米特矩阵,你可以执行

>>> from scipy.linalg import eigh
>>> def funm_herm(a, func, check_finite=False):
...     w, v = eigh(a, check_finite=check_finite)
...     ## if you further know that your matrix is positive semidefinite,
...     ## you can optionally guard against precision errors by doing
...     # w = np.maximum(w, 0)
...     w = func(w)
...     return (v * w).dot(v.conj().T) 

参考文献

[1]

Gene H. Golub, Charles F. van Loan, 《Matrix Computations》第四版。

示例

>>> import numpy as np
>>> from scipy.linalg import funm
>>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
>>> funm(a, lambda x: x*x)
array([[  4.,  15.],
 [  5.,  19.]])
>>> a.dot(a)
array([[  4.,  15.],
 [  5.,  19.]]) 

scipy.linalg.expm_frechet

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

scipy.linalg.expm_frechet(A, E, method=None, compute_expm=True, check_finite=True)

A 的矩阵指数在 E 方向上的 Frechet 导数。

参数:

A(N, N) 类似数组

矩阵的矩阵指数。

E(N, N) 类似数组

用于计算 Frechet 导数的矩阵方向。

method字符串,可选

算法的选择。应该是以下之一:

  • SPS(默认)

  • blockEnlarge

compute_expm布尔值,可选

是否同时计算expm_Aexpm_frechet_AE。默认为 True。

check_finite布尔值,可选

是否检查输入矩阵是否仅包含有限数值。禁用可能会提高性能,但如果输入包含无穷大或 NaN,则可能导致问题(崩溃、非终止)。

返回:

expm_A数组

A 的矩阵指数。

expm_frechet_AE数组

A 的矩阵指数在 E 方向上的 Frechet 导数。

对于compute_expm = False,只返回expm_frechet_AE

另请参见:

expm

计算矩阵的指数。

注:

本节描述了可以通过method参数选择的可用实现。默认方法是SPS

方法blockEnlarge是一个朴素的算法。

方法SPS是 Scaling-Pade-Squaring [1]。这是一个复杂的实现,其执行时间只需朴素实现的 3/8。渐近性质相同。

从版本 0.13.0 开始。

参考资料:

[1]

Awad H. Al-Mohy 和 Nicholas J. Higham(2009 年)计算矩阵指数的 Frechet 导数,及其在条件数估计中的应用。SIAM Journal On Matrix Analysis and Applications.,30(4)。pp. 1639-1657。ISSN 1095-7162

示例:

>>> import numpy as np
>>> from scipy import linalg
>>> rng = np.random.default_rng() 
>>> A = rng.standard_normal((3, 3))
>>> E = rng.standard_normal((3, 3))
>>> expm_A, expm_frechet_AE = linalg.expm_frechet(A, E)
>>> expm_A.shape, expm_frechet_AE.shape
((3, 3), (3, 3)) 

创建一个包含[[A, E], [0, A]]的 6x6 矩阵:

>>> M = np.zeros((6, 6))
>>> M[:3, :3] = A
>>> M[:3, 3:] = E
>>> M[3:, 3:] = A 
>>> expm_M = linalg.expm(M)
>>> np.allclose(expm_A, expm_M[:3, :3])
True
>>> np.allclose(expm_frechet_AE, expm_M[:3, 3:])
True 

scipy.linalg.expm_cond

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.expm_cond.html#scipy.linalg.expm_cond

scipy.linalg.expm_cond(A, check_finite=True)

矩阵指数在 Frobenius 范数中的相对条件数。

参数:

A2 维数组类型

形状为(N, N)的方形输入矩阵。

check_finite布尔型,可选

是否检查输入矩阵只包含有限数字。禁用可能会提高性能,但如果输入包含无穷大或 NaN,可能会导致问题(崩溃,非终止)。

返回:

kappa浮点型

矩阵指数在 Frobenius 范数中的相对条件数。

另请参见

expm

计算矩阵的指数。

expm_frechet

计算矩阵指数的 Frechet 导数。

注意事项

已发布 1 范数中条件数的更快估计,但尚未在 SciPy 中实现。

自版本 0.14.0 开始新增。

示例

>>> import numpy as np
>>> from scipy.linalg import expm_cond
>>> A = np.array([[-0.3, 0.2, 0.6], [0.6, 0.3, -0.1], [-0.7, 1.2, 0.9]])
>>> k = expm_cond(A)
>>> k
1.7787805864469866 

scipy.linalg.fractional_matrix_power

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

scipy.linalg.fractional_matrix_power(A, t)

计算矩阵的分数幂。

按照[1]中第六部分的讨论进行。

参数:

  • A(N, N) 数组类型

评估其分数幂的矩阵。

  • tfloat

分数幂。

返回:

  • X(N, N) 数组类型

矩阵的分数幂。

参考文献

[1]

Nicholas J. Higham 和 Lijing lin(2011 年)“矩阵的分数幂的舒尔-帕德算法。”《SIAM 矩阵分析和应用杂志》,32(3)。第 1056-1078 页。ISSN 0895-4798

示例

>>> import numpy as np
>>> from scipy.linalg import fractional_matrix_power
>>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
>>> b = fractional_matrix_power(a, 0.5)
>>> b
array([[ 0.75592895,  1.13389342],
 [ 0.37796447,  1.88982237]])
>>> np.dot(b, b)      # Verify square root
array([[ 1.,  3.],
 [ 1.,  4.]]) 

scipy.linalg.solve_sylvester

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

scipy.linalg.solve_sylvester(a, b, q)

计算 Sylvester 方程 (AX + XB = Q) 的解(X)。

参数:

a(M, M) 数组

Sylvester 方程的首部矩阵

b(N, N) 数组

Sylvester 方程的尾部矩阵

q(M, N) 数组

右手边

返回:

x(M, N) 数组

Sylvester 方程的解。

引发:

LinAlgError

如果找不到解决方案

注意事项

通过巴特尔斯-斯图尔特算法计算 Sylvester 矩阵方程的解。首先对 A 和 B 矩阵进行 Schur 分解。然后利用得到的矩阵构造一个替代的 Sylvester 方程 (RY + YS^T = F),其中 R 和 S 矩阵处于准三角形形式(或当 R、S 或 F 是复数时,为三角形形式)。简化的方程然后直接使用 LAPACK 中的 *TRSYL 解决。

自版本 0.11.0 起新增

示例

给定 a, bq 求解 x

>>> import numpy as np
>>> from scipy import linalg
>>> a = np.array([[-3, -2, 0], [-1, -1, 3], [3, -5, -1]])
>>> b = np.array([[1]])
>>> q = np.array([[1],[2],[3]])
>>> x = linalg.solve_sylvester(a, b, q)
>>> x
array([[ 0.0625],
 [-0.5625],
 [ 0.6875]])
>>> np.allclose(a.dot(x) + x.dot(b), q)
True 

scipy.linalg.solve_continuous_are

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.solve_continuous_are.html#scipy.linalg.solve_continuous_are

scipy.linalg.solve_continuous_are(a, b, q, r, e=None, s=None, balanced=True)

解连续时间代数 Riccati 方程(CARE)。

CARE 的定义为

[X A + A^H X - X B R^{-1} B^H X + Q = 0]

解的存在条件限制为:

  • A 的所有特征值在右半平面上,应该是可控的。
  • 关联的哈密顿笔(见注释),其特征值应足够远离虚轴。

此外,如果es不精确为None,则 CARE 的广义版本

[E^HXA + A^HXE - (E^HXB + S) R^{-1} (B^HXE + S^H) + Q = 0]

被解决。当省略时,假设e为单位矩阵,sab兼容且为零矩阵的大小相同。

参数:

a(M, M) array_like

方阵

b(M, N) array_like

输入

q(M, M) array_like

输入

r(N, N) array_like

非奇异方阵

e(M, M) array_like, 可选

非奇异方阵

s(M, N) array_like, 可选

输入

balancedbool, 可选

指示数据是否进行平衡步骤的布尔值,默认设置为 True。

返回:

x(M, M) ndarray

连续时间代数 Riccati 方程的解。

异常:

LinAlgError

对于无法分离出笔的稳定子空间的情况。请参阅 Notes 部分和详细信息的参考资料。

另见

solve_discrete_are

解决离散时间代数 Riccati 方程

注释

方程式通过形成扩展的哈密顿矩阵笔来解决,如[1]中描述的,由块矩阵给出,[H - \lambda J]

[ A    0    B ]             [ E   0    0 ]
[-Q  -A^H  -S ] - \lambda * [ 0  E^H   0 ]
[ S^H B^H   R ]             [ 0   0    0 ] 

并使用 QZ 分解方法。

在此算法中,失败条件与产品(U_2 U_1^{-1})的对称性和(U_1)的条件数相关。这里,(U)是一个 2m×m 矩阵,包含了稳定子空间的特征向量,具有 2-m 行并分成两个 m 行矩阵。详见[1][2]获取更多详细信息。

为了提高 QZ 分解的准确性,笔在进行平衡步骤时,根据[3]中给出的配方,平衡绝对值的和(在删除对角元素后)。

从版本 0.11.0 开始新增。

参考文献

[1] (1,2)

P. van Dooren,《用于解 Riccati 方程的广义特征值方法》,SIAM 科学与统计计算杂志,Vol.2(2),DOI:10.1137/0902010

[2]

A.J. Laub,“用于解代数 Riccati 方程的 Schur 方法”,麻省理工学院。信息与决策系统实验室。LIDS-R ; 859。在线查看:hdl.handle.net/1721.1/1301

[3]

P. Benner,“哈密顿矩阵的辛平衡”,2001 年,SIAM J. Sci. Comput.,2001 年,Vol.22(5),DOI:10.1137/S1064827500367993

示例

给定 a, b, q, 和 r,解出 x

>>> import numpy as np
>>> from scipy import linalg
>>> a = np.array([[4, 3], [-4.5, -3.5]])
>>> b = np.array([[1], [-1]])
>>> q = np.array([[9, 6], [6, 4.]])
>>> r = 1
>>> x = linalg.solve_continuous_are(a, b, q, r)
>>> x
array([[ 21.72792206,  14.48528137],
 [ 14.48528137,   9.65685425]])
>>> np.allclose(a.T.dot(x) + x.dot(a)-x.dot(b).dot(b.T).dot(x), -q)
True 

scipy.linalg.solve_discrete_are

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.solve_discrete_are.html#scipy.linalg.solve_discrete_are

scipy.linalg.solve_discrete_are(a, b, q, r, e=None, s=None, balanced=True)

解离散时间代数 Riccati 方程(DARE)。

DARE 定义为

[A^HXA - X - (A^HXB) (R + B^HXB)^{-1} (B^HXA) + Q = 0]

存在解的限制条件是:

  • 所有 (A) 的特征值都在单位圆外,应该是可控的。
  • 相关的辛特征对(见注释),其特征值应远离单位圆。

此外,如果 es 都不精确为 None,则求解广义版本的 DARE

[A^HXA - E^HXE - (A^HXB+S) (R+B^HXB)^{-1} (B^HXA+S^H) + Q = 0]

被解决。当省略时,假定 e 为单位矩阵, s 为零矩阵。

参数:

a(M, M) 数组样式

方阵

b(M, N) 数组样式

输入

q(M, M) 数组样式

输入

r(N, N) 数组样式

方阵

e(M, M) 数组样式,可选

非奇异方阵

s(M, N) 数组样式,可选

输入

balanced布尔值

布尔值,指示是否在数据上执行平衡步骤。默认设置为 True。

返回:

x(M, M) ndarray

离散代数 Riccati 方程的解。

引发:

LinAlgError

对于无法隔离铅笔的稳定子空间的情况,请参见注释部分和详细的参考文献。

另请参阅

solve_continuous_are

解连续代数 Riccati 方程

注释

通过形成扩展辛矩阵对,求解方程 (H - \lambda J),如[1]所述,其中 (H - \lambda J)由块矩阵给出

[  A   0   B ]             [ E   0   B ]
[ -Q  E^H -S ] - \lambda * [ 0  A^H  0 ]
[ S^H  0   R ]             [ 0 -B^H  0 ] 

使用 QZ 分解方法。

在该算法中,失败条件与 (U_2 U_1^{-1}) 的对称性和 (U_1) 的条件数相关。这里,(U) 是一个 2m-by-m 矩阵,包含了稳定子空间的特征向量,具有 2-m 行,并分成两个 m 行的矩阵。详见[1][2]

为了提高 QZ 分解的精度,铅笔经历了一个平衡步骤,其中绝对值的和(去除对角线条目后)按照[3]给出的配方平衡。如果数据有小的数值噪声,平衡可能会放大它们的影响,需要进行一些清理。

新功能在版本 0.11.0 中引入。

参考文献

[1] (1,2)

P. van Dooren,“用于解决 Riccati 方程的广义特征值方法”,SIAM 科学与统计计算杂志,Vol.2(2),DOI:10.1137/0902010

[2]

A.J. Laub, “用于解决代数 Riccati 方程的 Schur 方法”, 麻省理工学院. 信息与决策系统实验室. LIDS-R ; 859. 在线提供 : hdl.handle.net/1721.1/1301

[3]

P. Benner, “Hamiltonian 矩阵的辛平衡”, 2001, SIAM J. Sci. Comput., 2001, Vol.22(5), DOI:10.1137/S1064827500367993

例子

给定 a, b, q, 和 r 求解 x:

>>> import numpy as np
>>> from scipy import linalg as la
>>> a = np.array([[0, 1], [0, -1]])
>>> b = np.array([[1, 0], [2, 1]])
>>> q = np.array([[-4, -4], [-4, 7]])
>>> r = np.array([[9, 3], [3, 1]])
>>> x = la.solve_discrete_are(a, b, q, r)
>>> x
array([[-4., -4.],
 [-4.,  7.]])
>>> R = la.solve(r + b.T.dot(x).dot(b), b.T.dot(x).dot(a))
>>> np.allclose(a.T.dot(x).dot(a) - x - a.T.dot(x).dot(b).dot(R), -q)
True 

scipy.linalg.solve_continuous_lyapunov

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.solve_continuous_lyapunov.html#scipy.linalg.solve_continuous_lyapunov

scipy.linalg.solve_continuous_lyapunov(a, q)

解决连续李亚普诺夫方程 (AX + XA^H = Q)。

使用巴特尔斯-斯图尔特算法找到 (X)。

参数:

aarray_like

方阵

qarray_like

右手边方阵

返回:

xndarray

连续李亚普诺夫方程的解

另请参阅

solve_discrete_lyapunov

计算离散时间李亚普诺夫方程的解

solve_sylvester

计算斯普尔斯特方程的解

注意

连续时间李亚普诺夫方程是斯普尔斯特方程的特殊形式,因此该解算器依赖于 LAPACK 例程 ?TRSYL。

新版本新增于 0.11.0。

示例

给定 aq 解出 x

>>> import numpy as np
>>> from scipy import linalg
>>> a = np.array([[-3, -2, 0], [-1, -1, 0], [0, -5, -1]])
>>> b = np.array([2, 4, -1])
>>> q = np.eye(3)
>>> x = linalg.solve_continuous_lyapunov(a, q)
>>> x
array([[ -0.75  ,   0.875 ,  -3.75  ],
 [  0.875 ,  -1.375 ,   5.3125],
 [ -3.75  ,   5.3125, -27.0625]])
>>> np.allclose(a.dot(x) + x.dot(a.T), q)
True 

scipy.linalg.solve_discrete_lyapunov

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

scipy.linalg.solve_discrete_lyapunov(a, q, method=None)

解决离散 Lyapunov 方程 (AXA^H - X + Q = 0)。

参数:

a, q(M, M) array_like

对应于上述方程的 A 和 Q 的方阵。必须具有相同的形状。

方法{‘direct’, ‘bilinear’},可选

求解器的类型。

如果未给出,则选择为 direct 如果 M 小于 10,否则为 bilinear

返回:

xndarray

离散 Lyapunov 方程的解

另见

solve_continuous_lyapunov

计算连续时间 Lyapunov 方程的解

注释

本节描述了可以通过 ‘method’ 参数选择的可用求解器。如果 M 小于 10,则默认方法为 direct,否则为 bilinear

方法 direct 使用直接的分析解来解离散 Lyapunov 方程。该算法在例如[1]中给出。然而,它要求线性解一个维度为 (M²) 的系统,因此即使对于中等大小的矩阵,性能也会迅速下降。

方法 bilinear 使用双线性变换将离散 Lyapunov 方程转换为连续 Lyapunov 方程 ((BX+XB'=-C)),其中 (B=(A-I)(A+I)^{-1}) 并且 (C=2(A' + I)^{-1} Q (A + I)^{-1})。连续方程可以有效地求解,因为它是 Sylvester 方程的特例。变换算法来自 Popov(1964),如[2]中描述。

自版本 0.11.0 新增。

参考文献

[1]

Hamilton, James D. Time Series Analysis, Princeton: Princeton University Press, 1994. 265. Print. doc1.lbfl.li/aca/FLMF037168.pdf

[2]

Gajic, Z., and M.T.J. Qureshi. 2008. Lyapunov Matrix Equation in System Stability and Control. Dover Books on Engineering Series. Dover Publications.

示例

给定 aq 求解 x

>>> import numpy as np
>>> from scipy import linalg
>>> a = np.array([[0.2, 0.5],[0.7, -0.9]])
>>> q = np.eye(2)
>>> x = linalg.solve_discrete_lyapunov(a, q)
>>> x
array([[ 0.70872893,  1.43518822],
 [ 1.43518822, -2.4266315 ]])
>>> np.allclose(a.dot(x).dot(a.T)-x, -q)
True 

scipy.linalg.clarkson_woodruff_transform

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

scipy.linalg.clarkson_woodruff_transform(input_matrix, sketch_size, seed=None)

应用 Clarkson-Woodruff 变换/草图到输入矩阵。

给定大小为 (n, d) 的输入矩阵 A,计算大小为 (sketch_size, d) 的矩阵 A',以便

[|Ax| \approx |A'x|]

通过 Clarkson-Woodruff 变换,通常称为 CountSketch 矩阵,以高概率。

参数:

input_matrixarray_like

输入矩阵,形状为 (n, d)

sketch_sizeint

草图的行数。

seed{None, int, numpy.random.Generator, numpy.random.RandomState}, 可选

如果 seed 是 None(或 np.random),则使用 numpy.random.RandomState 单例。如果 seed 是一个整数,则使用新的带有 seed 种子的 RandomState 实例。如果 seed 已经是 GeneratorRandomState 实例,则使用该实例。

返回:

**A’**array_like

对输入矩阵 A 的草图,大小为 (sketch_size, d)

注意事项

为了说明以下的结论

[|Ax| \approx |A'x|]

精确,观察以下的结果,它是从定理 14 的证明中适应的 [2] 通过马尔科夫不等式。如果我们有一个 sketch_size=k 的草图大小,它至少是

[k \geq \frac{2}{\epsilon²\delta}]

针对任意固定向量 x

[|Ax| = (1\pm\epsilon)|A'x|]

至少以概率1 - delta

此实现利用稀疏性:计算草图所需时间与 A.nnz 成正比。数据 Ascipy.sparse.csc_matrix 格式给出时,提供了稀疏输入的最快计算时间。

>>> import numpy as np
>>> from scipy import linalg
>>> from scipy import sparse
>>> rng = np.random.default_rng()
>>> n_rows, n_columns, density, sketch_n_rows = 15000, 100, 0.01, 200
>>> A = sparse.rand(n_rows, n_columns, density=density, format='csc')
>>> B = sparse.rand(n_rows, n_columns, density=density, format='csr')
>>> C = sparse.rand(n_rows, n_columns, density=density, format='coo')
>>> D = rng.standard_normal((n_rows, n_columns))
>>> SA = linalg.clarkson_woodruff_transform(A, sketch_n_rows) # fastest
>>> SB = linalg.clarkson_woodruff_transform(B, sketch_n_rows) # fast
>>> SC = linalg.clarkson_woodruff_transform(C, sketch_n_rows) # slower
>>> SD = linalg.clarkson_woodruff_transform(D, sketch_n_rows) # slowest 

也就是说,在稠密输入上,这种方法表现良好,只是相对来说速度较慢。

参考资料

[1]

Kenneth L. Clarkson 和 David P. Woodruff。在 STOC, 2013 中的低秩逼近与输入稀疏时间回归。

[2]

David P. Woodruff。作为数值线性代数工具的草图化。在 Foundations and Trends in Theoretical Computer Science, 2014 中。

示例

创建一个大的密集矩阵 A 作为例子:

>>> import numpy as np
>>> from scipy import linalg
>>> n_rows, n_columns  = 15000, 100
>>> rng = np.random.default_rng()
>>> A = rng.standard_normal((n_rows, n_columns)) 

应用变换来创建一个新的矩阵,其中有 200 行:

>>> sketch_n_rows = 200
>>> sketch = linalg.clarkson_woodruff_transform(A, sketch_n_rows, seed=rng)
>>> sketch.shape
(200, 100) 

现在以高概率,真实范数的绝对值接近于草图范数。

>>> linalg.norm(A)
1224.2812927123198
>>> linalg.norm(sketch)
1226.518328407333 

类似地,应用我们的草图保留了线性回归的解 (\min |Ax - b|)。

>>> b = rng.standard_normal(n_rows)
>>> x = linalg.lstsq(A, b)[0]
>>> Ab = np.hstack((A, b.reshape(-1, 1)))
>>> SAb = linalg.clarkson_woodruff_transform(Ab, sketch_n_rows, seed=rng)
>>> SA, Sb = SAb[:, :-1], SAb[:, -1]
>>> x_sketched = linalg.lstsq(SA, Sb)[0] 

就像矩阵范数示例一样,linalg.norm(A @ x - b) 与高概率接近于 linalg.norm(A @ x_sketched - b)

>>> linalg.norm(A @ x - b)
122.83242365433877
>>> linalg.norm(A @ x_sketched - b)
166.58473879945151 

scipy.linalg.block_diag

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

scipy.linalg.block_diag(*arrs)

从提供的数组创建块对角线矩阵。

给定输入的 A, BC,输出将在对角线上排列这些数组。

[[A, 0, 0],
 [0, B, 0],
 [0, 0, C]] 

参数:

A, B, C, … array_like,最多为二维

输入数组。长度为 n 的一维数组或类数组序列被视为形状为 (1,n) 的二维数组。

返回:

D ndarray

数组与 A, B, C, … 对角线上的元素。DA 具有相同的数据类型。

注意事项

如果所有输入数组都是方阵,则输出称为块对角线矩阵。

空序列(即大小为零的类数组)不会被忽略。值得注意的是,[][[]] 都被视为形状为 (1,0) 的矩阵。

示例

>>> import numpy as np
>>> from scipy.linalg import block_diag
>>> A = [[1, 0],
...      [0, 1]]
>>> B = [[3, 4, 5],
...      [6, 7, 8]]
>>> C = [[7]]
>>> P = np.zeros((2, 0), dtype='int32')
>>> block_diag(A, B, C)
array([[1, 0, 0, 0, 0, 0],
 [0, 1, 0, 0, 0, 0],
 [0, 0, 3, 4, 5, 0],
 [0, 0, 6, 7, 8, 0],
 [0, 0, 0, 0, 0, 7]])
>>> block_diag(A, P, B, C)
array([[1, 0, 0, 0, 0, 0],
 [0, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 3, 4, 5, 0],
 [0, 0, 6, 7, 8, 0],
 [0, 0, 0, 0, 0, 7]])
>>> block_diag(1.0, [2, 3], [[4, 5], [6, 7]])
array([[ 1.,  0.,  0.,  0.,  0.],
 [ 0.,  2.,  3.,  0.,  0.],
 [ 0.,  0.,  0.,  4.,  5.],
 [ 0.,  0.,  0.,  6.,  7.]]) 

scipy.linalg.circulant

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

scipy.linalg.circulant(c)

构造一个循环矩阵。

参数:

c(N,) array_like

1-D 数组,矩阵的第一列。

Returns:

A(N, N) ndarray

一个首列为 c 的循环矩阵。

参见

toeplitz

Toeplitz 矩阵

hankel

Hankel 矩阵

solve_circulant

解决循环系统。

注解

自版本 0.8.0 新增

示例

>>> from scipy.linalg import circulant
>>> circulant([1, 2, 3])
array([[1, 3, 2],
 [2, 1, 3],
 [3, 2, 1]]) 

scipy.linalg.companion

原文:docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.companion.html#scipy.linalg.companion

scipy.linalg.companion(a)

创建一个伴随矩阵。

创建与系数在 a 中给出的多项式相关联的伴随矩阵 [1]

Parameters:

a(N,) 数组类似

1-D 数组的多项式系数。a 的长度至少为两个,并且 a[0] 不能为零。

Returns:

c(N-1, N-1) 的 ndarray

c 的第一行是 -a[1:]/a[0],第一个次对角线全为 1。数组的数据类型与 1.0*a[0] 的数据类型相同。

Raises:

ValueError

如果以下任一条件为真:a) a.ndim != 1; b) a.size < 2; c) a[0] == 0

Notes

新版本 0.8.0 中引入。

References

[1]

R. A. Horn & C. R. Johnson,《矩阵分析》。英国剑桥:剑桥大学出版社,1999 年,第 146-7 页。

示例

>>> from scipy.linalg import companion
>>> companion([1, -10, 31, -30])
array([[ 10., -31.,  30.],
 [  1.,   0.,   0.],
 [  0.,   1.,   0.]]) 

scipy.linalg.convolution_matrix

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

scipy.linalg.convolution_matrix(a, n, mode='full')

构造一个卷积矩阵。

构造表示一维卷积的 Toeplitz 矩阵[1]。详细信息请参见下面的注释。

参数:

a(m,) array_like

要卷积的一维数组。

nint

结果矩阵中的列数。它给出要与 a 进行卷积的输入长度。这类似于 numpy.convolve(a, v)v 的长度。

modestr

这类似于 numpy.convolve(v, a, mode) 中的 mode。它必须是 (‘full’, ‘valid’, ‘same’) 之一。有关 mode 如何确定结果形状,请参见下文。

返回:

A(k, n) ndarray

卷积矩阵的行数 k 取决于 mode

=======  =========================
 mode    k
=======  =========================
'full'   m + n -1
'same'   max(m, n)
'valid'  max(m, n) - min(m, n) + 1
=======  ========================= 

另见

toeplitz

Toeplitz 矩阵

注释

代码:

A = convolution_matrix(a, n, mode) 

创建一个 Toeplitz 矩阵 A,使得 A @ v 等同于使用 convolve(a, v, mode)。返回的数组始终有 n 列。行数取决于上述指定的 mode

在默认的 ‘full’ 模式下,A 的条目如下:

A[i, j] == (a[i-j] if (0 <= (i-j) < m) else 0) 

其中 m = len(a)。例如,输入数组为 [x, y, z]。卷积矩阵的形式如下:

[x, 0, 0, ..., 0, 0]
[y, x, 0, ..., 0, 0]
[z, y, x, ..., 0, 0]
...
[0, 0, 0, ..., x, 0]
[0, 0, 0, ..., y, x]
[0, 0, 0, ..., z, y]
[0, 0, 0, ..., 0, z] 

在 ‘valid’ 模式下,A 的条目如下:

A[i, j] == (a[i-j+m-1] if (0 <= (i-j+m-1) < m) else 0) 

这对应于一个矩阵,其行是从 ‘full’ 情况中子集的行,其中 a 中的所有系数都包含在行中。对于输入 [x, y, z],此数组如下所示:

[z, y, x, 0, 0, ..., 0, 0, 0]
[0, z, y, x, 0, ..., 0, 0, 0]
[0, 0, z, y, x, ..., 0, 0, 0]
...
[0, 0, 0, 0, 0, ..., x, 0, 0]
[0, 0, 0, 0, 0, ..., y, x, 0]
[0, 0, 0, 0, 0, ..., z, y, x] 

在 ‘same’ 模式下,A 的条目如下:

d = (m - 1) // 2
A[i, j] == (a[i-j+d] if (0 <= (i-j+d) < m) else 0) 

“same” 模式的典型应用是当信号的长度为 n(其中 n 大于 len(a))时,所得输出为仍然长度为 n 的滤波信号。

对于输入 [x, y, z],此数组如下所示:

[y, x, 0, 0, ..., 0, 0, 0]
[z, y, x, 0, ..., 0, 0, 0]
[0, z, y, x, ..., 0, 0, 0]
[0, 0, z, y, ..., 0, 0, 0]
...
[0, 0, 0, 0, ..., y, x, 0]
[0, 0, 0, 0, ..., z, y, x]
[0, 0, 0, 0, ..., 0, z, y] 

新增于版本 1.5.0。

参考文献

[1]

“卷积”,en.wikipedia.org/wiki/Convolution

示例

>>> import numpy as np
>>> from scipy.linalg import convolution_matrix
>>> A = convolution_matrix([-1, 4, -2], 5, mode='same')
>>> A
array([[ 4, -1,  0,  0,  0],
 [-2,  4, -1,  0,  0],
 [ 0, -2,  4, -1,  0],
 [ 0,  0, -2,  4, -1],
 [ 0,  0,  0, -2,  4]]) 

与使用 numpy.convolve 进行乘法比较。

>>> x = np.array([1, 2, 0, -3, 0.5])
>>> A @ x
array([  2\. ,   6\. ,  -1\. , -12.5,   8\. ]) 

验证 A @ x 是否产生与应用卷积函数相同的结果。

>>> np.convolve([-1, 4, -2], x, mode='same')
array([  2\. ,   6\. ,  -1\. , -12.5,   8\. ]) 

作为 mode='same' 情况的比较,这里显示了相同系数和大小的 mode='full'mode='valid' 产生的矩阵。

>>> convolution_matrix([-1, 4, -2], 5, mode='full')
array([[-1,  0,  0,  0,  0],
 [ 4, -1,  0,  0,  0],
 [-2,  4, -1,  0,  0],
 [ 0, -2,  4, -1,  0],
 [ 0,  0, -2,  4, -1],
 [ 0,  0,  0, -2,  4],
 [ 0,  0,  0,  0, -2]]) 
>>> convolution_matrix([-1, 4, -2], 5, mode='valid')
array([[-2,  4, -1,  0,  0],
 [ 0, -2,  4, -1,  0],
 [ 0,  0, -2,  4, -1]])