New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sparse Eigensolver issue. #1998
Comments
I see a similar issue with just calculating the eigenstates of a simple import qutip as q
import scipy
op = q.tensor(q.sigmax(), q.sigmax())
eigv_sp, eigs_sp = op.eigenstates(sparse=True)
eigv_full, eigs_full = op.eigenstates(sparse=False)
eigv_scipy, eigs_scipy = scipy.linalg.eigh(op.full())
print(eigv_sp, eigs_sp)
print(eigv_full, eigs_full)
print(eigv_scipy, eigs_scipy) The sparse=True gives eigenstates
whereas
|
Hi @pschindler, thanks for reporting this! Although the eigenenstates are different for both cases ( For the case that @Ericgig presented though, the eigenvalues are non-degenerated. I tracked down the issue and it is related to how we compute these eigenvalues. When we ask for all the eigenvalues what we actually do is to compute the smallest half in with one method ( If we include a small real component the bug completely disappears:
Because now there is a real part to use in the ordering. The behavior of We may want to extend the behavior of |
Hi @Ericgig Thank you for the clarification. You are right for the I stumbled upon weird behavior of import qutip as q
import scipy
max_n = 6
op = 0
for i in range(max_n - 1):
op += q.projection(max_n, i, i+1)
op += q.projection(max_n, max_n-1, 0)
eigv_sp, eigs_sp = op.eigenstates(sparse=True)
eigv_full, eigs_full = op.eigenstates(sparse=False)
eigv_scipy, eigs_scipy = scipy.linalg.eigh(op.full())
print(f"Sparse eigenvalues: {eigv_sp}")
print(f"Full eigenvalues: {eigv_full}")
print(f"Scipy eigenvalues: {eigv_scipy}") Here I get differing eigenvalues for the
|
Hi @pschindler, Indeed, the behavior you show is a bug in qutip 4.7.0. Thanks for reporting this! However, it is actually a bug in the
I am genuinely surprised that the I will try to find the source of the error but it seems very likely that we incorrectly label the operator as hermitian and hence uses the wrong method to find eigenvalues. |
Hi @AGaliciaMartinez . Good to hear from you again ;) It seems that the hermitian check for the operator qutip.cy.spmath.zcsr_isherm(op.data) == True |
Also, if I add import qutip as q
import scipy
max_n = 6
op = 0
for i in range(max_n - 1):
op += q.projection(max_n, i, i+1)
op += q.projection(max_n, max_n-1, 0)
op.isherm = False
eigv_sp, eigs_sp = op.eigenstates(sparse=True)
eigv_full, eigs_full = op.eigenstates(sparse=False)
eigv_scipy, eigs_scipy = scipy.linalg.eigh(op.full())
print(f"Sparse eigenvalues: {eigv_sp}")
print(f"Full eigenvalues: {eigv_full}")
print(f"Scipy eigenvalues: {eigv_scipy}") |
Hi! 😄
Yes, this is definitely the source of the error. Nice catch! I will try to compare the 4.7.1 version of qutip with the new pre lease of version 5.0.0 and see if we can provide a quick fix for it. |
This was solved in dev.major qutip#1866. Thanks Eric for pointing out the solution :).
Fixed in #2082, I believe. |
Nope, the original issue is not fixed. |
Hello @AGaliciaMartinez, |
I do not think it's a good first issue...
I would personally go for either 1.2 of 3. The place to start would be to debate on the solution. If you have some opinion on the matter, please let us know. |
5 seems also fine for me. We default to the dense solver when all the eigenvalues are required, even if 1 and 4 seem indeed too much work right now (but perhaps they can be tackled in the future). 2 may actually be separate an enhacement, that could be useful for some specific scenarios (?). But maybe it is best to wait for when this scenario is present to actually motivate the enhancement (?). |
By (3), I meant removing the csr specialisation from the dispatched function and call the function directly when not all values are desired. When Yes (2) can be seen as separate enhancement. For me (5) was purely documentation, a warning is fine, but when (3) would also mean removing the
since they are no longer used ( |
Bug Description
The sparse eigensolver can fail when eigenvalues are purely imaginary.
Code to Reproduce the Bug
import qutip (qutip.num(4) * 1j).eigenenergies(sparse=True)
Code Output
Expected Behaviour
All unique eigenstates should be returned.
Your Environment
Additional Context
No response
The text was updated successfully, but these errors were encountered: