scipy.linalg.svdvals
原文:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.svdvals.html#scipy.linalg.svdvals
scipy.linalg.svdvals(a, overwrite_a=False, check_finite=True)
计算矩阵的奇异值。
参数:
a(M, N) 数组样式
要分解的矩阵。
overwrite_abool,可选
是否覆盖 a;可能会提高性能。默认为 False。
check_finitebool,可选
是否检查输入矩阵仅包含有限数值。禁用此选项可能提高性能,但如果输入包含无穷大或 NaN,可能会导致问题(崩溃、非终止)。
返回:
s(min(M, N),) ndarray
按降序排序的奇异值。
引发:
LinAlgError
如果 SVD 计算不收敛。
另请参阅
svd
计算矩阵的完全奇异值分解。
diagsvd
根据向量 s 构造 Sigma 矩阵。
注意
svdvals(a)
与 svd(a, compute_uv=False)
的唯一区别在于对空矩阵 a
的边缘情况处理,它返回一个空序列:
>>> import numpy as np
>>> a = np.empty((0, 2))
>>> from scipy.linalg import svdvals
>>> svdvals(a)
array([], dtype=float64)
示例
>>> import numpy as np
>>> from scipy.linalg import svdvals
>>> m = np.array([[1.0, 0.0],
... [2.0, 3.0],
... [1.0, 1.0],
... [0.0, 2.0],
... [1.0, 0.0]])
>>> svdvals(m)
array([ 4.28091555, 1.63516424])
我们可以通过计算 m 点乘平面 (x,y) 中所有单位向量 u 的最大长度来验证 m 的最大奇异值。我们用一个大样本近似“所有”单位向量。由于线性性质,我们只需考虑角度在 [0, pi] 内的单位向量。
>>> t = np.linspace(0, np.pi, 2000)
>>> u = np.array([np.cos(t), np.sin(t)])
>>> np.linalg.norm(m.dot(u), axis=0).max()
4.2809152422538475
p 是一个秩为 1 的投影矩阵。在精确算术中,它的奇异值将为 [1, 0, 0, 0]。
>>> v = np.array([0.1, 0.3, 0.9, 0.3])
>>> p = np.outer(v, v)
>>> svdvals(p)
array([ 1.00000000e+00, 2.02021698e-17, 1.56692500e-17,
8.15115104e-34])
正交矩阵的奇异值都为 1。在这里,我们通过使用 scipy.stats.ortho_group
的 rvs() 方法创建一个随机正交矩阵。
>>> from scipy.stats import ortho_group
>>> orth = ortho_group.rvs(4)
>>> svdvals(orth)
array([ 1., 1., 1., 1.])
scipy.linalg.diagsvd
原文链接:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.diagsvd.html#scipy.linalg.diagsvd
scipy.linalg.diagsvd(s, M, N)
从奇异值和大小 M、N 构造 SVD 中的 sigma 矩阵。
参数:
s(M,) 或 (N,) array_like
奇异值
M整数
矩阵其奇异值为s的大小。
N整数
矩阵其奇异值为s的大小。
返回:
S(M, N) ndarray
在奇异值分解中的 S 矩阵
另请参阅
矩阵的奇异值分解
计算矩阵的奇异值。
示例
>>> import numpy as np
>>> from scipy.linalg import diagsvd
>>> vals = np.array([1, 2, 3]) # The array representing the computed svd
>>> diagsvd(vals, 3, 4)
array([[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0]])
>>> diagsvd(vals, 4, 3)
array([[1, 0, 0],
[0, 2, 0],
[0, 0, 3],
[0, 0, 0]])
scipy.linalg.orth
原文:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.orth.html#scipy.linalg.orth
scipy.linalg.orth(A, rcond=None)
使用 SVD 构造 A 的范围的正交基
参数:
A(M, N) 类似数组
输入数组
rcond 浮点数,可选
相对条件数。奇异值s
小于rcond * max(s)
被视为零。默认值:浮点数 eps * max(M,N)。
返回:
Q(M, K) ndarray
A 的范围的正交基。K = 由 rcond 确定的 A 的有效秩
另请参见
svd
矩阵的奇异值分解
null_space
矩阵的零空间
示例
>>> import numpy as np
>>> from scipy.linalg import orth
>>> A = np.array([[2, 0, 0], [0, 5, 0]]) # rank 2 array
>>> orth(A)
array([[0., 1.],
[1., 0.]])
>>> orth(A.T)
array([[0., 1.],
[1., 0.],
[0., 0.]])
scipy.linalg.null_space
scipy.linalg.null_space(A, rcond=None)
使用 SVD 构造 A 的零空间的标准正交基
参数:
A(M, N) array_like
输入数组
rcondfloat, optional
相对条件数。比rcond * max(s)
小的奇异值s
被认为是零。默认值:浮点数 eps * max(M, N)。
返回:
Z(N, K) ndarray
A 的零空间的标准正交基。K = 有效零空间的维度,由 rcond 确定。
另请参阅
svd
矩阵的奇异值分解
orth
矩阵范围
示例
1-D 零空间:
>>> import numpy as np
>>> from scipy.linalg import null_space
>>> A = np.array([[1, 1], [1, 1]])
>>> ns = null_space(A)
>>> ns * np.copysign(1, ns[0,0]) # Remove the sign ambiguity of the vector
array([[ 0.70710678],
[-0.70710678]])
2-D 零空间:
>>> from numpy.random import default_rng
>>> rng = default_rng()
>>> B = rng.random((3, 5))
>>> Z = null_space(B)
>>> Z.shape
(5, 2)
>>> np.allclose(B.dot(Z), 0)
True
基向量是标准正交的(舍入误差):
>>> Z.T.dot(Z)
array([[ 1.00000000e+00, 6.92087741e-17],
[ 6.92087741e-17, 1.00000000e+00]])
scipy.linalg.ldl
原文:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.ldl.html#scipy.linalg.ldl
scipy.linalg.ldl(A, lower=True, hermitian=True, overwrite_a=False, check_finite=True)
计算对称/ Hermitian 矩阵的 LDLt 或 Bunch-Kaufman 分解。
此函数返回一个块对角矩阵 D,其中每个块的大小最多为 2x2,并且可能会返回一个可能排列的单位下三角矩阵 L
,使得分解 A = L D L^H
或 A = L D L^T
成立。如果 lower 为 False,则返回(再次可能排列的)上三角矩阵作为外因子。
排列数组可以通过行洗牌简单地将外因子三角化,即 lu[perm, :]
是一个上/下三角矩阵。这也等同于与置换矩阵 P
的乘积 P.dot(lu)
,其中 P
是列置换的单位矩阵 I[:, perm]
。
根据布尔值 lower 的值,仅引用输入数组的上三角或下三角部分。因此,输入一个三角矩阵会得到与提供完整矩阵相同的结果。
参数:
A:array_like
方阵输入数组
lower:bool, 可选
这会在因子分解的下三角或上三角外因子之间切换。下三角(lower=True
)是默认值。
hermitian:bool, 可选
对于复数数组,这会定义是否假设 A = A.conj().T
或 A = A.T
。对于实数数组,此切换无效。
overwrite_a:bool, 可选
允许重写 A 中的数据(可能会提升性能)。默认值为 False。
check_finite:bool, 可选
是否检查输入矩阵仅包含有限数。禁用可能会带来性能提升,但如果输入包含无穷大或 NaN,则可能导致问题(崩溃、非终止)。
返回:
lu:LU 分解后的数组
因子分解的(可能)排列的上/下三角外因子。
d:数组 d
因子分解的块对角乘积。
perm:数组 perm
将 lu 变为三角形形式的行置换索引数组。
异常:
值错误
如果输入数组不是方阵。
ComplexWarning
如果给定一个具有非零虚部对角线的复数数组,并且 hermitian 设置为 True。
另请参见
注意
该函数使用来自 LAPACK 的对称矩阵的 ?SYTRF
例程和 Hermitian 矩阵的 ?HETRF
例程。详见 [1] 获取算法细节。
根据 lower 关键字的值,只引用输入数组的下三角或上三角部分。此关键字还定义了因子分解的外因子的结构。
新版本 1.1.0 中引入。
参考文献
[1]
J.R. Bunch, L. Kaufman, 计算惯性和解决对称线性系统的一些稳定方法, Math. Comput. Vol.31, 1977. DOI:10.2307/2005787
Examples
给定一个代表带有其条目的完整对称数组的上三角数组 a
,获取 l
,d
和置换向量 perm:
>>> import numpy as np
>>> from scipy.linalg import ldl
>>> a = np.array([[2, -1, 3], [0, 2, 0], [0, 0, 1]])
>>> lu, d, perm = ldl(a, lower=0) # Use the upper part
>>> lu
array([[ 0\. , 0\. , 1\. ],
[ 0\. , 1\. , -0.5],
[ 1\. , 1\. , 1.5]])
>>> d
array([[-5\. , 0\. , 0\. ],
[ 0\. , 1.5, 0\. ],
[ 0\. , 0\. , 2\. ]])
>>> perm
array([2, 1, 0])
>>> lu[perm, :]
array([[ 1\. , 1\. , 1.5],
[ 0\. , 1\. , -0.5],
[ 0\. , 0\. , 1\. ]])
>>> lu.dot(d).dot(lu.T)
array([[ 2., -1., 3.],
[-1., 2., 0.],
[ 3., 0., 1.]])
scipy.linalg.cholesky
原文:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.cholesky.html#scipy.linalg.cholesky
scipy.linalg.cholesky(a, lower=False, overwrite_a=False, check_finite=True)
计算矩阵的乔列斯基分解。
返回埃尔米特正定矩阵 A 的乔列斯基分解,(A = L L^) 或 (A = U^ U)。
参数:
a(M, M) array_like
要分解的矩阵
lowerbool, 可选
是否计算上三角或下三角的乔列斯基分解。默认为上三角。
overwrite_abool, 可选
是否覆盖a中的数据(可能提高性能)。
check_finitebool, 可选
是否检查输入矩阵是否仅包含有限数。禁用可能提高性能,但如果输入确实包含无穷大或 NaN,则可能导致问题(崩溃、非终止)。
返回:
c(M, M) ndarray
a的上三角或下三角乔列斯基因子。
引发:
LinAlgError如果分解失败。
示例
>>> import numpy as np
>>> from scipy.linalg import cholesky
>>> a = np.array([[1,-2j],[2j,5]])
>>> L = cholesky(a, lower=True)
>>> L
array([[ 1.+0.j, 0.+0.j],
[ 0.+2.j, 1.+0.j]])
>>> L @ L.T.conj()
array([[ 1.+0.j, 0.-2.j],
[ 0.+2.j, 5.+0.j]])
scipy.linalg.cholesky_banded
scipy.linalg.cholesky_banded(ab, overwrite_ab=False, lower=False, check_finite=True)
Cholesky 分解一个带状 Hermitian 正定矩阵
矩阵 a 以 lower-diagonal 或 upper-diagonal 形式存储在 ab 中:
ab[u + i - j, j] == a[i,j] (if upper form; i <= j)
ab[ i - j, j] == a[i,j] (if lower form; i >= j)
ab 的示例(a 的形状为(6,6),u=2):
upper form:
* * a02 a13 a24 a35
* a01 a12 a23 a34 a45
a00 a11 a22 a33 a44 a55
lower form:
a00 a11 a22 a33 a44 a55
a10 a21 a32 a43 a54 *
a20 a31 a42 a53 * *
参数:
ab(u + 1, M) array_like
带状矩阵
overwrite_abbool, 可选
在 ab 中丢弃数据(可能增强性能)
lowerbool, 可选
矩阵是否以 lower 形式表示(默认为 upper 形式)
check_finitebool, 可选
是否检查输入矩阵仅包含有限数。禁用可能会提高性能,但如果输入确实包含无穷大或 NaN,可能会导致问题(崩溃、非终止)。
返回:
c(u + 1, M) ndarray
a 的 Cholesky 分解,与 ab 具有相同的带状格式
参见
cho_solve_banded
解决线性方程组,给定一个带状厄米特矩阵的 Cholesky 分解。
示例
>>> import numpy as np
>>> from scipy.linalg import cholesky_banded
>>> from numpy import allclose, zeros, diag
>>> Ab = np.array([[0, 0, 1j, 2, 3j], [0, -1, -2, 3, 4], [9, 8, 7, 6, 9]])
>>> A = np.diag(Ab[0,2:], k=2) + np.diag(Ab[1,1:], k=1)
>>> A = A + A.conj().T + np.diag(Ab[2, :])
>>> c = cholesky_banded(Ab)
>>> C = np.diag(c[0, 2:], k=2) + np.diag(c[1, 1:], k=1) + np.diag(c[2, :])
>>> np.allclose(C.conj().T @ C - A, np.zeros((5, 5)))
True
scipy.linalg.cho_factor
scipy.linalg.cho_factor(a, lower=False, overwrite_a=False, check_finite=True)
计算矩阵的 Cholesky 分解,以在 cho_solve
中使用
返回包含 Hermitian 正定矩阵 a 的 Cholesky 分解 A = L L*
或 A = U* U
的矩阵。返回值可以直接用作 cho_solve
的第一个参数。
警告
返回的矩阵还在未使用 Cholesky 分解的条目中包含随机数据。如果需要将这些条目清零,请改用函数 cholesky
。
参数:
a(M, M) 类似数组
要分解的矩阵
lower布尔值,可选
是否计算上三角或下三角的 Cholesky 分解(默认为:上三角)
overwrite_a布尔值,可选
是否覆盖数据(可能会提高性能)
check_finite布尔值,可选
是否检查输入矩阵只包含有限数字。禁用此选项可能会提高性能,但如果输入确实包含无穷大或 NaN,则可能会导致问题(崩溃、非终止)。
返回:
c(M, M) 数组
矩阵的上三角形或下三角形包含矩阵 a 的 Cholesky 因子。矩阵的其他部分包含随机数据。
lower布尔值
指示因子位于下三角形还是上三角形的标志
引发:
线性代数错误
如果分解失败,则引发错误。
另请参阅
cho_solve
使用矩阵的 Cholesky 分解解线性方程组。
示例
>>> import numpy as np
>>> from scipy.linalg import cho_factor
>>> A = np.array([[9, 3, 1, 5], [3, 7, 5, 1], [1, 5, 9, 2], [5, 1, 2, 6]])
>>> c, low = cho_factor(A)
>>> c
array([[3\. , 1\. , 0.33333333, 1.66666667],
[3\. , 2.44948974, 1.90515869, -0.27216553],
[1\. , 5\. , 2.29330749, 0.8559528 ],
[5\. , 1\. , 2\. , 1.55418563]])
>>> np.allclose(np.triu(c).T @ np. triu(c) - A, np.zeros((4, 4)))
True
scipy.linalg.cho_solve
scipy.linalg.cho_solve(c_and_lower, b, overwrite_b=False, check_finite=True)
解线性方程 A x = b,给定 A 的 Cholesky 分解。
参数:
**(c, lower)**元组,(数组,布尔值)
给定 cho_factor 给出的 a 的 Cholesky 分解
b数组
右侧
overwrite_b布尔值,可选
是否覆盖 b 中的数据(可能提高性能)
check_finite布尔值,可选
是否检查输入矩阵仅包含有限数值。禁用可能会提高性能,但如果输入包含无穷大或 NaN,则可能导致问题(崩溃、非终止)。
返回:
x数组
方程组 A x = b 的解
另见
cho_factor
矩阵 a 的 Cholesky 分解
示例
>>> import numpy as np
>>> from scipy.linalg import cho_factor, cho_solve
>>> A = np.array([[9, 3, 1, 5], [3, 7, 5, 1], [1, 5, 9, 2], [5, 1, 2, 6]])
>>> c, low = cho_factor(A)
>>> x = cho_solve((c, low), [1, 1, 1, 1])
>>> np.allclose(A @ x - [1, 1, 1, 1], np.zeros(4))
True
scipy.linalg.cho_solve_banded
scipy.linalg.cho_solve_banded(cb_and_lower, b, overwrite_b=False, check_finite=True)
解线性方程组A x = b
,给定带状 Hermitian 矩阵A
的 Cholesky 分解。
参数:
**(cb, lower)**元组,(ndarray, bool)
cb是由 cholesky_banded 给出的 A 的 Cholesky 分解。lower必须与传递给 cholesky_banded 的值相同。
b类数组
右侧向量
overwrite_b布尔值,可选
如果为 True,函数将覆盖b中的值。
check_finite布尔值,可选
是否检查输入矩阵仅包含有限数。禁用可能会提高性能,但如果输入包含无穷大或 NaN,可能会导致问题(崩溃、非终止)。
返回:
x数组
系统 A x = b 的解
另请参见
带状矩阵的 Cholesky 分解
注意事项
自 0.8.0 版本开始。
示例
>>> import numpy as np
>>> from scipy.linalg import cholesky_banded, cho_solve_banded
>>> Ab = np.array([[0, 0, 1j, 2, 3j], [0, -1, -2, 3, 4], [9, 8, 7, 6, 9]])
>>> A = np.diag(Ab[0,2:], k=2) + np.diag(Ab[1,1:], k=1)
>>> A = A + A.conj().T + np.diag(Ab[2, :])
>>> c = cholesky_banded(Ab)
>>> x = cho_solve_banded((c, False), np.ones(5))
>>> np.allclose(A @ x - np.ones(5), np.zeros(5))
True
scipy.linalg.polar
原文:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.polar.html#scipy.linalg.polar
scipy.linalg.polar(a, side='right')
计算极分解。
返回极分解的因子 [1] u 和 p,使得 a = up
(如果 side 是“right”)或 a = pu
(如果 side 是“left”),其中 p 是半正定矩阵。根据 a 的形状,u 的行或列正交。当 a 是方阵时,u 是方酉矩阵。当 a 不是方阵时,计算“标准极分解” [2]。
参数:
a(m, n) array_like
要分解的数组。
side{‘left’, ‘right’},可选
确定计算右极分解还是左极分解。如果 side 是“right”,那么 a = up
。如果 side 是“left”,那么 a = pu
。默认为“right”。
返回:
u(m, n) ndarray
如果 a 是方阵,则 u 是酉矩阵。如果 m > n,则 a 的列正交;如果 m < n,则 u 的行正交。
pndarray
p 是埃尔米特半正定矩阵。如果 a 非奇异,则 p 是正定的。p 的形状为 (n, n) 或 (m, m),具体取决于 side 是“right” 还是“left”。
参考文献
[1]
R. A. Horn 和 C. R. Johnson,《矩阵分析》,剑桥大学出版社,1985 年。
[2]
N. J. Higham,《矩阵函数:理论与计算》,SIAM,2008 年。
示例
>>> import numpy as np
>>> from scipy.linalg import polar
>>> a = np.array([[1, -1], [2, 4]])
>>> u, p = polar(a)
>>> u
array([[ 0.85749293, -0.51449576],
[ 0.51449576, 0.85749293]])
>>> p
array([[ 1.88648444, 1.2004901 ],
[ 1.2004901 , 3.94446746]])
一个非方阵示例,其中 m < n:
>>> b = np.array([[0.5, 1, 2], [1.5, 3, 4]])
>>> u, p = polar(b)
>>> u
array([[-0.21196618, -0.42393237, 0.88054056],
[ 0.39378971, 0.78757942, 0.4739708 ]])
>>> p
array([[ 0.48470147, 0.96940295, 1.15122648],
[ 0.96940295, 1.9388059 , 2.30245295],
[ 1.15122648, 2.30245295, 3.65696431]])
>>> u.dot(p) # Verify the decomposition.
array([[ 0.5, 1\. , 2\. ],
[ 1.5, 3\. , 4\. ]])
>>> u.dot(u.T) # The rows of u are orthonormal.
array([[ 1.00000000e+00, -2.07353665e-17],
[ -2.07353665e-17, 1.00000000e+00]])
另一个非方阵示例,其中 m > n:
>>> c = b.T
>>> u, p = polar(c)
>>> u
array([[-0.21196618, 0.39378971],
[-0.42393237, 0.78757942],
[ 0.88054056, 0.4739708 ]])
>>> p
array([[ 1.23116567, 1.93241587],
[ 1.93241587, 4.84930602]])
>>> u.dot(p) # Verify the decomposition.
array([[ 0.5, 1.5],
[ 1\. , 3\. ],
[ 2\. , 4\. ]])
>>> u.T.dot(u) # The columns of u are orthonormal.
array([[ 1.00000000e+00, -1.26363763e-16],
[ -1.26363763e-16, 1.00000000e+00]])
scipy.linalg.qr
原文链接:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.qr.html#scipy.linalg.qr
scipy.linalg.qr(a, overwrite_a=False, lwork=None, mode='full', pivoting=False, check_finite=True)
计算矩阵的 QR 分解。
计算分解A = Q R
,其中 Q 是单位矩阵/正交矩阵,R 是上三角矩阵。
参数:
a(M, N) array_like
要分解的矩阵
overwrite_abool,可选
如果overwrite_a设置为 True,重复使用现有输入数据结构而不是创建新的数据结构,可能会提高性能。
lworkint,可选
工作数组大小,lwork >= a.shape[1]
。如果为 None 或-1,则计算最佳大小。
mode{‘full’, ‘r’, ‘economic’, ‘raw’},可选
确定要返回的信息:返回 Q 和 R(‘full’,默认),仅返回 R(‘r’),或者返回经济型大小计算的 Q 和 R(‘economic’,详见备注)。最后一个选项’raw’(在 SciPy 0.11 中添加)使函数以 LAPACK 使用的内部格式返回两个矩阵(Q,TAU)。
pivotingbool,可选
是否应在用于排名显示 qr 分解的枢轴处理中包括枢轴。如果使用枢轴,则计算分解A P = Q R
,如上所述,但选择 P 使得 R 的对角线非递增。
check_finitebool,可选
是否检查输入矩阵仅包含有限数字。禁用可能会带来性能提升,但如果输入确实包含无穷大或 NaN,可能会导致问题(崩溃、非终止)。
返回:
Qfloat 或复数 ndarray
形状为(M, M)或者对于mode='economic'
为(M, K)的形状。如果mode='r'
,则不返回。如果mode='raw'
,则由元组(Q, TAU)
替代。
Rfloat 或复数 ndarray
形状为(M, N)或者对于mode in ['economic', 'raw']
为(K, N)。K = min(M, N)
。
Pint ndarray
对于pivoting=True
的形状为(N,)。如果pivoting=False
,则不返回。
引发:
LinAlgError
如果分解失败则引发
备注
这是 LAPACK 例程 dgeqrf、zgeqrf、dorgqr、zungqr、dgeqp3 和 zgeqp3 的接口。
如果mode=economic
,则 Q 和 R 的形状为(M, K)和(K, N),而不是(M,M)和(M,N),其中K=min(M,N)
。
示例
>>> import numpy as np
>>> from scipy import linalg
>>> rng = np.random.default_rng()
>>> a = rng.standard_normal((9, 6))
>>> q, r = linalg.qr(a)
>>> np.allclose(a, np.dot(q, r))
True
>>> q.shape, r.shape
((9, 9), (9, 6))
>>> r2 = linalg.qr(a, mode='r')
>>> np.allclose(r, r2)
True
>>> q3, r3 = linalg.qr(a, mode='economic')
>>> q3.shape, r3.shape
((9, 6), (6, 6))
>>> q4, r4, p4 = linalg.qr(a, pivoting=True)
>>> d = np.abs(np.diag(r4))
>>> np.all(d[1:] <= d[:-1])
True
>>> np.allclose(a[:, p4], np.dot(q4, r4))
True
>>> q4.shape, r4.shape, p4.shape
((9, 9), (9, 6), (6,))
>>> q5, r5, p5 = linalg.qr(a, mode='economic', pivoting=True)
>>> q5.shape, r5.shape, p5.shape
((9, 6), (6, 6), (6,))
scipy.linalg.qr_multiply
scipy.linalg.qr_multiply(a, c, mode='right', pivoting=False, conjugate=False, overwrite_a=False, overwrite_c=False)
计算 QR 分解并将 Q 与矩阵相乘。
计算分解A = Q R
,其中 Q 是单位/正交矩阵,R 是上三角矩阵。将 Q 与向量或矩阵 c 相乘。
参数:
a(M, N),array_like
输入数组
carray_like
要乘以q
的输入数组。
mode{‘left’, ‘right’},可选
如果 mode 为‘left’,则返回Q @ c
,如果 mode 为‘right’,则返回c @ Q
。如果 mode 为‘left’,则 c 的形状必须适合矩阵乘法,min(a.shape) == c.shape[0]
;如果 mode 为‘right’,则a.shape[0] == c.shape[1]
。
pivotingbool,可选
是否应在 rank-revealing qr 分解中包含枢轴。有关 qr 的文档,请参阅。
conjugatebool,可选
是否应复合 Q。这可能比显式复合更快。
overwrite_abool,可选
数据是否在 a 中覆盖(可能会提高性能)
overwrite_cbool,可选
数据是否被覆盖(可能会提高性能)。如果使用此选项,则 c 必须足够大以保存结果,即如果 mode 为‘left’,则c.shape[0]
=a.shape[0]
。
Returns:
CQndarray
Q
和c
的乘积。
R(K, N),ndarray
结果 QR 分解的 R 数组,其中K = min(M, N)
。
P(N,) ndarray
整数枢轴数组。仅当pivoting=True
时返回。
Raises:
LinAlgError
如果 QR 分解失败,则引发。
Notes
这是 LAPACK 例程?GEQRF
、?ORMQR
、?UNMQR
和?GEQP3
的接口。
版本 0.11.0 中的新功能。
Examples
>>> import numpy as np
>>> from scipy.linalg import qr_multiply, qr
>>> A = np.array([[1, 3, 3], [2, 3, 2], [2, 3, 3], [1, 3, 2]])
>>> qc, r1, piv1 = qr_multiply(A, 2*np.eye(4), pivoting=1)
>>> qc
array([[-1., 1., -1.],
[-1., -1., 1.],
[-1., -1., -1.],
[-1., 1., 1.]])
>>> r1
array([[-6., -3., -5\. ],
[ 0., -1., -1.11022302e-16],
[ 0., 0., -1\. ]])
>>> piv1
array([1, 0, 2], dtype=int32)
>>> q2, r2, piv2 = qr(A, mode='economic', pivoting=1)
>>> np.allclose(2*q2 - qc, np.zeros((4, 3)))
True
scipy.linalg.qr_update
scipy.linalg.qr_update(Q, R, u, v, overwrite_qruv=False, check_finite=True)
排名 k 的 QR 更新
如果A = Q R
是A
的 QR 分解,则返回A + u v**T
的 QR 分解(对于实数A
)或A + u v**H
的 QR 分解(对于复数A
)。
参数:
Q(M, M) 或 (M, N) 类似数组
QR 分解后的酉/正交矩阵。
R(M, N) 或 (N, N) 类似数组
QR 分解后的上三角矩阵。
u(M,) 或 (M, k) 类似数组
左侧更新向量
v(N,) 或 (N, k) 类似数组
右侧更新向量
overwrite_qruv bool,可选
如果为 True,在执行更新时尽可能消耗 Q、R、u 和 v,否则根据需要进行复制。默认为 False。
check_finite bool,可选
是否检查输入矩阵仅包含有限数字。禁用可能会提高性能,但如果输入确实包含无穷大或 NaN,可能会导致问题(崩溃、非终止)。默认为 True。
返回:
Q1 ndarray
更新后的酉/正交因子
R1 ndarray
更新后的上三角因子
另见
qr
, qr_multiply
, qr_delete
, qr_insert
注释
此例程不保证R1的对角线条目是实数或正数。
新版本 0.16.0 中新增。
参考文献
[1]
高卢布(G. H.)与范伦(C. F.)·卢恩,《矩阵计算》,第三版(约翰·霍普金斯大学出版社,1996 年)。
[2]
丹尼尔(J. W.)、格拉格(W. B.)、考夫曼(L.)与斯图尔特(G. W.),《重正交化和稳定算法用于更新格拉姆-施密特 QR 分解》,数学与计算 30,772-795 页(1976 年)。
[3]
莱切尔(L.)与格拉格(W. B.),《用于更新 QR 分解的 FORTRAN 子程序》,ACM 数学软件事务 16,369-377 页(1990 年)。
示例
>>> import numpy as np
>>> from scipy import linalg
>>> a = np.array([[ 3., -2., -2.],
... [ 6., -9., -3.],
... [ -3., 10., 1.],
... [ 6., -7., 4.],
... [ 7., 8., -6.]])
>>> q, r = linalg.qr(a)
鉴于此 QR 分解,执行一个排名 1 的更新。
>>> u = np.array([7., -2., 4., 3., 5.])
>>> v = np.array([1., 3., -5.])
>>> q_up, r_up = linalg.qr_update(q, r, u, v, False)
>>> q_up
array([[ 0.54073807, 0.18645997, 0.81707661, -0.02136616, 0.06902409], # may vary (signs)
[ 0.21629523, -0.63257324, 0.06567893, 0.34125904, -0.65749222],
[ 0.05407381, 0.64757787, -0.12781284, -0.20031219, -0.72198188],
[ 0.48666426, -0.30466718, -0.27487277, -0.77079214, 0.0256951 ],
[ 0.64888568, 0.23001 , -0.4859845 , 0.49883891, 0.20253783]])
>>> r_up
array([[ 18.49324201, 24.11691794, -44.98940746], # may vary (signs)
[ 0\. , 31.95894662, -27.40998201],
[ 0\. , 0\. , -9.25451794],
[ 0\. , 0\. , 0\. ],
[ 0\. , 0\. , 0\. ]])
更新等效,但比以下更快。
>>> a_up = a + np.outer(u, v)
>>> q_direct, r_direct = linalg.qr(a_up)
检查我们是否有等价结果:
>>> np.allclose(np.dot(q_up, r_up), a_up)
True
而更新后的 Q 仍然是酉的:
>>> np.allclose(np.dot(q_up.T, q_up), np.eye(5))
True
还可以更新经济(减少、薄)分解:
>>> qe, re = linalg.qr(a, mode='economic')
>>> qe_up, re_up = linalg.qr_update(qe, re, u, v, False)
>>> qe_up
array([[ 0.54073807, 0.18645997, 0.81707661], # may vary (signs)
[ 0.21629523, -0.63257324, 0.06567893],
[ 0.05407381, 0.64757787, -0.12781284],
[ 0.48666426, -0.30466718, -0.27487277],
[ 0.64888568, 0.23001 , -0.4859845 ]])
>>> re_up
array([[ 18.49324201, 24.11691794, -44.98940746], # may vary (signs)
[ 0\. , 31.95894662, -27.40998201],
[ 0\. , 0\. , -9.25451794]])
>>> np.allclose(np.dot(qe_up, re_up), a_up)
True
>>> np.allclose(np.dot(qe_up.T, qe_up), np.eye(3))
True
类似上述,执行一个二阶更新。
>>> u2 = np.array([[ 7., -1,],
... [-2., 4.],
... [ 4., 2.],
... [ 3., -6.],
... [ 5., 3.]])
>>> v2 = np.array([[ 1., 2.],
... [ 3., 4.],
... [-5., 2]])
>>> q_up2, r_up2 = linalg.qr_update(q, r, u2, v2, False)
>>> q_up2
array([[-0.33626508, -0.03477253, 0.61956287, -0.64352987, -0.29618884], # may vary (signs)
[-0.50439762, 0.58319694, -0.43010077, -0.33395279, 0.33008064],
[-0.21016568, -0.63123106, 0.0582249 , -0.13675572, 0.73163206],
[ 0.12609941, 0.49694436, 0.64590024, 0.31191919, 0.47187344],
[-0.75659643, -0.11517748, 0.10284903, 0.5986227 , -0.21299983]])
>>> r_up2
array([[-23.79075451, -41.1084062 , 24.71548348], # may vary (signs)
[ 0\. , -33.83931057, 11.02226551],
[ 0\. , 0\. , 48.91476811],
[ 0\. , 0\. , 0\. ],
[ 0\. , 0\. , 0\. ]])
这个更新也是A + U V**T
的有效 QR 分解。
>>> a_up2 = a + np.dot(u2, v2.T)
>>> np.allclose(a_up2, np.dot(q_up2, r_up2))
True
>>> np.allclose(np.dot(q_up2.T, q_up2), np.eye(5))
True
scipy.linalg.qr_delete
scipy.linalg.qr_delete(Q, R, k, int p=1, which=u'row', overwrite_qr=False, check_finite=True)
行或列删除的 QR 下降
如果A = Q R
是A
的 QR 分解,则返回A
的 QR 分解,其中从行或列k
开始删除p
行或列。
参数:
Q(M, M)或(M, N) array_like
来自 QR 分解的酉/正交矩阵。
R(M, N)或(N, N) array_like
来自 QR 分解的上三角矩阵。
kint
要删除的第一行或列的索引。
pint,可选
要删除的行或列数,默认为 1。
which: {‘row’, ‘col’},可选
确定将删除行或列,默认为‘行’
overwrite_qrbool,可选
如果为 True,消耗 Q 和 R,用它们的下降版本覆盖它们的内容,并返回适当大小的视图。默认为 False。
check_finitebool,可选
是否检查输入矩阵仅包含有限数。禁用可能会带来性能提升,但如果输入确实包含无穷大或 NaN,可能会导致问题(崩溃,非终止)。默认为 True。
返回:
Q1ndarray
更新后的酉/正交因子
R1ndarray
更新后的上三角因子
另见
qr
, qr_multiply
, qr_insert
, qr_update
注意事项
此例程不保证R1
的对角线条目为正。
新版本 0.16.0 中加入。
参考资料
[1]
Golub, G. H. & Van Loan, C. F. Matrix Computations, 3rd Ed. (Johns Hopkins University Press, 1996).
[2]
Daniel, J. W., Gragg, W. B., Kaufman, L. & Stewart, G. W. Reorthogonalization and stable algorithms for updating the Gram-Schmidt QR factorization. Math. Comput. 30, 772-795 (1976).
[3]
Reichel, L. & Gragg, W. B. Algorithm 686: FORTRAN Subroutines for Updating the QR Decomposition. ACM Trans. Math. Softw. 16, 369-377 (1990).
示例
>>> import numpy as np
>>> from scipy import linalg
>>> a = np.array([[ 3., -2., -2.],
... [ 6., -9., -3.],
... [ -3., 10., 1.],
... [ 6., -7., 4.],
... [ 7., 8., -6.]])
>>> q, r = linalg.qr(a)
给定这个 QR 分解,当移除 2 行时更新 q 和 r。
>>> q1, r1 = linalg.qr_delete(q, r, 2, 2, 'row', False)
>>> q1
array([[ 0.30942637, 0.15347579, 0.93845645], # may vary (signs)
[ 0.61885275, 0.71680171, -0.32127338],
[ 0.72199487, -0.68017681, -0.12681844]])
>>> r1
array([[ 9.69535971, -0.4125685 , -6.80738023], # may vary (signs)
[ 0\. , -12.19958144, 1.62370412],
[ 0\. , 0\. , -0.15218213]])
此更新与以下方法等效,但速度更快。
>>> a1 = np.delete(a, slice(2,4), 0)
>>> a1
array([[ 3., -2., -2.],
[ 6., -9., -3.],
[ 7., 8., -6.]])
>>> q_direct, r_direct = linalg.qr(a1)
检查我们是否有等效的结果:
>>> np.dot(q1, r1)
array([[ 3., -2., -2.],
[ 6., -9., -3.],
[ 7., 8., -6.]])
>>> np.allclose(np.dot(q1, r1), a1)
True
更新后的 Q 仍然是酉的:
>>> np.allclose(np.dot(q1.T, q1), np.eye(3))
True
scipy.linalg.qr_insert
scipy.linalg.qr_insert(Q, R, u, k, which='row', rcond=None, overwrite_qru=False, check_finite=True)
QR 更新行或列插入
如果A = Q R
是A
的 QR 分解,则返回在行或列从 k 开始插入的A
的 QR 分解。
参数:
Q(M, M) array_like
A
的 QR 分解的单位/正交矩阵。
R(M, N) array_like
A
的 QR 分解的上三角矩阵。
u(N,), (p, N), (M,), or (M, p) array_like
要插入的行或列
kint
要插入u之前的索引。
which: {‘row’, ‘col’}, optional
决定是否插入行或列,默认为’row’
rcondfloat
Q
增广为u/||u||
的倒数条件数的下限。仅在更新经济模式(薄,(M,N) (N,N))分解时使用。如果为 None,则使用机器精度。默认为 None。
overwrite_qrubool, optional
如果为 True,则在执行更新时尽可能消耗 Q、R 和 u,否则根据需要制作副本。默认为 False。
check_finitebool, optional
是否检查输入矩阵只包含有限数字。禁用可能会带来性能提升,但如果输入确实包含无穷大或 NaN,则可能会导致问题(崩溃,非终止)。默认为 True。
返回:
Q1ndarray
更新后的单位/正交因子
R1ndarray
更新后的上三角因子
Raises:
LinAlgError
如果更新(M,N) (N,N)分解,并且带有 u/||u||增广的 Q 的倒数条件数小于 rcond。
另请参阅
qr
, qr_multiply
, qr_delete
, qr_update
注释
此例程不保证R1
的对角线条目为正。
新版本 0.16.0 中添加。
参考文献
[1]
Golub, G. H. & Van Loan, C. F. Matrix Computations, 3rd Ed. (Johns Hopkins University Press, 1996).
[2]
Daniel, J. W., Gragg, W. B., Kaufman, L. & Stewart, G. W. Reorthogonalization and stable algorithms for updating the Gram-Schmidt QR factorization. Math. Comput. 30, 772-795 (1976).
[3]
Reichel, L. & Gragg, W. B. Algorithm 686: FORTRAN Subroutines for Updating the QR Decomposition. ACM Trans. Math. Softw. 16, 369-377 (1990).
示例
>>> import numpy as np
>>> from scipy import linalg
>>> a = np.array([[ 3., -2., -2.],
... [ 6., -7., 4.],
... [ 7., 8., -6.]])
>>> q, r = linalg.qr(a)
给定此 QR 分解,当插入 2 行时更新 q 和 r。
>>> u = np.array([[ 6., -9., -3.],
... [ -3., 10., 1.]])
>>> q1, r1 = linalg.qr_insert(q, r, u, 2, 'row')
>>> q1
array([[-0.25445668, 0.02246245, 0.18146236, -0.72798806, 0.60979671], # may vary (signs)
[-0.50891336, 0.23226178, -0.82836478, -0.02837033, -0.00828114],
[-0.50891336, 0.35715302, 0.38937158, 0.58110733, 0.35235345],
[ 0.25445668, -0.52202743, -0.32165498, 0.36263239, 0.65404509],
[-0.59373225, -0.73856549, 0.16065817, -0.0063658 , -0.27595554]])
>>> r1
array([[-11.78982612, 6.44623587, 3.81685018], # may vary (signs)
[ 0\. , -16.01393278, 3.72202865],
[ 0\. , 0\. , -6.13010256],
[ 0\. , 0\. , 0\. ],
[ 0\. , 0\. , 0\. ]])
更新相当于但比以下更快。
>>> a1 = np.insert(a, 2, u, 0)
>>> a1
array([[ 3., -2., -2.],
[ 6., -7., 4.],
[ 6., -9., -3.],
[ -3., 10., 1.],
[ 7., 8., -6.]])
>>> q_direct, r_direct = linalg.qr(a1)
检查我们是否有相同的结果:
>>> np.dot(q1, r1)
array([[ 3., -2., -2.],
[ 6., -7., 4.],
[ 6., -9., -3.],
[ -3., 10., 1.],
[ 7., 8., -6.]])
>>> np.allclose(np.dot(q1, r1), a1)
True
并且更新后的 Q 仍然是单位的:
>>> np.allclose(np.dot(q1.T, q1), np.eye(5))
True
scipy.linalg.rq
原文链接:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.rq.html#scipy.linalg.rq
scipy.linalg.rq(a, overwrite_a=False, lwork=None, mode='full', check_finite=True)
计算矩阵的 RQ 分解。
计算分解A = R Q
,其中 Q 是酉/正交的,R 是上三角形的。
参数:
a(M, N) 类似数组
要分解的矩阵
overwrite_a布尔型,可选
是否覆盖 a 中的数据(可能会提高性能)
lwork整型,可选
工作数组大小,lwork >= a.shape[1]。如果为 None 或-1,则计算一个最佳大小。
mode{‘full’,‘r’,‘economic’},可选
决定返回哪些信息:Q 和 R 都返回(‘full’,默认),只返回 R(‘r’),或者返回经济尺寸计算的 Q 和 R(‘economic’,参见注意事项)。
check_finite布尔型,可选
是否检查输入矩阵仅包含有限数。禁用可能会带来性能提升,但如果输入包含无穷大或 NaN,可能会导致问题(崩溃、非终止)。
返回:
R浮点数或复数的 ndarray
形状为(M, N)或(M, K),对于mode='economic'
,K = min(M, N)
。
Q浮点数或复数的 ndarray
形状为(N, N)或(K, N),对于mode='economic'
。如果mode='r'
,则不返回。
抛出:
LinAlgError
如果分解失败。
注意事项
这是 LAPACK 例程 sgerqf,dgerqf,cgerqf,zgerqf,sorgrq,dorgrq,cungrq 和 zungrq 的接口。
如果mode=economic
,则 Q 和 R 的形状为(K, N)和(M, K),而不是(N,N)和(M,N),其中K=min(M,N)
。
示例
>>> import numpy as np
>>> from scipy import linalg
>>> rng = np.random.default_rng()
>>> a = rng.standard_normal((6, 9))
>>> r, q = linalg.rq(a)
>>> np.allclose(a, r @ q)
True
>>> r.shape, q.shape
((6, 9), (9, 9))
>>> r2 = linalg.rq(a, mode='r')
>>> np.allclose(r, r2)
True
>>> r3, q3 = linalg.rq(a, mode='economic')
>>> r3.shape, q3.shape
((6, 6), (6, 9))
scipy.linalg.qz
原文:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.qz.html#scipy.linalg.qz
scipy.linalg.qz(A, B, output='real', lwork=None, sort=None, overwrite_a=False, overwrite_b=False, check_finite=True)
用于一对矩阵的广义特征值的 QZ 分解。
一对 n 乘 n 矩阵(A,B)的 QZ 或广义舒尔分解是:
(A,B) = (Q @ AA @ Z*, Q @ BB @ Z*)
如果 BB 是具有非负对角线的上三角形状,且 AA 是上三角形状,则 AA,BB 位于广义舒尔形式中;或者对于实 QZ 分解(output='real'
)块上三角形状,具有 1x1 和 2x2 块。在这种情况下,1x1 块对应于实广义特征值,而 2x2 块通过使 BB 的对应元素具有以下形式而‘标准化’:
[ a 0 ]
[ 0 b ]
并且 AA 和 BB 的对应的 2x2 块将具有一对复共轭的广义特征值。如果(output='complex'
)或 A 和 B 是复矩阵,则 Z’表示 Z 的共轭转置。Q 和 Z 是酉矩阵。
参数:
A(N, N) array_like
用于分解的二维数组
B(N, N) array_like
用于分解的二维数组
output{‘real’, ‘complex’},可选
构建实数或复数矩阵的 QZ 分解。默认为‘real’。
lworkint,可选
工作数组大小。如果为 None 或-1,则会自动计算。
sort{None, callable, ‘lhp’, ‘rhp’, ‘iuc’, ‘ouc’},可选
注意:此输入目前已禁用。请使用 ordqz 代替。
指定是否应对上层特征值进行排序。可以传递一个可调用函数,给定一个特征值,返回一个布尔值,表示是否应将特征值排序到左上角(True)。对于实矩阵对,排序函数接受三个实参数(alphar, alphai, beta)。特征值 x = (alphar + alphai*1j)/beta
。对于复矩阵对或者 output=’complex’,排序函数接受两个复参数(alpha, beta)。特征值 x = (alpha/beta)
。也可以使用字符串参数:
- ‘lhp’ 左平面(x.real < 0.0)
- ‘rhp’ 右平面(x.real > 0.0)
- ‘iuc’ 单位圆内部(x*x.conjugate() < 1.0)
- ‘ouc’ 单位圆外部(x*x.conjugate() > 1.0)
默认为 None(不排序)。
overwrite_abool,可选
是否覆盖 a 中的数据(可能提高性能)
overwrite_bbool,可选
是否覆盖 b 中的数据(可能提高性能)
check_finitebool,可选
如果为 true,则检查A和B的元素是否为有限数。如果为 false,则不进行检查并将矩阵传递给底层算法。
返回:
AA(N, N) ndarray
一般化的 A 的舒尔形式。
BB(N, N) ndarray
一般化的 B 的舒尔形式。
Q(N, N) ndarray
左舒尔向量。
Z(N, N) ndarray
右舒尔向量。
参见
ordqz
注释
Q 相对于 Matlab 中等效函数是转置的。
新版本 0.11.0 中的新增内容。
示例
>>> import numpy as np
>>> from scipy.linalg import qz
>>> A = np.array([[1, 2, -1], [5, 5, 5], [2, 4, -8]])
>>> B = np.array([[1, 1, -3], [3, 1, -1], [5, 6, -2]])
计算分解。QZ 分解不唯一,因此根据所使用的基础库不同,以下输出中系数的符号可能会有所不同。
>>> AA, BB, Q, Z = qz(A, B)
>>> AA
array([[-1.36949157, -4.05459025, 7.44389431],
[ 0\. , 7.65653432, 5.13476017],
[ 0\. , -0.65978437, 2.4186015 ]]) # may vary
>>> BB
array([[ 1.71890633, -1.64723705, -0.72696385],
[ 0\. , 8.6965692 , -0\. ],
[ 0\. , 0\. , 2.27446233]]) # may vary
>>> Q
array([[-0.37048362, 0.1903278 , 0.90912992],
[-0.90073232, 0.16534124, -0.40167593],
[ 0.22676676, 0.96769706, -0.11017818]]) # may vary
>>> Z
array([[-0.67660785, 0.63528924, -0.37230283],
[ 0.70243299, 0.70853819, -0.06753907],
[ 0.22088393, -0.30721526, -0.92565062]]) # may vary
验证 QZ 分解。对于实数输出,在以下表达式中我们只需要Z
的转置。
>>> Q @ AA @ Z.T # Should be A
array([[ 1., 2., -1.],
[ 5., 5., 5.],
[ 2., 4., -8.]])
>>> Q @ BB @ Z.T # Should be B
array([[ 1., 1., -3.],
[ 3., 1., -1.],
[ 5., 6., -2.]])
重复分解,但使用output='complex'
。
>>> AA, BB, Q, Z = qz(A, B, output='complex')
为了输出简洁,我们使用np.set_printoptions()
来将 NumPy 数组的输出精度设置为 3,并将微小值显示为 0。
>>> np.set_printoptions(precision=3, suppress=True)
>>> AA
array([[-1.369+0.j , 2.248+4.237j, 4.861-5.022j],
[ 0\. +0.j , 7.037+2.922j, 0.794+4.932j],
[ 0\. +0.j , 0\. +0.j , 2.655-1.103j]]) # may vary
>>> BB
array([[ 1.719+0.j , -1.115+1.j , -0.763-0.646j],
[ 0\. +0.j , 7.24 +0.j , -3.144+3.322j],
[ 0\. +0.j , 0\. +0.j , 2.732+0.j ]]) # may vary
>>> Q
array([[ 0.326+0.175j, -0.273-0.029j, -0.886-0.052j],
[ 0.794+0.426j, -0.093+0.134j, 0.402-0.02j ],
[-0.2 -0.107j, -0.816+0.482j, 0.151-0.167j]]) # may vary
>>> Z
array([[ 0.596+0.32j , -0.31 +0.414j, 0.393-0.347j],
[-0.619-0.332j, -0.479+0.314j, 0.154-0.393j],
[-0.195-0.104j, 0.576+0.27j , 0.715+0.187j]]) # may vary
对于复数数组,在以下表达式中我们必须使用Z.conj().T
来验证分解。
>>> Q @ AA @ Z.conj().T # Should be A
array([[ 1.-0.j, 2.-0.j, -1.-0.j],
[ 5.+0.j, 5.+0.j, 5.-0.j],
[ 2.+0.j, 4.+0.j, -8.+0.j]])
>>> Q @ BB @ Z.conj().T # Should be B
array([[ 1.+0.j, 1.+0.j, -3.+0.j],
[ 3.-0.j, 1.-0.j, -1.+0.j],
[ 5.+0.j, 6.+0.j, -2.+0.j]])
scipy.linalg.ordqz
原文:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.ordqz.html#scipy.linalg.ordqz
scipy.linalg.ordqz(A, B, sort='lhp', output='real', overwrite_a=False, overwrite_b=False, check_finite=True)
用于一对重新排序矩阵的 QZ 分解。
参数:
A(N, N) array_like
2-D 数组进行分解
B(N, N) array_like
2-D 数组进行分解
sort{callable,‘lhp’,‘rhp’,‘iuc’,‘ouc’},可选
指定是否应对上部特征值进行排序。可以传递一个可调用函数,给定一个有序对 (alpha, beta)
表示特征值 x = (alpha/beta)
,返回一个布尔值,表示是否应将特征值排序到左上角(True)。对于实矩阵对,beta 是实数,而 alpha 可以是复数;对于复杂矩阵对,alpha 和 beta 都可以是复数。该可调用函数必须能够接受一个 NumPy 数组。另外,也可以使用字符串参数:
- ‘lhp’ 左半平面(x.real < 0.0)
- ‘rhp’ 右半平面(x.real > 0.0)
- ‘iuc’ 单位圆内(x*x.conjugate() < 1.0)
- ‘ouc’ 单位圆外(x*x.conjugate() > 1.0)
使用预定义的排序函数,无穷特征值(即 alpha != 0
且 beta = 0
)被认为既不位于左半平面也不位于右半平面,但被认为位于单位圆外。对于特征值 (alpha, beta) = (0, 0)
,预定义的排序函数都返回 False。
outputstr {‘real’,‘complex’},可选
构造实数或复数 QZ 分解的真实矩阵。默认为 ‘real’。
overwrite_abool, optional
如果为真,则覆盖 A 的内容。
overwrite_bbool, optional
如果为真,则覆盖 B 的内容。
check_finitebool, optional
如果为真,则检查 A 和 B 的元素是否为有限数。如果为假,则不进行检查并将矩阵传递给底层算法。
返回:
AA(N, N) ndarray
A 的广义舒尔形式。
BB(N, N) ndarray
B 的广义舒尔形式。
alpha(N,) ndarray
alpha = alphar + alphai * 1j。请参阅备注。
beta(N,) ndarray
请参阅备注。
Q(N, N) ndarray
左舒尔向量。
Z(N, N) ndarray
右舒尔向量。
另请参阅
备注
在退出时,(ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N
,将是广义特征值。 ALPHAR(j) + ALPHAI(j)*i
和 BETA(j),j=1,...,N
是复杂舒尔形式(S,T)的对角线,如果实广义舒尔形式(A,B)的 2×2 对角块进一步通过复杂酉变换化为三角形式,则结果如此。如果 ALPHAI(j) 为零,则第 j 个特征值为实数;如果为正,则第 j
个和 (j+1)
个特征值为复共轭对,其中 ALPHAI(j+1)
为负数。
自版本 0.17.0 起新增。
示例
>>> import numpy as np
>>> from scipy.linalg import ordqz
>>> A = np.array([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]])
>>> B = np.array([[0, 6, 0, 0], [5, 0, 2, 1], [5, 2, 6, 6], [4, 7, 7, 7]])
>>> AA, BB, alpha, beta, Q, Z = ordqz(A, B, sort='lhp')
由于我们已对左半平面特征值进行了排序,负值首先出现
>>> (alpha/beta).real < 0
array([ True, True, False, False], dtype=bool)
scipy.linalg.schur
原文链接:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.schur.html#scipy.linalg.schur
scipy.linalg.schur(a, output='real', lwork=None, overwrite_a=False, sort=None, check_finite=True)
计算矩阵的舒尔分解。
舒尔分解为:
A = Z T Z^H
其中 Z 为酉,T 为上三角,或对于实舒尔分解(output=’real’),准上三角。在准三角形式中,描述复值特征值对的 2x2 块可能从对角线突出。
参数:
a(M, M) array_like
矩阵分解
output{‘real’, ‘complex’},可选
构造实数或复数舒尔分解(对于实矩阵)。
lwork整数,可选
工作数组大小。如果为 None 或-1,则会自动计算。
overwrite_a布尔值,可选
是否覆盖数据在(可能提高性能)。
sort{None, callable, ‘lhp’, ‘rhp’, ‘iuc’, ‘ouc’},可选
指定是否应对上特征值进行排序。可以传递一个可调用对象,给定一个特征值,返回一个布尔值,表示是否应将该特征值排序到左上角(True)。另外,也可以使用字符串参数:
'lhp' Left-hand plane (x.real < 0.0)
'rhp' Right-hand plane (x.real > 0.0)
'iuc' Inside the unit circle (x*x.conjugate() <= 1.0)
'ouc' Outside the unit circle (x*x.conjugate() > 1.0)
默认为 None(不排序)。
check_finite布尔值,可选
是否检查输入矩阵仅包含有限数。禁用可能会带来性能提升,但如果输入确实包含无穷大或 NaN,则可能会导致问题(崩溃、非终止)。
返回:
T(M, M) 数组
A 的舒尔形式。对于实数舒尔分解,它是实数值的。
Z(M, M) 数组
一个 A 的酉舒尔变换矩阵。对于实数舒尔分解,它是实数值的。
sdim整数
如果只有在请求排序时,第三个返回值才会包含满足排序条件的特征值数量。
引发:
线性代数错误
三种条件下引发的错误:
-
算法由于 QR 算法未能计算所有特征值而失败。
-
如果请求特征值排序,由于未能分离特征值而导致无法重新排序特征值,通常是因为条件不佳。
-
如果请求特征值排序,由于舍入误差导致主特征值不再满足排序条件。
另见
rsf2csf
将实数舒尔形式转换为复数舒尔形式
示例
>>> import numpy as np
>>> from scipy.linalg import schur, eigvals
>>> A = np.array([[0, 2, 2], [0, 1, 2], [1, 0, 1]])
>>> T, Z = schur(A)
>>> T
array([[ 2.65896708, 1.42440458, -1.92933439],
[ 0\. , -0.32948354, -0.49063704],
[ 0\. , 1.31178921, -0.32948354]])
>>> Z
array([[0.72711591, -0.60156188, 0.33079564],
[0.52839428, 0.79801892, 0.28976765],
[0.43829436, 0.03590414, -0.89811411]])
>>> T2, Z2 = schur(A, output='complex')
>>> T2
array([[ 2.65896708, -1.22839825+1.32378589j, 0.42590089+1.51937378j], # may vary
[ 0\. , -0.32948354+0.80225456j, -0.59877807+0.56192146j],
[ 0\. , 0\. , -0.32948354-0.80225456j]])
>>> eigvals(T2)
array([2.65896708, -0.32948354+0.80225456j, -0.32948354-0.80225456j])
一个任意的自定义特征值排序条件,具有正虚部,仅由一个特征值满足
>>> T3, Z3, sdim = schur(A, output='complex', sort=lambda x: x.imag > 0)
>>> sdim
1
scipy.linalg.rsf2csf
原文链接:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.linalg.rsf2csf.html#scipy.linalg.rsf2csf
scipy.linalg.rsf2csf(T, Z, check_finite=True)
将实 Schur 形式转换为复 Schur 形式。
将准对角的实值 Schur 形式转换为上三角形的复值 Schur 形式。
参数:
T(M, M) array_like
原始数组的实 Schur 形式
Z(M, M) array_like
Schur 变换矩阵
check_finitebool,可选
是否检查输入数组仅包含有限数。禁用可能会提高性能,但如果输入确实包含无穷大或 NaN,则可能会导致问题(崩溃、非终止)。
返回值:
T(M, M) ndarray
原始数组的复 Schur 形式
Z(M, M) ndarray
对应于复形式的 Schur 变换矩阵
参见
schur
数组的 Schur 分解
示例
>>> import numpy as np
>>> from scipy.linalg import schur, rsf2csf
>>> A = np.array([[0, 2, 2], [0, 1, 2], [1, 0, 1]])
>>> T, Z = schur(A)
>>> T
array([[ 2.65896708, 1.42440458, -1.92933439],
[ 0\. , -0.32948354, -0.49063704],
[ 0\. , 1.31178921, -0.32948354]])
>>> Z
array([[0.72711591, -0.60156188, 0.33079564],
[0.52839428, 0.79801892, 0.28976765],
[0.43829436, 0.03590414, -0.89811411]])
>>> T2 , Z2 = rsf2csf(T, Z)
>>> T2
array([[2.65896708+0.j, -1.64592781+0.743164187j, -1.21516887+1.00660462j],
[0.+0.j , -0.32948354+8.02254558e-01j, -0.82115218-2.77555756e-17j],
[0.+0.j , 0.+0.j, -0.32948354-0.802254558j]])
>>> Z2
array([[0.72711591+0.j, 0.28220393-0.31385693j, 0.51319638-0.17258824j],
[0.52839428+0.j, 0.24720268+0.41635578j, -0.68079517-0.15118243j],
[0.43829436+0.j, -0.76618703+0.01873251j, -0.03063006+0.46857912j]])