svds(求解器=’arpack’)#

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)

使用 ARPACK 對稀疏矩陣進行部分奇異值分解。

計算稀疏矩陣 A 的最大或最小 k 個奇異值以及對應的奇異向量。傳回奇異值的順序不保證。

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

參數:
A稀疏矩陣或 LinearOperator

要分解的矩陣。

k整數, 可選

要計算的奇異值和奇異向量的數量。必須滿足 1 <= k <= min(M, N) - 1。預設值為 6。

ncv整數, 可選

生成的 Lanczos 向量的數量。預設值為 min(n, max(2*k + 1, 20))。如果指定,則必須滿足 k + 1 < ncv < min(M, N);建議 ncv > 2*k

tol浮點數, 可選

奇異值的容差。零(預設值)表示機器精度。

which{‘LM’, ‘SM’}

要尋找的 k 個奇異值:最大量值 (‘LM’) 或最小量值 (‘SM’) 奇異值。

v0ndarray, 可選

迭代的起始向量:如果 N > M,則為(近似)左奇異向量,否則為右奇異向量。長度必須為 min(M, N)。預設值:隨機

maxiter整數, 可選

允許的最大 Arnoldi 更新迭代次數;預設值為 min(M, N) * 10

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

奇異值總是會被計算並傳回;此參數控制奇異向量的計算和傳回。

  • True: 傳回奇異向量。

  • False: 不傳回奇異向量。

  • "u": 如果 M <= N,則僅計算左奇異向量,並為右奇異向量傳回 None。否則,計算所有奇異向量。

  • "vh": 如果 M > N,則僅計算右奇異向量,並為左奇異向量傳回 None。否則,計算所有奇異向量。

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

這是針對 solver='arpack' 的求解器特定文件。‘lobpcg’‘propack’ 也受到支援。

rngnumpy.random.Generator, 可選

偽隨機數生成器狀態。當 rng 為 None 時,將使用來自作業系統的熵建立新的 numpy.random.Generator。除了 numpy.random.Generator 之外的類型會傳遞至 numpy.random.default_rng 以實例化 Generator

options字典, 可選

求解器特定選項的字典。目前不支援任何求解器特定選項;此參數保留供未來使用。

傳回值:
undarray, shape=(M, k)

以左奇異向量作為列的 unitary 矩陣。

sndarray, shape=(k,)

奇異值。

vhndarray, shape=(k, N)

以右奇異向量作為列的 unitary 矩陣。

註解

這是一個樸素的實作,使用 ARPACK 作為 A.conj().T @ AA @ A.conj().T 上的特徵值求解器,具體取決於哪個效率更高。

範例

從奇異值和向量建構矩陣 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='arpack')
>>> A2 = u2 @ np.diag(s2) @ vT2
>>> np.allclose(A2, A.toarray(), atol=1e-3)
True

使用所有五個奇異值/向量,我們可以重現原始矩陣。

>>> u3, s3, vT3 = svds(A, k=5, solver='arpack')
>>> A3 = u3 @ np.diag(s3) @ vT3
>>> np.allclose(A3, A.toarray())
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