快捷方式

torch.linalg.eigh

torch.linalg.eigh(A, UPLO='L', *, out=None)

計算複數 Hermitian 矩陣或實數對稱矩陣的特徵值分解。

K\mathbb{K}R\mathbb{R}C\mathbb{C},複數 Hermitian 矩陣或實數對稱矩陣 AKn×nA \in \mathbb{K}^{n \times n} 的**特徵值分解**定義為

A=Qdiag(Λ)QHQKn×n,ΛRnA = Q \operatorname{diag}(\Lambda) Q^{\text{H}}\mathrlap{\qquad Q \in \mathbb{K}^{n \times n}, \Lambda \in \mathbb{R}^n}

其中當 QQ 是複數時 QHQ^{\text{H}} 是共軛轉置,當 QQ 是實數時是轉置。在實數情況下 QQ 是正交的,在複數情況下是酉矩陣。

支援 float、double、cfloat 和 cdouble 資料型別的輸入。也支援批次矩陣輸入,如果 A 是一批矩陣,則輸出具有相同的批次維度。

假設 A 是 Hermitian (或對稱) 矩陣,但這在內部不進行檢查,而是

  • 如果 UPLO= ‘L’ (預設值),計算中僅使用矩陣的下三角部分。

  • 如果 UPLO= ‘U’,僅使用矩陣的上三角部分。

特徵值以升序返回。

注意

當輸入在 CUDA 裝置上時,此函式會將該裝置與 CPU 同步。

注意

實對稱矩陣或複數 Hermitian 矩陣的特徵值始終是實數。

警告

對稱矩陣的特徵向量不是唯一的,並且相對於 A 也不是連續的。由於缺乏唯一性,不同的硬體和軟體可能會計算出不同的特徵向量。

這種非唯一性是因為在實數情況下將特徵向量乘以 -1,或在複數情況下乘以 eiϕ,ϕRe^{i \phi}, \phi \in \mathbb{R},都會產生另一組有效的矩陣特徵向量。因此,損失函式不應依賴於特徵向量的相位,因為這個量沒有明確定義。計算此函式梯度時會檢查複數輸入。因此,當輸入是複數且在 CUDA 裝置上時,計算此函式梯度會將該裝置與 CPU 同步。

警告

使用 eigenvectors 張量計算的梯度僅在 A 具有不同特徵值時是有限的。此外,如果任意兩個特徵值之間的距離接近零,梯度將是數值不穩定的,因為它依賴於特徵值 λi\lambda_i,透過計算 1minijλiλj\frac{1}{\min_{i \neq j} \lambda_i - \lambda_j} 得到。

警告

如果在 CUDA 版本早於 12.1 update 1 的 CUDA 裝置上對大的病態矩陣輸入執行 eigh,使用者可能會遇到 PyTorch 崩潰。更多詳情請參閱線性代數數值穩定性。如果出現這種情況,使用者可以 (1) 調整矩陣輸入使其病態性降低,或者 (2) 使用 torch.backends.cuda.preferred_linalg_library() 嘗試其他支援的後端。

另請參見

torch.linalg.eigvalsh() 僅計算 Hermitian 矩陣的特徵值。與 torch.linalg.eigh() 不同,eigvalsh() 的梯度始終是數值穩定的。

對於 Hermitian 矩陣的不同分解,可使用 torch.linalg.cholesky()。Cholesky 分解提供的矩陣資訊較少,但計算速度比特徵值分解快得多。

對於不一定是 Hermitian 的方陣的特徵值分解,可使用(較慢的)函式 torch.linalg.eig()

對於任意形狀矩陣的更通用的 SVD 分解,可使用(較慢的)函式 torch.linalg.svd()

對於適用於一般矩陣的另一種(快得多的)分解,可使用 torch.linalg.qr()

引數
  • A (張量) – 形狀為 (*, n, n) 的張量,其中 * 表示零個或多個批次維度,包含對稱矩陣或 Hermitian 矩陣。

  • UPLO ('L', 'U', 可選) – 控制計算中使用 A 的上三角或下三角部分。預設值:‘L’

關鍵字引數

out (元組, 可選) – 由兩個張量組成的輸出元組。如果為 None 則忽略。預設值:None

返回

一個命名元組 (eigenvalues, eigenvectors),對應於上面提到的 Λ\LambdaQQ

eigenvalues 將始終是實數,即使 A 是複數。它也將以升序排列。

eigenvectors 將具有與 A 相同的資料型別,並且其列包含特徵向量。

示例:
>>> A = torch.randn(2, 2, dtype=torch.complex128)
>>> A = A + A.T.conj()  # creates a Hermitian matrix
>>> A
tensor([[2.9228+0.0000j, 0.2029-0.0862j],
        [0.2029+0.0862j, 0.3464+0.0000j]], dtype=torch.complex128)
>>> L, Q = torch.linalg.eigh(A)
>>> L
tensor([0.3277, 2.9415], dtype=torch.float64)
>>> Q
tensor([[-0.0846+-0.0000j, -0.9964+0.0000j],
        [ 0.9170+0.3898j, -0.0779-0.0331j]], dtype=torch.complex128)
>>> torch.dist(Q @ torch.diag(L.cdouble()) @ Q.T.conj(), A)
tensor(6.1062e-16, dtype=torch.float64)
>>> A = torch.randn(3, 2, 2, dtype=torch.float64)
>>> A = A + A.mT  # creates a batch of symmetric matrices
>>> L, Q = torch.linalg.eigh(A)
>>> torch.dist(Q @ torch.diag_embed(L) @ Q.mH, A)
tensor(1.5423e-15, dtype=torch.float64)

文件

獲取 PyTorch 的完整開發者文件

檢視文件

教程

獲取面向初學者和高階開發者的深度教程

檢視教程

資源

查詢開發資源並獲得解答

檢視資源