gftool.matrix.decompose_sym

gftool.matrix.decompose_sym(sym_mat, check=True) Decomposition[source]

Decompose symmetric matrix sym_mat into eigenvalues and (right) eigenvectors.

Decompose the sym_mat into rv, eig, rv_inv, with sym_mat = (rv * eig) @ rv_inv. This is the almost orthogonal similarity transformation:

\[M = O Λ O^T, Λ = diag(λ₀, λ₁, …)\]

where \(λₗ\) are the eigenvalues and \(U\) the unitary matrix of right eigenvectors returned as rv with \(O^{-1} ≈ O^T\). Internally, this is just a wrapper for numpy.linalg.eig. As mentioned the transformation is only almost orthogonal, so you should not rely on this fact! Still, decompose_sym should be better conditioned than decompose_mat so it is preferable (so slightly slower).

If you require orthogonality consider using [noble2017], it should also be faster.

Parameters:
sym_mat(…, N, N) complex np.ndarray

Matrix to be decomposed.

checkbool, optional

If check, raise an error if sym_mat is not symmetric (default: True).

Returns:
Decomposition.rv(…, N, N) complex np.ndarray

The right eigenvectors \(O\).

Decomposition.eig(…, N) complex np.ndarray

The complex eigenvalues of sym_mat.

Decomposition.rv_inv(…, N, N) complex np.ndarray

The inverse of the right eigenvectors \(O\).

Raises:
ValueError

If check=True and sym_mat is not symmetric.

References

[noble2017]

Noble, J.H., Lubasch, M., Stevens, J., Jentschura, U.D., 2017. Diagonalization of complex symmetric matrices: Generalized Householder reflections, iterative deflation and implicit shifts. Computer Physics Communications 221, 304–316. https://doi.org/10.1016/j.cpc.2017.06.014

Examples

Perform the eigendecomposition:

>>> matrix = np.random.random((10, 10)) + 1j*np.random.random((10, 10))
>>> sym_mat = 0.5*(matrix + matrix.T)
>>> rv, eig, rv_inv = gt.matrix.decompose_sym(sym_mat)
>>> np.allclose(sym_mat, (rv * eig) @ rv_inv)
True

The result should be almost orthogonal, but do not rely on it!

>>> np.allclose(np.linalg.inv(rv), rv.T)
True

This can also be simplified using the Decomposition class

>>> dec = gt.matrix.decompose_sym(sym_mat)
>>> np.allclose(sym_mat, dec.reconstruct())
True