torch.linalg.eigh¶
- torch.linalg.eigh(A, UPLO='L', *, out=None)¶
計算複 Hermitian 或實對稱矩陣的特徵值分解。
令 為 或 , 複數 Hermitian 或實數對稱矩陣 的特徵值分解定義為
其中 在 為複數時是共軛轉置,在 為實數值時是轉置。 在實數情況下是正交的,在複數情況下是么正的。
支援 float、double、cfloat 和 cdouble 等 dtype 的輸入。 也支援矩陣批次處理,如果
A
是一批矩陣,則輸出具有相同的批次維度。假設
A
是 Hermitian (resp. symmetric),但內部不會檢查,而是如果
UPLO
= ‘L’ (預設),則計算中僅使用矩陣的下三角部分。如果
UPLO
= ‘U’,則僅使用矩陣的上三角部分。
特徵值以升序返回。
注意
當輸入位於 CUDA 裝置上時,此函數會將該裝置與 CPU 同步。
注意
實數對稱或複數 Hermitian 矩陣的特徵值始終為實數。
警告
對稱矩陣的特徵向量不是唯一的,也不會隨著
A
而連續變化。 由於這種缺乏唯一性,不同的硬體和軟體可能會計算出不同的特徵向量。這種非唯一性是由於在實數情況下,將特徵向量乘以 -1,或是在複數情況下,將其乘以 ,都會產生該矩陣的另一組有效的特徵向量。 因此,損失函數不應取決於特徵向量的相位,因為此數值未明確定義。 在計算此函數的梯度時,會針對複數輸入檢查此情況。 因此,當輸入為複數且位於 CUDA 裝置上時,此函數的梯度計算會將該裝置與 CPU 同步。
警告
只有當
A
具有不同的特徵值時,使用 eigenvectors 張量計算的梯度才會是有限的。 此外,如果任意兩個特徵值之間的距離接近於零,則梯度在數值上將不穩定,因為它取決於特徵值 ,透過計算 。警告
如果使用者在 CUDA 12.1 update 1 之前的 CUDA 裝置上,使用較大的病態矩陣作為輸入執行 eigh,可能會看到 pytorch 崩潰。 有關更多詳細信息,請參閱 線性代數數值穩定性。 如果是這種情況,使用者可以 (1) 調整其矩陣輸入,使其病態程度較低,或 (2) 使用
torch.backends.cuda.preferred_linalg_library()
嘗試其他支援的後端。另請參閱
torch.linalg.eigvalsh()
僅計算 Hermitian 矩陣的特徵值。 與torch.linalg.eigh()
不同,eigvalsh()
的梯度始終在數值上是穩定的。torch.linalg.cholesky()
用於 Hermitian 矩陣的不同分解。 Cholesky 分解提供的有關矩陣的訊息較少,但比特徵值分解的計算速度快得多。torch.linalg.eig()
用於計算不一定是 Hermitian 方陣的特徵值分解的(較慢)函數。torch.linalg.svd()
用於計算任何形狀矩陣的更通用的 SVD 分解的(較慢)函數。torch.linalg.qr()
用於另一種(速度快得多)適用於一般矩陣的分解。- 參數
A (Tensor) – 形狀為 (*, n, n) 的張量,其中 * 是由對稱或 Hermitian 矩陣組成的零個或多個批次維度。
UPLO ('L', 'U', optional) – 控制在計算中使用
A
的上三角還是下三角部分。 預設值:‘L’。
- 關鍵字引數
out ( tuple, optional) – 包含兩個 tensors 的輸出 tuple。如果為 None 則忽略。預設值:None。
- 回傳值
一個名為 (eigenvalues, eigenvectors) 的 named tuple,分別對應到上方的 與 。
eigenvalues 將永遠是實數值,即使
A
是複數。 並且會以遞增順序排列。eigenvectors 將會與
A
具有相同的 dtype,並且會將 eigenvectors 包含在其 columns 中。
- 範例:
>>> 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)