pytorch / 2 / generated / torch.linalg.eig.html

torch.linalg.eig

torch.linalg.eig(A, *, out=None)

Computes the eigenvalue decomposition of a square matrix if it exists.

Letting K \mathbb{K} be R \mathbb{R} or C \mathbb{C} , the eigenvalue decomposition of a square matrix A K n × n A \in \mathbb{K}^{n \times n} (if it exists) is defined as

A = V diag ( Λ ) V 1 V C n × n , Λ C n A = V \operatorname{diag}(\Lambda) V^{-1}\mathrlap{\qquad V \in \mathbb{C}^{n \times n}, \Lambda \in \mathbb{C}^n}

This decomposition exists if and only if A A is diagonalizable. This is the case when all its eigenvalues are different.

Supports input of float, double, cfloat and cdouble dtypes. Also supports batches of matrices, and if A is a batch of matrices then the output has the same batch dimensions.

Note

The eigenvalues and eigenvectors of a real matrix may be complex.

Note

When inputs are on a CUDA device, this function synchronizes that device with the CPU.

Warning

This function assumes that A is diagonalizable (for example, when all the eigenvalues are different). If it is not diagonalizable, the returned eigenvalues will be correct but A V diag ( Λ ) V 1 A \neq V \operatorname{diag}(\Lambda)V^{-1} .

Warning

The returned eigenvectors are normalized to have norm 1. Even then, the eigenvectors of a matrix are not unique, nor are they continuous with respect to A. Due to this lack of uniqueness, different hardware and software may compute different eigenvectors.

This non-uniqueness is caused by the fact that multiplying an eigenvector by by e i ϕ , ϕ R e^{i \phi}, \phi \in \mathbb{R} produces another set of valid eigenvectors of the matrix. For this reason, the loss function shall not depend on the phase of the eigenvectors, as this quantity is not well-defined. This is checked when computing the gradients of this function. As such, when inputs are on a CUDA device, this function synchronizes that device with the CPU when computing the gradients. This is checked when computing the gradients of this function. As such, when inputs are on a CUDA device, the computation of the gradients of this function synchronizes that device with the CPU.

Warning

Gradients computed using the eigenvectors tensor will only be finite when A has distinct eigenvalues. Furthermore, if the distance between any two eigenvalues is close to zero, the gradient will be numerically unstable, as it depends on the eigenvalues λ i \lambda_i through the computation of 1 min i j λ i λ j \frac{1}{\min_{i \neq j} \lambda_i - \lambda_j} .

See also

torch.linalg.eigvals() computes only the eigenvalues. Unlike torch.linalg.eig(), the gradients of eigvals() are always numerically stable.

torch.linalg.eigh() for a (faster) function that computes the eigenvalue decomposition for Hermitian and symmetric matrices.

torch.linalg.svd() for a function that computes another type of spectral decomposition that works on matrices of any shape.

torch.linalg.qr() for another (much faster) decomposition that works on matrices of any shape.

Parameters

A (Tensor) – tensor of shape (*, n, n) where * is zero or more batch dimensions consisting of diagonalizable matrices.

Keyword Arguments

out (tuple, optional) – output tuple of two tensors. Ignored if None. Default: None.

Returns

A named tuple (eigenvalues, eigenvectors) which corresponds to Λ \Lambda and V V above.

eigenvalues and eigenvectors will always be complex-valued, even when A is real. The eigenvectors will be given by the columns of eigenvectors.

Examples:

>>> A = torch.randn(2, 2, dtype=torch.complex128)
>>> A
tensor([[ 0.9828+0.3889j, -0.4617+0.3010j],
        [ 0.1662-0.7435j, -0.6139+0.0562j]], dtype=torch.complex128)
>>> L, V = torch.linalg.eig(A)
>>> L
tensor([ 1.1226+0.5738j, -0.7537-0.1286j], dtype=torch.complex128)
>>> V
tensor([[ 0.9218+0.0000j,  0.1882-0.2220j],
        [-0.0270-0.3867j,  0.9567+0.0000j]], dtype=torch.complex128)
>>> torch.dist(V @ torch.diag(L) @ torch.linalg.inv(V), A)
tensor(7.7119e-16, dtype=torch.float64)

>>> A = torch.randn(3, 2, 2, dtype=torch.float64)
>>> L, V = torch.linalg.eig(A)
>>> torch.dist(V @ torch.diag_embed(L) @ torch.linalg.inv(V), A)
tensor(3.2841e-16, dtype=torch.float64)

© 2024, PyTorch Contributors
PyTorch has a BSD-style license, as found in the LICENSE file.
https://pytorch.org/docs/2.1/generated/torch.linalg.eig.html