Skip to content
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

Faster dm norm in solvers #2408

Merged
merged 3 commits into from Apr 26, 2024
Merged

Conversation

Ericgig
Copy link
Member

@Ericgig Ericgig commented Apr 24, 2024

Description
The trace norm was used to normalized dm in mesolve and other open solvers.
This is computed as tr( sqrtm(op @ op.dag()) ) which is quite slow.
For density matrices, this is equivalent to the normal trace.
By using the trace, mesolve can be twice as fast.

Related issues or PRs
fix #2406

ps. While we check if the input is a dm to set the isherm flag, we don't check the liouvillian.
Since we accept any super-operator as Liouvillian, we could wrongly set the flag in some cases.

@coveralls
Copy link

coveralls commented Apr 24, 2024

Coverage Status

coverage: 86.08%. first build
when pulling 9e0279b on Ericgig:solver.faster_normalizations
into 12bf7f7 on qutip:master.

@@ -102,7 +102,10 @@ def _restore_state(self, data, *, copy=True):
state = Qobj(data, **self._state_metadata, copy=copy)

if data.shape[1] == 1 and self._options['normalize_output']:
state = state * (1 / state.norm())
if state._isherm:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is meant to check whether the state is a density matrix, yes? Surely there must be a better way if this doesn't always work. Also definitely worth a comment if the check remains a bit obscure.

@pmenczel
Copy link
Member

pmenczel commented Apr 25, 2024

Are there any use cases where the state is an operator and we want to use norm instead of tr? If no, we could just do isoper(state) instead of state._isherm.

As a side note, in cases with non-Hermitian "density matrices", it probably does not make much sense to normalize the output in any way. That is, I don't think it matters too much whether we use norm or tr in such a case, because probably neither is intended by the user... (But maybe there are some use cases I am not aware of?)

@Ericgig
Copy link
Member Author

Ericgig commented Apr 25, 2024

The only operator we normalise are density matrices, so isoper work as well. Propagator computation turn the normalisation off. Other cases should only happen when the user pass an arbitrary super operator. I which case they probably don't want any normalisation on our side.

My issue is that in these cases, we still set the isherm flag while not having any ideas what the user is trying to do:

>>> H = qt.qeye(2) * 1j
>>> L = qt.spre(H)
>>> qt.mesolve(L, qt.basis(2,1), [0, 1]).final_state
Quantum object: dims=[[2], [2]], shape=(2, 2), type='oper', dtype=Dense, isherm=True
Qobj data =
[[0.+0.j         0.+0.j        ]
 [0.+0.j         1.+1.55740849j]]

We don't set the flag when the input are super operators? We try to check if the Liouvillian preserve hermiticity (not easy for time dependant operator)? Junk in, junk out?

@pmenczel
Copy link
Member

My issue is that in these cases, we still set the isherm flag while not having any ideas what the user is trying to do:

We don't set the flag when the input are super operators? We try to check if the Liouvillian preserve hermiticity (not easy for time dependant operator)? Junk in, junk out?

A problem can also happen if the input is not a superoperator:

H = qt.sigmaz() + 1j * qt.sigmax()
initial = qt.ket2dm(qt.basis(2, 0))
qt.mesolve(H, initial, [0, 1], c_ops=[qt.sigmam()]).final_state
> Quantum object: dims=[[2], [2]], shape=(2, 2), type='oper', dtype=Dense, isherm=True
> Qobj data =
> [[ 0.51118445+0.j         -0.11358048+0.24945183j]
>  [ 0.11358048+0.24945183j  0.32517255+0.j        ]]

Copy link
Member

@pmenczel pmenczel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the isherm issue is separate from this PR. I created issue #2410 about that.

@Ericgig Ericgig merged commit f403c94 into qutip:master Apr 26, 2024
11 of 12 checks passed
@Ericgig Ericgig deleted the solver.faster_normalizations branch April 26, 2024 13:13
@Ericgig Ericgig mentioned this pull request May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Performance drop in QuTiP 5.0.1 vs QuTiP 4.7.6
4 participants