Search code examples
pythonnumpylinear-algebraeigenvalue

Suppress negligible complex numpy eigenvalues?


I am calculating the eigenvalues of a covariance matrix, which is real and symmetric positive semi-definite. Therefore, the eigenvalues and eigenvectors should all be real, however numpy.linalg.eig() is returning complex values with (almost) zero imaginary components.

The covariance matrix is too large to post here, but the eigenvalues come out as

[1.38174e01+00j, 9.00153e00+00j, ....]

with the largest imaginary component in the vector being negligible at -9.7557e-16j.

I think there is some machine precision issue here, as clearly the imaginary components are negligible (and given that my covariance matrix is real pos semi-def).

Is there a way to suppress returning the imaginary component using numpy eig (or scipy)? I'm trying to avoid an if statement that checks if the eigenvalue object is complex and then sets it to the real components only, if possible.


Solution

  • I think the best solution for this specific case is to use @PaulPanzer's suggestion, that is np.linalg.eigh. This works directly for Hermitian matrices, and thus will have only real Eigen values, exactly this specific use case.


    In general, to retrieve the real part of numbers in an array is as easy as:

    >>> np.real(np.array([1+1j,2+1j]))
    array([ 1.,  2.])
    

    numpy.real returns the real part of your numbers.