numpy.linalg.svd#
- linalg.svd(a, full_matrices=True, compute_uv=True, hermitian=False)[源代码]#
奇异值分解.
当 a 是一个二维数组,且
full_matrices=False时,它被分解为u @ np.diag(s) @ vh = (u * s) @ vh,其中 u 和 vh 的 Hermitian 转置是具有正交列的二维数组, s 是 a 的奇异值的一维数组.当 a 是更高维时,SVD以堆叠模式应用,如下面所述.- 参数:
- a(…, M, N) array_like
一个 real 或 complex 数组,带有
a.ndim >= 2.- full_matricesbool,可选
如果为 True (默认),则 u 和 vh 分别具有形状
(..., M, M)和(..., N, N).否则,形状分别为(..., M, K)和(..., K, N),其中K = min(M, N).- compute_uvbool,可选
是否计算 u 和 vh ,以及 s .默认为 True.
- hermitianbool,可选
如果为 True,则假定 a 是 Hermitian(如果为实值,则为对称矩阵),从而可以更有效地找到奇异值. 默认为 False.
- 返回:
- 当 compute_uv 为 True 时,结果是一个具有以下属性名称的 namedtuple:
- 属性名称:
- U{ (…, M, M), (…, M, K) } array
酉矩阵.第一个
a.ndim - 2维度的大小与输入 a 的大小相同.最后两个维度的大小取决于 full_matrices 的值.仅当 compute_uv 为 True 时返回.- S(…, K) array
包含奇异值的向量,每个向量都按降序排序.第一个
a.ndim - 2维度的大小与输入 a 的大小相同.- Vh{ (…, N, N), (…, K, N) } array
酉矩阵.第一个
a.ndim - 2维度的大小与输入 a 的大小相同.最后两个维度的大小取决于 full_matrices 的值.仅当 compute_uv 为 True 时返回.
- Raises:
- LinAlgError
如果 SVD 计算不收敛.
参见
scipy.linalg.svdSciPy 中的类似函数.
scipy.linalg.svdvals计算矩阵的奇异值.
注释
该分解使用 LAPACK 例程
_gesdd执行.SVD 通常描述为二维矩阵 \(A\) 的分解.更高维度的情况将在下面讨论.在二维情况下,SVD 写为 \(A = U S V^H\) ,其中 \(A = a\) , \(U= u\) , \(S= \mathtt{np.diag}(s)\) 和 \(V^H = vh\) .一维数组 s 包含 a 的奇异值, u 和 vh 是酉矩阵. vh 的行是 \(A^H A\) 的特征向量, u 的列是 \(A A^H\) 的特征向量.在这两种情况下,对应的(可能非零)特征值由
s2给出.如果 a 具有两个以上的维度,则应用广播规则,如 一次对多个矩阵进行线性代数运算 中所述.这意味着 SVD 以"堆叠"模式工作:它迭代第一个
a.ndim - 2维度的所有索引,并且对于每个组合,SVD 应用于最后两个索引.矩阵 a 可以从分解中重建,可以使用(u * s[..., None, :]) @ vh或u @ (s[..., None] * vh).(对于低于 3.5 的 python 版本,@运算符可以替换为函数np.matmul.)如果 a 是一个
matrix对象(而不是一个ndarray),那么所有的返回值也是.示例
>>> import numpy as np >>> rng = np.random.default_rng() >>> a = rng.normal(size=(9, 6)) + 1j*rng.normal(size=(9, 6)) >>> b = rng.normal(size=(2, 7, 8, 3)) + 1j*rng.normal(size=(2, 7, 8, 3))
基于完整 SVD 的重建,二维情形:
>>> U, S, Vh = np.linalg.svd(a, full_matrices=True) >>> U.shape, S.shape, Vh.shape ((9, 9), (6,), (6, 6)) >>> np.allclose(a, np.dot(U[:, :6] * S, Vh)) True >>> smat = np.zeros((9, 6), dtype=complex) >>> smat[:6, :6] = np.diag(S) >>> np.allclose(a, np.dot(U, np.dot(smat, Vh))) True
基于约简 SVD 的重建,二维情形:
>>> U, S, Vh = np.linalg.svd(a, full_matrices=False) >>> U.shape, S.shape, Vh.shape ((9, 6), (6,), (6, 6)) >>> np.allclose(a, np.dot(U * S, Vh)) True >>> smat = np.diag(S) >>> np.allclose(a, np.dot(U, np.dot(smat, Vh))) True
基于完整 SVD 的重建,四维情形:
>>> U, S, Vh = np.linalg.svd(b, full_matrices=True) >>> U.shape, S.shape, Vh.shape ((2, 7, 8, 8), (2, 7, 3), (2, 7, 3, 3)) >>> np.allclose(b, np.matmul(U[..., :3] * S[..., None, :], Vh)) True >>> np.allclose(b, np.matmul(U[..., :3], S[..., None] * Vh)) True
基于约简 SVD 的重建,四维情形:
>>> U, S, Vh = np.linalg.svd(b, full_matrices=False) >>> U.shape, S.shape, Vh.shape ((2, 7, 8, 3), (2, 7, 3), (2, 7, 3, 3)) >>> np.allclose(b, np.matmul(U * S[..., None, :], Vh)) True >>> np.allclose(b, np.matmul(U, S[..., None] * Vh)) True