Authors: C. Staufenbiel, 2022
following the instructions in the Bloch-Redfield documentation.
This notebook introduces the usage of time-dependent operators in the Bloch-Redfield solver, which is also described in the corresponding documentation.
We will discuss time-dependent Hamiltonians and time-dependent dissipations. The Bloch-Redfield solver is especially efficient since it uses Cython internally. For correct functioning we have to pass the time dependence in a string-based format.
import numpy as np
from qutip import about, basis, brmesolve, destroy, plot_expectation_values
%matplotlib inline
For our small example, we setup a system with N
states and the number operator as Hamiltonian. We can observe that for the constant Hamiltonian and no given a_ops
the expectation value $\langle n \rangle $ is a constant.
# num modes
N = 2
# Hamiltonian
a = destroy(N)
H = a.dag() * a
# initial state
psi0 = basis(N, N - 1)
# times for simulation
times = np.linspace(0, 10, 100)
# solve using brmesolve
result_const = brmesolve(H, psi0, times, e_ops=[a.dag() * a])
plot_expectation_values(result_const, ylabels=["<n>"]);
Next we define a string, which describes some time-dependence. We can use functions that are supported by the Cython implementation. A list of all supported functions can be found in the docs. For example, supported functions are sin
or exp
. The time variable is denoted by t
.
time_dependence = "sin(t)"
H_t = [H, [a + a.dag(), time_dependence]]
result_brme = brmesolve(H_t, psi0, times, e_ops=[a.dag() * a])
plot_expectation_values(result_brme, ylabels=["<n>"]);
Above we did not use the noise-power-spectrum, which the Bloch-Redfield solver is mainly used for. This spectrum is passed in the argument a_ops
. We can also add a string-based time dependence to a_ops
and thereby make the dissipation itself time-dependent.
Here we will define a a noice power spectrum of the form:
$$ J(\omega, t) = \kappa * e^{-t} \quad \text{for} \; \omega \geq 0$$# setup dissipation
kappa = 0.2
a_ops = [[a + a.dag(), "{kappa}*exp(-t)*(w>=0)".format(kappa=kappa)]]
# solve
result_brme_aops = brmesolve(H, psi0, times, a_ops, e_ops=[a.dag() * a])
plot_expectation_values([result_brme_aops], ylabels=["<n>"]);
The coupling to the bath is sometimes described by operators of the form
$$ A = f(t)a + f(t)^* a^\dagger $$To add such a coupling to brmesolve
we can pass tuple in the a_ops
argument. For example if we have $f(t) = e^{i * t}$ we can define the coupling of operator $A$ with strength $\kappa$ by the following a_ops
. Note that t
a_ops = [[(a, a.dag()),
('{kappa} * (w>=0)'.format(kappa=kappa),
'exp(1j*t)', 'exp(-1j*t)')]]
# solve using brmesolve and plot expecation
result_brme_aops_sum = brmesolve(H, psi0, times, a_ops, e_ops=[a.dag() * a])
plot_expectation_values([result_brme_aops_sum], ylabels=["<n>"]);
about()
QuTiP: Quantum Toolbox in Python ================================ Copyright (c) QuTiP team 2011 and later. Current admin team: Alexander Pitchford, Nathan Shammah, Shahnawaz Ahmed, Neill Lambert, Eric Giguère, Boxi Li, Jake Lishman, Simon Cross and Asier Galicia. Board members: Daniel Burgarth, Robert Johansson, Anton F. Kockum, Franco Nori and Will Zeng. Original developers: R. J. Johansson & P. D. Nation. Previous lead developers: Chris Granade & A. Grimsmo. Currently developed through wide collaboration. See https://github.com/qutip for details. QuTiP Version: 4.7.1 Numpy Version: 1.22.4 Scipy Version: 1.8.1 Cython Version: 0.29.33 Matplotlib Version: 3.5.2 Python Version: 3.10.4 Number of CPUs: 2 BLAS Info: Generic OPENMP Installed: False INTEL MKL Ext: False Platform Info: Linux (x86_64) Installation path: /home/runner/work/qutip-tutorials/qutip-tutorials/qutip/qutip ================================================================================ Please cite QuTiP in your publication. ================================================================================ For your convenience a bibtex reference can be easily generated using `qutip.cite()`
assert np.allclose(result_const.expect[0], 1.0)
# compare result from brme with a_ops to analytic solution
analytic_aops = (N - 1) * np.exp(-kappa * (1.0 - np.exp(-times)))
assert np.allclose(result_brme_aops.expect[0], analytic_aops)
assert np.all(np.diff(result_brme_aops_sum.expect[0]) <= 0.0)