I am using scipy.sparse.linalg.eigsh()
to find the first 10 smallest eigenvalues of a large, sparse and Hermitian matrix H. I'm finding the eigenvalues following the documentation
For which = ‘LM’ or ‘SA’:
If return_eigenvectors is True, eigenvalues are sorted by algebraic value.
If return_eigenvectors is False, eigenvalues are sorted by absolute value.
The eigenvalues I get for H
do not seem to be in any apparent order. For instance, if I am not returning eigenvectors
E1 = H.eigsh(k=10,which='SA',maxiter=1E4,return_eigenvectors=False)
gives
E1: [-5.8445426 -5.87106398 -5.87106398 -5.88635936 -6.37709649 -6.38166066 -6.39249619 -6.39249619 -6.39756682 -6.42135482]
If I am returning eigenvalues via
E2,V = H.eigsh(k=10,which='SA',maxiter=1E4,return_eigenvectors=True)
or equally
E2, V = H.eigsh(k=NEvals, which='SA')
I get,
E2: [-6.42135482 -6.39756682 -6.39249619 -6.38166066 -6.37709649 -6.39249619 -5.88635936 -5.87106398 -5.8445426 -5.87106398]
Questions
In E1
the eigenvalues are in ascending order. Why do I need to sort the eigenvalues again after I specified 'SA'
to get the smallest eigenvalue?
Why are the eigenvalues in E2
not in any order? Or better, what does it mean to sort by algebraic value? Do I need to sort the eigenvalues again or is there reason (perhaps to do with the complex eigenvectors) as to why they're in this order?
Finally, where I can learn about how (if at all) the eigenvectors affect the order of the eigenvalues? Any explanation with a physics application, where finding the ground state corresponds to the finding the lowest eigenvalue, is also appreciated.
I looked for documentation of eigsh.
I remember discussing this issue on github. The fact that the return order depends on eigenvector is surprising, there is no obvious reason for that, but at least it is documented. As of why exactly, this is how ARPACK works internally, I did not dig into it.
Now your case abides by the documentation. For case E1
with return_eigenvector=False
, you get abs(E1[i]) < abs(E1[i+1])
. For case E2
with return_eigenvector=True
, you have E2[i]) < E2[i+1])
. Both cases are sorted, but with a different sort depending on return_eigenvector
. The eigenvectors are sorted according to the eigenvalues. You can always sort them with a different conventions that suits you better:
E2, V = H.eigsh(k=NEvals, which='SA')
so = np.abs(E2).argsort()
E2 = E2[so]
V = V[:, so]
This is not related to the properties of the input matrix, just a convention in the function.