torch.linalg.eigh¶
- torch.linalg.eigh(A, UPLO='L', *, out=None)¶
計算複數 Hermitian 矩陣或實數對稱矩陣的特徵值分解。
設 為 或 ,複數 Hermitian 矩陣或實數對稱矩陣 的**特徵值分解**定義為
其中當 是複數時 是共軛轉置,當 是實數時是轉置。在實數情況下 是正交的,在複數情況下是酉矩陣。
支援 float、double、cfloat 和 cdouble 資料型別的輸入。也支援批次矩陣輸入,如果
A是一批矩陣,則輸出具有相同的批次維度。假設
A是 Hermitian (或對稱) 矩陣,但這在內部不進行檢查,而是如果
UPLO= ‘L’ (預設值),計算中僅使用矩陣的下三角部分。如果
UPLO= ‘U’,僅使用矩陣的上三角部分。
特徵值以升序返回。
注意
當輸入在 CUDA 裝置上時,此函式會將該裝置與 CPU 同步。
注意
實對稱矩陣或複數 Hermitian 矩陣的特徵值始終是實數。
警告
對稱矩陣的特徵向量不是唯一的,並且相對於
A也不是連續的。由於缺乏唯一性,不同的硬體和軟體可能會計算出不同的特徵向量。這種非唯一性是因為在實數情況下將特徵向量乘以 -1,或在複數情況下乘以 ,都會產生另一組有效的矩陣特徵向量。因此,損失函式不應依賴於特徵向量的相位,因為這個量沒有明確定義。計算此函式梯度時會檢查複數輸入。因此,當輸入是複數且在 CUDA 裝置上時,計算此函式梯度會將該裝置與 CPU 同步。
警告
使用 eigenvectors 張量計算的梯度僅在
A具有不同特徵值時是有限的。此外,如果任意兩個特徵值之間的距離接近零,梯度將是數值不穩定的,因為它依賴於特徵值 ,透過計算 得到。警告
如果在 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),對應於上面提到的 和 。
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)