Callback function form for c_ops in mesolve does not work
See original GitHub issueThis issue is on behalf of a post in the forums by Louis Fry who is trying to implement Lindblad operators which cannot be written in the form of a known f(t) * A
, because the operators are related to the instantaneous eigenstates of a time-dependent Hamiltonian.
The documentation in the docstring of mesolve
says that c_ops
may be a callback function of the signature f(t, args) -> Qobj
, similarly to the Hamiltonian. This is not the case, and as best as I can tell, has never been the case.
Basic reproduction (though the functionality is just completely missing, so this won’t ever succeed).
import qutip
def c_ops(t, args):
return qutip.create(3)
qutip.mesolve(qutip.num(3), qutip.basis(3, 1).proj(), [0, 1], c_ops)
History
- @jrjohansson originally wrote the docstring saying that
c_ops
could be a callback function in 2012 (pre-QuTiP 1.1.4) in commit 1bf006d4, although the code did not support it at this time - in issue #40 (2013), he commented that this functionality should be implemented, and this issue was closed without further action in 2018.
- in issue #223 (2014) there is some further discussion, but nothing is done until @Ericgig closes it in 2019, saying it is addressed by QuTiP 4.4.0 (the big swap to QobjEvo), but this doesn’t appear to be the case.
As of tag v4.4.0
, the code does not support it. The failing line of code would be https://github.com/qutip/qutip/blob/fc9d9915d0f6242587828ce716ff3cd444edf82a/qutip/mesolve.py#L227-L236
as a function type is truth-y but has no length, but the underlying problem is more just that there’s no support for it at all - there’s no check for callable(c_ops)
.
At the current master
at the time of writing (QuTiP ~4.5.1, 4102b99), we’re in the same place as at tag v4.4.0
.
Solution
In previous issues, people have been told to rewrite the Liouvillian in the supported form, however that’s not reasonably possible here. Technically it can be well-approximated by using an interpolation for each individual matrix element, as the time-dependent Hamiltonian can be solved ahead of time, but that’s not at all sensible.
Most pressingly, the documentation is currently wrong and should be changed to reflect reality. Secondly, we have to decide whether we’re going to implement this functionality at all, perhaps as a part of @Ericgig’s refactor of the solvers?
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (6 by maintainers)
Top GitHub Comments
Speaking of this, can we talk about the solver classes and what they’re aiming to do in the next call? I’ll write up some notes before then, but as I think about my plans more, the only sensible way forward always seems to involve completely unifying all
QobjEvo
types into one (and possibly even withQobj
itself), and that will invariably be affected by what you want to do with the solvers.I think it’s something that needs to be talked about and planned, because I think there’s two main ways to solve the issue of “we want the solvers to be as fast as possible”, and segregating the data layer is an orthogonal approach (which also permits speed-ups outside of the solvers) to solver classes which make their own choices about the data layer.
It’d be good to talk, so I know exactly what your plans and aims are, rather than me just making assumptions, though.
Trying
np.array
callback:It beats the
QobjEvo
for small arrays.Qobj
overhead is big and Qutip only use sparse matrix, Jake will be working on this during the summer.