svds(solver=’propack’)#

scipy.sparse.linalg.svds(A, k=6, ncv=None, tol=0, which='LM', v0=None, maxiter=None, return_singular_vectors=True, solver='arpack', random_state=None, options=None)

使用 PROPACK 对稀疏矩阵进行部分奇异值分解。

计算稀疏矩阵 A 的最大或最小 k 个奇异值和相应的奇异向量。奇异值返回的顺序不保证。

在下面的描述中,令 M, N = A.shape

参数:
A稀疏矩阵或线性算子

要分解的矩阵。如果 A 是一个 LinearOperator 对象,它必须定义 matvecrmatvec 方法。

kint,默认值:6

要计算的奇异值和奇异向量的数量。必须满足 1 <= k <= min(M, N)

ncvint,可选

忽略。

tolfloat,可选

计算出的奇异值的期望相对精度。零(默认)表示机器精度。

which{‘LM’, ‘SM’}

要查找的 k 个奇异值:最大幅度 (‘LM’) 或最小幅度 (‘SM’) 奇异值。请注意,选择 which='SM' 将强制 irl 选项设置为 True

v0ndarray,可选

迭代的起始向量:必须为长度 A.shape[0]。如果未指定,PROPACK 将生成一个起始向量。

maxiterint,可选

最大迭代次数/Krylov 子空间的最大维度。默认值为 10 * k

return_singular_vectors{True, False, “u”, “vh”}

奇异值始终计算并返回;此参数控制奇异向量的计算和返回。

  • True:返回奇异向量。

  • False:不返回奇异向量。

  • "u":仅计算左奇异向量;返回 None 作为右奇异向量。

  • "vh":仅计算右奇异向量;返回 None 作为左奇异向量。

solver{‘arpack’, ‘propack’, ‘lobpcg’},可选

这是 solver='propack' 的特定于求解器的文档。 ‘arpack’‘lobpcg’ 也受支持。

random_state{None, int, numpy.random.Generator,

用于生成重采样的伪随机数生成器状态。

如果 random_stateNone(或 np.random),则使用 numpy.random.RandomState 单例。如果 random_state 为整数,则使用一个新的 RandomState 实例,并使用 random_state 对其进行种子设置。如果 random_state 已经是 GeneratorRandomState 实例,则使用该实例。

optionsdict,可选

一个包含特定于求解器的选项的字典。当前不支持特定于求解器的选项;此参数为将来使用保留。

返回:
undarray,形状为 (M, k)

将左奇异向量作为列的酉矩阵。

sndarray,形状为 (k,)

奇异值。

vhndarray,形状为 (k, N)

将右奇异向量作为行的酉矩阵。

注释

这是一个对 Fortran 库 PROPACK [1] 的接口。当前默认情况下,除非寻找最小的奇异值/向量 (which='SM'),否则将禁用 IRL 模式。

参考文献

[1]

Larsen, Rasmus Munk。“PROPACK - 用于大型稀疏 SVD 计算的软件。” 可在线获取。URL http://sun.stanford.edu/~rmunk/PROPACK (2004): 2008-2009。

示例

从奇异值和向量构造矩阵 A

>>> import numpy as np
>>> from scipy.stats import ortho_group
>>> from scipy.sparse import csc_matrix, diags
>>> from scipy.sparse.linalg import svds
>>> rng = np.random.default_rng()
>>> orthogonal = csc_matrix(ortho_group.rvs(10, random_state=rng))
>>> s = [0.0001, 0.001, 3, 4, 5]  # singular values
>>> u = orthogonal[:, :5]         # left singular vectors
>>> vT = orthogonal[:, 5:].T      # right singular vectors
>>> A = u @ diags(s) @ vT

仅使用三个奇异值/向量,SVD 近似于原始矩阵。

>>> u2, s2, vT2 = svds(A, k=3, solver='propack')
>>> A2 = u2 @ np.diag(s2) @ vT2
>>> np.allclose(A2, A.todense(), atol=1e-3)
True

使用所有五个奇异值/向量,我们可以重现原始矩阵。

>>> u3, s3, vT3 = svds(A, k=5, solver='propack')
>>> A3 = u3 @ np.diag(s3) @ vT3
>>> np.allclose(A3, A.todense())
True

奇异值与预期奇异值匹配,奇异向量与预期相同,除了符号不同。

>>> (np.allclose(s3, s) and
...  np.allclose(np.abs(u3), np.abs(u.toarray())) and
...  np.allclose(np.abs(vT3), np.abs(vT.toarray())))
True

奇异向量也是正交的。

>>> (np.allclose(u3.T @ u3, np.eye(5)) and
...  np.allclose(vT3 @ vT3.T, np.eye(5)))
True