From 335796e58d7985be6a421af33f1f22fdcd7e0f2b Mon Sep 17 00:00:00 2001 From: Eric Giguere Date: Tue, 8 Oct 2024 13:47:22 -0400 Subject: [PATCH 1/3] Make using time dependent system in propagator easier --- qutip/solver/propagator.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/qutip/solver/propagator.py b/qutip/solver/propagator.py index 2abef1680d..93d1eeae60 100644 --- a/qutip/solver/propagator.py +++ b/qutip/solver/propagator.py @@ -48,7 +48,8 @@ def propagator( will always be the identity matrix. c_ops : list, optional - List of Qobj or QobjEvo collapse operators. + List of collapse operators as Qobj, QobjEvo or list that can be made + into QobjEvo. args : dictionary, optional Parameters to callback functions for time-dependent Hamiltonians and @@ -59,7 +60,9 @@ def propagator( **kwargs : Extra parameters to use when creating the - :obj:`.QobjEvo` from a list format ``H``. + :obj:`.QobjEvo` from a list format ``H``. The most common as ``tlist`` + and ``order`` for spline time dependance. See :obj:`.QobjEvo` for the + full list. Returns ------- @@ -67,6 +70,13 @@ def propagator( Instance representing the propagator(s) :math:`U(t)`. Return a single Qobj when ``t`` is a number or a list when ``t`` is a list. + Notes + ----- + Unlike :func:`.sesolve` or :func:`.mesolve`, the output times ``t`` are not + used for time dependent system with array based. ``tlist`` must be passed + as a keyword argument in those case. ``tlist`` and ``t`` can have different + length and values. + """ if isinstance(t, numbers.Real): tlist = [0, t] @@ -78,7 +88,10 @@ def propagator( if not isinstance(H, (Qobj, QobjEvo)): H = QobjEvo(H, args=args, **kwargs) - if c_ops: + if isinstance(c_ops, list): + c_ops = [QobjEvo(op, args=args, **kwargs) for op in c_ops)] + + if c_ops is not None: H = liouvillian(H, c_ops) U0 = qeye_like(H) From b790812b1981ea38d6075baf2cb27176e27ef2ff Mon Sep 17 00:00:00 2001 From: Eric Giguere Date: Tue, 8 Oct 2024 13:50:46 -0400 Subject: [PATCH 2/3] Add towncrier --- doc/changes/2532.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changes/2532.bugfix diff --git a/doc/changes/2532.bugfix b/doc/changes/2532.bugfix new file mode 100644 index 0000000000..3486819866 --- /dev/null +++ b/doc/changes/2532.bugfix @@ -0,0 +1 @@ +`propagator` now accepts list format `c_ops` like `mesolve` does. From e2cbddd0df45c3a04aa1a0b14f9f8f76d504ec6c Mon Sep 17 00:00:00 2001 From: Eric Giguere Date: Tue, 8 Oct 2024 14:09:18 -0400 Subject: [PATCH 3/3] Add a test --- qutip/solver/propagator.py | 16 ++++++++-------- qutip/tests/solver/test_propagator.py | 18 ++++++++++++++++-- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/qutip/solver/propagator.py b/qutip/solver/propagator.py index 93d1eeae60..f42dd279fd 100644 --- a/qutip/solver/propagator.py +++ b/qutip/solver/propagator.py @@ -60,9 +60,9 @@ def propagator( **kwargs : Extra parameters to use when creating the - :obj:`.QobjEvo` from a list format ``H``. The most common as ``tlist`` - and ``order`` for spline time dependance. See :obj:`.QobjEvo` for the - full list. + :obj:`.QobjEvo` from a list format ``H``. The most common are ``tlist`` + and ``order`` for array-based time dependance. See :obj:`.QobjEvo` for + the full list. Returns ------- @@ -72,9 +72,9 @@ def propagator( Notes ----- - Unlike :func:`.sesolve` or :func:`.mesolve`, the output times ``t`` are not - used for time dependent system with array based. ``tlist`` must be passed - as a keyword argument in those case. ``tlist`` and ``t`` can have different + Unlike :func:`.sesolve` or :func:`.mesolve`, the output times in ``t`` are + not used for array time dependent system. ``tlist`` must be passed as a + keyword argument in those case. ``tlist`` and ``t`` can have different length and values. """ @@ -89,9 +89,9 @@ def propagator( H = QobjEvo(H, args=args, **kwargs) if isinstance(c_ops, list): - c_ops = [QobjEvo(op, args=args, **kwargs) for op in c_ops)] + c_ops = [QobjEvo(op, args=args, **kwargs) for op in c_ops] - if c_ops is not None: + if c_ops: H = liouvillian(H, c_ops) U0 = qeye_like(H) diff --git a/qutip/tests/solver/test_propagator.py b/qutip/tests/solver/test_propagator.py index ffb335cbe3..0db507c2df 100644 --- a/qutip/tests/solver/test_propagator.py +++ b/qutip/tests/solver/test_propagator.py @@ -2,11 +2,11 @@ from scipy.integrate import trapezoid from qutip import (destroy, propagator, Propagator, propagator_steadystate, steadystate, tensor, qeye, basis, QobjEvo, sesolve, - liouvillian) + liouvillian, rand_dm) import qutip import pytest from qutip.solver.brmesolve import BRSolver -from qutip.solver.mesolve import MESolver +from qutip.solver.mesolve import MESolver, mesolve from qutip.solver.sesolve import SESolver from qutip.solver.mcsolve import MCSolver @@ -49,6 +49,20 @@ def testPropHOTd(): assert (U - U2).norm('max') < 1e-4 +def testPropHOTd(): + "Propagator: func array td format + open" + a = destroy(5) + H = a.dag()*a + ts = np.linspace(-0.01, 1.01, 103) + coeffs = np.cos(ts) + Htd = [H, [H, coeffs]] + rho_0 = rand_dm(5) + rho_1_prop = propagator(Htd, 1, c_ops=[a], tlist=ts)(rho_0) + rho_1_me = mesolve(QobjEvo(Htd, tlist=ts), rho_0, [0, 1], [a]).final_state + + assert (rho_1_prop - rho_1_me).norm('max') < 1e-4 + + def testPropObjTd(): a = destroy(5) H = a.dag()*a