torch.linalg.eigh#
- torch.linalg.eigh(A, UPLO='L', *, out=None)#
計算複共軛厄米特矩陣或實對稱矩陣的特徵值分解。
令 為 或 ,複共軛厄米特矩陣或實對稱矩陣 的**特徵值分解**定義為
其中,當 是複數時, 是共軛轉置;當 是實數時, 是轉置。 在實數情況下是正交的,在複數情況下是酉的。
支援浮點 (float)、雙精度浮點 (double)、複數浮點 (cfloat) 和複數雙精度浮點 (cdouble) 資料型別。還支援矩陣批處理,如果 `A` 是一個矩陣批處理,則輸出具有相同的批處理維度。
假定
A是厄米特(或對稱)的,但內部不進行檢查,而是如果
UPLO= ‘L’(預設),則計算中僅使用矩陣的下三角部分。如果
UPLO= ‘U’,則僅使用矩陣的上三角部分。
特徵值按升序返回。
注意
當輸入在 CUDA 裝置上時,此函式會使該裝置與 CPU 同步。
注意
實對稱或複共軛厄米特矩陣的特徵值始終是實數。
警告
對稱矩陣的特徵向量不是唯一的,也不是相對於
A連續的。由於這種不唯一性,不同的硬體和軟體可能會計算出不同的特徵向量。這種不唯一性是由以下事實引起的:在實數情況下將特徵向量乘以 -1,或在複數情況下乘以 會產生另一組有效的矩陣特徵向量。因此,損失函式不應依賴於特徵向量的相位,因為該量沒有明確定義。在計算此函式的梯度時,會對複數輸入進行檢查。因此,當輸入為複數且位於 CUDA 裝置上時,此函式的梯度計算會將該裝置與 CPU 同步。
警告
使用 eigenvectors 張量計算的梯度僅在
A具有不同特徵值時才是有限的。此外,如果任何兩個特徵值之間的距離接近零,梯度將變得數值不穩定,因為它取決於透過 的計算 得到的。警告
使用者可能會遇到 PyTorch 在使用 CUDA 版本早於 12.1 Update 1 的 CUDA 裝置上處理大型病態輸入矩陣時崩潰。更多詳細資訊請參閱 線性代數數值穩定性。如果發生這種情況,使用者可以(1)調整輸入矩陣使其病態程度降低,或者(2)使用
torch.backends.cuda.preferred_linalg_library()來嘗試其他支援的後端。另請參閱
torch.linalg.eigvalsh()僅計算厄米特矩陣的特徵值。與torch.linalg.eigh()不同,eigvalsh()的梯度始終是數值穩定的。torch.linalg.cholesky()用於厄米特矩陣的不同分解。Cholesky 分解比特徵值分解提供的資訊少,但計算速度快得多。torch.linalg.eig()用於(較慢的)計算非厄米特方陣特徵值分解的函式。torch.linalg.svd()用於(較慢的)計算任意形狀矩陣的更一般的 SVD 分解的函式。torch.linalg.qr()用於另一種(速度快得多)適用於通用矩陣的分解。- 引數
A (Tensor) – 形狀為 (*, n, n) 的張量,其中 * 是零個或多個批次維度,由對稱或埃爾米特矩陣組成。
UPLO (‘L’, ‘U’, optional) – 控制在計算中是使用
A的上三角部分還是下三角部分。預設值:‘L’。
- 關鍵字引數
out (tuple, optional) – 包含兩個張量的輸出元組。如果為 None 則忽略。預設為 None。
- 返回
一個命名元組 (eigenvalues, eigenvectors),對應於上面的 和 。
eigenvalues 始終是實數值,即使
A是複數。它們也將按升序排列。eigenvectors 的
A的dtype相同,並且將包含作為其列的特徵向量。
- 示例:
>>> 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)