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

FLiMESolve #2186

Open
wants to merge 90 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
b9a7b25
Version 5.0.0a1
hodgestar Feb 7, 2023
b51c6d0
Set version 5.0.0a1 in changelog.
hodgestar Feb 7, 2023
945bea9
Created flimesolve.py
magnamancer Mar 28, 2023
ee6ac8d
Added QuickSolve
magnamancer May 11, 2023
445cb41
Reconstructed R tensor, Made things more efficient
magnamancer May 13, 2023
d28f431
Fixed Basis Conversion in Rate Tensor Construction
magnamancer May 16, 2023
f86ef3a
Reworked FLiMESolve
magnamancer May 21, 2023
7ce7747
Experimental Stuff to rework FLiMESolv/er
magnamancer May 26, 2023
0152666
mode table in solver.run() generalized
magnamancer May 26, 2023
678bc69
Nyquist Constraint & E_ops
magnamancer Jun 15, 2023
b938432
Merge pull request #1 from magnamancer/Floquet-Beta
magnamancer Jun 15, 2023
8d4a5fb
Working
magnamancer Jun 26, 2023
c057aa0
Merge pull request #2 from magnamancer/Floquet-Beta
magnamancer Jun 26, 2023
31aff66
Added to documentation
magnamancer Jun 26, 2023
d4528bf
Merge branch 'qutip-5.0.X' of https://github.com/magnamancer/qutip in…
magnamancer Jun 26, 2023
e581f2f
Updated internal documentation
magnamancer Jun 26, 2023
bbe99cd
Update floquet.py
magnamancer Jun 26, 2023
6f55e6e
Deleted Working Scripts
magnamancer Jun 26, 2023
a186139
First pass at Fixing Code Issues
magnamancer Jun 27, 2023
e37df3b
Fixed small comment issue
magnamancer Jun 27, 2023
c7dec85
Merge pull request #3 from magnamancer/Fixing-Code-Format
magnamancer Jun 27, 2023
09b40eb
Update qutip/solver/correlation.py
magnamancer Jun 27, 2023
a73b12c
Update doc/guide/dynamics/dynamics-floquet.rst
magnamancer Jun 27, 2023
cf67e6b
Update qutip/solver/correlation.py
magnamancer Jun 27, 2023
e8ca4f3
Update doc/guide/scripts/floquet_ex3.py
magnamancer Jun 27, 2023
ed9b58e
PEP8 style formatting
magnamancer Jun 27, 2023
6401f33
Merge branch 'qutip-5.0.X' of https://github.com/magnamancer/qutip in…
magnamancer Jun 27, 2023
72ff3c9
Merge branch 'qutip-5.0.X'
magnamancer Jun 27, 2023
e3c0ec8
Merge branch 'qutip:master' into master
magnamancer Jun 27, 2023
b9e1f5d
CodeClimate Changes
magnamancer Jun 27, 2023
8cac396
Merge branch 'master' of https://github.com/magnamancer/qutip
magnamancer Jun 27, 2023
49967c1
Changed Towncrier Filename to new PR number
magnamancer Jun 27, 2023
3c7df72
Merge branch 'master' of https://github.com/magnamancer/qutip
magnamancer Jul 6, 2023
31f9564
Fixed Dimensions, Added tests
magnamancer Jul 6, 2023
83db869
Update flimesolve.py
magnamancer Jul 6, 2023
96ba98c
Reverted Some Changes
magnamancer Jul 6, 2023
fc48797
Merge branch 'master' of https://github.com/magnamancer/qutip
magnamancer Jul 6, 2023
ca52eb9
flimesolve small fix
magnamancer Jul 6, 2023
91c0e26
Update doc/guide/scripts/floquet_ex3.py
magnamancer Jul 11, 2023
3174af8
Update qutip/tests/solver/test_flimesolve.py
magnamancer Jul 11, 2023
90f03ec
Reduce Rate Matrix Build Speed
magnamancer Jul 22, 2023
a0dad1e
Rebuilt R(t) for loop - much faster
magnamancer Aug 11, 2023
d0e2a30
Format Update
magnamancer Aug 15, 2023
4082922
Fixed Simon's Comments
magnamancer Aug 28, 2023
5ecdd28
Updated Rate Matrix Build
magnamancer Sep 1, 2023
c256bf3
Fixed Fmodes Anti-Transpose Issue
magnamancer Sep 6, 2023
b84e6bd
Fixed Some Errors
magnamancer Nov 29, 2023
16c9d55
Update flimesolve.py
magnamancer Jan 3, 2024
31c78c5
Moved c_op_rates
magnamancer Jan 4, 2024
dc6906b
Fixed Abs Issue
magnamancer Jan 29, 2024
9f3d3ce
Updated flimesolve
magnamancer Feb 7, 2024
58492df
Update flimesolve.py
magnamancer Feb 22, 2024
d5ae8e3
Fixed FFTshift Issue(?)
magnamancer Feb 24, 2024
62e1d01
Fixed Transformation Issue
magnamancer Feb 28, 2024
00f39ad
Merging Master to Update
magnamancer Apr 1, 2024
d35128a
Fixing Issues
magnamancer Apr 1, 2024
c5c0ca7
c_ops update and options fix
magnamancer Apr 7, 2024
6af1c82
Update flimesolve.py
magnamancer Apr 7, 2024
5e7ebe3
bugfix Qobj typing
magnamancer Apr 7, 2024
c45e5df
Update correlation.py
magnamancer Apr 7, 2024
22cc595
Update test_flimesolve.py
magnamancer Apr 17, 2024
7fa1c16
Update tests.yml
magnamancer Apr 17, 2024
4e5a62c
Fixed Documentation Issue
magnamancer Apr 29, 2024
feda016
Update flimesolve.py
magnamancer Apr 29, 2024
3915cdb
Merge branch 'qutip:master' into master
magnamancer Apr 30, 2024
36ee12b
Update tests.yml
magnamancer Apr 30, 2024
1201c9d
Fixed Eric's Recent Comments
magnamancer Apr 30, 2024
3e8efe2
Merge branch 'master' of https://github.com/magnamancer/qutip
magnamancer Apr 30, 2024
bdf5e6e
Update flimesolve.py
magnamancer Apr 30, 2024
c09e4cd
Update doc/guide/dynamics/dynamics-floquet.rst
magnamancer Apr 30, 2024
de3f937
Update flimesolve.py
magnamancer Apr 30, 2024
6c4ec97
Merge branch 'master' of https://github.com/magnamancer/qutip
magnamancer Apr 30, 2024
7be6df2
Update __init__.py
magnamancer Apr 30, 2024
39aa803
Updated test_flimesolve
magnamancer May 2, 2024
69f64a9
Update flimesolve.py
magnamancer May 3, 2024
0fecc66
Update test_flimesolve.py
magnamancer May 3, 2024
d604e4a
FlimeSolve steady state solver
magnamancer May 4, 2024
d24adff
Updated Floquet Examples 4,5
magnamancer May 4, 2024
9aa533e
Update qutip/tests/solver/test_flimesolve.py
magnamancer May 4, 2024
821c381
Update qutip/tests/solver/test_flimesolve.py
magnamancer May 4, 2024
5fad71d
Update qutip/tests/solver/test_flimesolve.py
magnamancer May 4, 2024
4cf0adf
Update qutip/tests/solver/test_flimesolve.py
magnamancer May 4, 2024
09b67b9
Update qutip/tests/solver/test_flimesolve.py
magnamancer May 4, 2024
1216792
Update qutip/solver/flimesolve.py
magnamancer May 4, 2024
586c585
Update qutip/solver/flimesolve.py
magnamancer May 4, 2024
e84b4d6
Removed steady state solver
magnamancer May 6, 2024
4854091
Update test_flimesolve.py
magnamancer May 7, 2024
9db451b
Update flimesolve.py
magnamancer May 14, 2024
80cd2fa
Adding Back in the FFT
magnamancer May 20, 2024
20f17ab
Update flimesolve.py
magnamancer May 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.0.0.dev
5.0.0a1
1 change: 1 addition & 0 deletions doc/changes/2186.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added Floquet-Lindblad Master Equation for sinuisoidally driven time-dependent open system dynamics
35 changes: 26 additions & 9 deletions doc/guide/dynamics/dynamics-floquet.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Consider for example the case of a strongly driven two-level atom, described by
In QuTiP we can define this Hamiltonian as follows:

.. plot::
:context: reset
:context: close-figs

>>> delta = 0.2 * 2*np.pi
>>> eps0 = 1.0 * 2*np.pi
Expand All @@ -107,7 +107,7 @@ In QuTiP we can define this Hamiltonian as follows:
The :math:`t=0` Floquet modes corresponding to the Hamiltonian :eq:`eq_driven_qubit` can then be calculated using the :class:`qutip.FloquetBasis` class, which encapsulates the Floquet modes and the quasienergies:

.. plot::
:context: close-figs
:context:

>>> T = 2*np.pi / omega
>>> floquet_basis = FloquetBasis(H, T, args)
Expand All @@ -131,7 +131,7 @@ For certain driving amplitudes the quasienergy levels cross.
Since the quasienergies can be associated with the time-scale of the long-term dynamics due that the driving, degenerate quasienergies indicates a "freezing" of the dynamics (sometimes known as coherent destruction of tunneling).

.. plot::
:context: close-figs
:context:

>>> delta = 0.2 * 2 * np.pi
>>> eps0 = 0.0 * 2 * np.pi
Expand Down Expand Up @@ -175,7 +175,7 @@ The purpose of calculating the Floquet modes is to find the wavefunction solutio
To do that, we first need to decompose the initial state in the Floquet states, using the function :meth:`FloquetBasis.to_floquet_basis`

.. plot::
:context: close-figs
:context:

>>> psi0 = rand_ket(2)
>>> f_coeff = floquet_basis.to_floquet_basis(psi0)
Expand All @@ -186,7 +186,7 @@ To do that, we first need to decompose the initial state in the Floquet states,
and given this decomposition of the initial state in the Floquet states we can easily evaluate the wavefunction that is the solution to :eq:`eq_driven_qubit` at an arbitrary time :math:`t` using the function :meth:`FloquetBasis.from_floquet_basis`:

.. plot::
:context: close-figs
:context:

>>> t = 10 * np.random.rand()
>>> psi_t = floquet_basis.from_floquet_basis(f_coeff, t)
Expand Down Expand Up @@ -284,7 +284,24 @@ Finally, :func:`qutip.solver.floquet.fmmesolve` always expects the ``e_ops`` to
output = fmmesolve(H, psi0, tlist, [sigmax()], e_ops=[num(2)], spectra_cb=[noise_spectrum], T=T, args=args)
p_ex = output.expect[0]

.. plot::
:context: reset
:include-source: false
:nofigs:
The Floquet-Lindblad master equation in QuTiP
-------------------------------------------
The QuTiP function :func:`qutip.floquet.flimesolve` implements the Floquet-Lindblad master equation. It calculates the dynamics of a system given its initial state, a time-dependent Hamiltonian, a list of operators through which the system couples to its environment and a list of corresponding time-independent decay rates for the associated operators. Flimesolve is much like the :func:`qutip.mesolve` and :func:`qutip.mcsolve`, in how the system couples to the environment.

Flimesolve expects the collapse operators and rates to be provided as a list of [c_op, rate] pairs. For example:

.. code-block:: python

gamma1 = 0.1
c_ops_and_rates = [[sigmax(), gamma1]]

The other parameters are similar to the :func:`qutip.mesolve` and :func:`qutip.mcsolve`, and the same format for the return value is used :class:`qutip.solve.solver.Result`. The following example extends the example studied above, and uses :func:`qutip.floquet.flimesolve` to introduce dissipation into the calculation

.. plot:: guide/scripts/floquet_ex4.py
:width: 4.0in
:include-source:

Finally, :func:`qutip.solver.floquet.fmmesolve`, similar to :func:`qutip.solver.floquet.flimesolve`, always expects the ``e_ops`` to be specified in the laboratory basis:

magnamancer marked this conversation as resolved.
Show resolved Hide resolved
output = flimesolve(H, psi0, tlist, [[sigmax(),gamma1]], e_ops=[num(2)], T=T, args=args)
p_ex = output.expect[0]
1 change: 0 additions & 1 deletion doc/guide/scripts/floquet_ex3.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def noise_spectrum(omega):
# Alternatively
psi_t = output.states[idx]
p_ex[idx] = qutip.expect(qutip.num(2), psi_t)

magnamancer marked this conversation as resolved.
Show resolved Hide resolved
# For reference: calculate the same thing with mesolve
output = qutip.mesolve(H, psi0, tlist,
[np.sqrt(gamma1) * qutip.sigmax()], [qutip.num(2)],
Expand Down
53 changes: 53 additions & 0 deletions doc/guide/scripts/floquet_ex4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import numpy as np
from matplotlib import pyplot
import qutip

delta = 0.0 * 2 * np.pi
eps0 = 1.0 * 2 * np.pi
A = 0.25 * 2 * np.pi
omega = 1.0 * 2 * np.pi
T = 2 * np.pi / omega
tlist = np.linspace(0.0, 20 * T, 301)
psi0 = qutip.basis(2, 0)

H0 = - delta/2.0 * qutip.sigmax() - eps0/2.0 * qutip.sigmaz()
H1 = A/2.0 * qutip.sigmax()
args = {'w': omega}
H = [H0, [H1, lambda t, w: np.sin(w * t)]]

# collapse [operator, rate] pair
gamma1 = 0.1
c_op_and_rate = [[qutip.sigmax(), gamma1]]

# solve the floquet-markov master equation
output = qutip.flimesolve(
H, psi0, tlist,
c_ops_and_rates=[[qutip.sigmax(), gamma1]],
T=T,
args=args, options={"store_floquet_states": True}
)

# calculate expectation values in the computational basis
p_ex = np.zeros(tlist.shape, dtype=np.complex128)
for idx, t in enumerate(tlist):
f_coeff_t = output.floquet_states[idx]
psi_t = output.floquet_basis.from_floquet_basis(f_coeff_t, t)
# Alternatively
psi_t = output.states[idx]
p_ex[idx] = qutip.expect(qutip.num(2), psi_t)
Ericgig marked this conversation as resolved.
Show resolved Hide resolved

# For reference: calculate the same thing with mesolve
output = qutip.mesolve(H, psi0, tlist,
[np.sqrt(gamma1) * qutip.sigmax()], [qutip.num(2)],
args)
p_ex_ref = output.expect[0]


# plot the results
pyplot.plot(tlist, np.real(p_ex), 'r--', tlist, 1-np.real(p_ex), 'b--')
pyplot.plot(tlist, np.real(p_ex_ref), 'r', tlist, 1-np.real(p_ex_ref), 'b')
pyplot.xlabel('Time')
pyplot.ylabel('Occupation probability')
pyplot.legend(("Floquet $P_1$", "Floquet $P_0$",
"Lindblad $P_1$", "Lindblad $P_0$"))
pyplot.show()
25 changes: 21 additions & 4 deletions qutip/solver/correlation.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
Qobj, QobjEvo, liouvillian, spre, unstack_columns, stack_columns,
tensor, expect, qeye_like, isket
)
from .floquet import FloquetBasis
from .flimesolve import FLiMESolver
from .mesolve import MESolver
from .mcsolve import MCSolver
from .brmesolve import BRSolver
from .heom.bofin_solvers import HEOMSolver

from .steadystate import steadystate
from ..ui.progressbar import progress_bars

Expand Down Expand Up @@ -346,7 +347,8 @@ def coherence_function_g1(
n = solver.run(state0, taulist, e_ops=[a_op.dag() * a_op]).expect[0]

# calculate the correlation function G1 and normalize with n to obtain g1
G1 = correlation_3op(solver, state0, [0], taulist, None, a_op.dag(), a_op)[0]
G1 = correlation_3op(
solver, state0, [0], taulist, None, a_op.dag(), a_op)[0]
magnamancer marked this conversation as resolved.
Show resolved Hide resolved

g1 = G1 / np.sqrt(n[0] * np.array(n))[0]
return g1, G1
Expand Down Expand Up @@ -416,8 +418,23 @@ def coherence_function_g2(H, state0, taulist, c_ops, a_op, solver="me",


def _make_solver(H, c_ops, args, options, solver):
H = QobjEvo(H, args=args)
c_ops = [QobjEvo(c_op, args=args) for c_op in c_ops]
if solver == "fme":
if isinstance(H, FloquetBasis):
floquet_basis = H
else:
T = options['T']
# are for the open system evolution.
floquet_basis = FloquetBasis(H, T, args, precompute=None)
time_sense = options.get('time sense', 0.)
solver_instance = FLiMESolver(
floquet_basis,
c_ops,
args,
time_sense=time_sense
)
magnamancer marked this conversation as resolved.
Show resolved Hide resolved
else:
H = QobjEvo(H, args=args)
c_ops = [QobjEvo(c_op, args=args) for c_op in c_ops]
if solver == "me":
solver_instance = MESolver(H, c_ops, options=options)
elif solver == "es":
Expand Down