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', rng=None, options=None)
使用 PROPACK 对稀疏矩阵进行部分奇异值分解。
计算稀疏矩阵 A 的最大或最小 k 个奇异值和对应的奇异向量。返回奇异值的顺序不保证。
在下面的描述中,设
M, N = A.shape
。- 参数:
- A稀疏矩阵或 LinearOperator
要分解的矩阵。如果 A 是一个
LinearOperator
对象,它必须定义matvec
和rmatvec
方法。- 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’},可选
- rng
numpy.random.Generator
,可选 伪随机数生成器状态。当 rng 为 None 时,会使用来自操作系统的熵创建一个新的
numpy.random.Generator
。除numpy.random.Generator
之外的类型将传递给numpy.random.default_rng
以实例化一个Generator
。- optionsdict,可选
特定于求解器的选项字典。当前不支持特定于求解器的选项;此参数保留供将来使用。
- 返回:
- undarray,形状=(M, k)
具有左奇异向量作为列的酉矩阵。
- sndarray,形状=(k,)
奇异值。
- vhndarray,形状=(k, N)
具有右奇异向量作为行的酉矩阵。
注释
这是 Fortran 库 PROPACK [1] 的接口。当前的默认设置是在禁用 IRL 模式的情况下运行,除非寻找最小的奇异值/向量 (
which='SM'
)。参考
[1]Larsen, Rasmus Munk。“用于大型稀疏 SVD 计算的 PROPACK 软件。” 在线提供。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_array, diags_array >>> from scipy.sparse.linalg import svds >>> rng = np.random.default_rng() >>> orthogonal = csc_array(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_array(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