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

QuTiPv5 Paper Notebook: smesolve #110

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
132 changes: 132 additions & 0 deletions tutorials-v5/time-evolution/022_v5_paper-smesolve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
---
jupyter:
jupytext:
text_representation:
extension: .md
format_name: markdown
format_version: '1.3'
jupytext_version: 1.13.8
kernelspec:
display_name: qutip-tutorials-v5
language: python
name: python3
---

# QuTiPv5 Paper Example: Stochastic Solver - Homodyne Detection

Authors: Maximilian Meyer-Mölleringhof ([email protected])
Langhaarzombie marked this conversation as resolved.
Show resolved Hide resolved

## Introduction

When modelling an open quantum system, stochastic noise can be used to simulate a large range of phenomena.
In the `smesolve()` solver, noise appears because of continuous measurement.
It allows us to generate the trajectory evolution of a quantum system conditioned on a noisy measurement record.
Historically speaking, such models were used by the quantum optics community to model homodyne and heterodyne detection of light emitted from a cavity.
However, this solver is of course quite general and can thus also be applied to other problems.

In this example we look at an optical cavity whose output is subject to homodyne detection.
Such a cavity obeys the general stochastic master equation

$d \rho(t) = -i [H, \rho(t)] dt + \mathcal{D}[a] \rho (t) dt + \mathcal{H}[a] \rho dW(t)$

with the Hamiltonian

$H = \Delta a^\dag a$
Langhaarzombie marked this conversation as resolved.
Show resolved Hide resolved

and the Lindblad dissipator

$\mathcal{D}[a] = a \rho a^\dag - \dfrac{1}{2} a^\dag a \rho - \dfrac{1}{2} \rho a^\dag a$.

The stochastic part

$\mathcal{H}[a]\rho = a \rho + \rho a^\dag - tr[a \rho + \rho a^\dag]$

captures the conditioning of the trajectory through continious monitoring of the operator $a$.
The term $dW(t)$ is the increment of a Wiener process that obeys $\mathbb{E}[dW] = 0$ and $\mathbb{E}[dW^2] = dt$.

```python
import numpy as np
from matplotlib import pyplot as plt
from qutip import about, coherent, destroy, mesolve, smesolve

%matplotlib inline
```

## Problem Parameters

```python
N = 20 # dimensions of Hilbert space
delta = 10 * np.pi # cavity detuning
kappa = 1 # decay rate
A = 4 # initial coherent state intensity
```

```python
a = destroy(N)
x = a + a.dag() # operator for expectation value
H = delta * a.dag() * a # Hamiltonian
mon_op = np.sqrt(kappa) * a # continiously monitored operators
```

## Solving for the Time Evolution

We calculate the predicted trajectory conditioned on the continious monitoring of operator $a$.
This is compared to the regular `mesolve()` solver for the same model but without resolving conditioned trajectories.

```python
rho_0 = coherent(N, np.sqrt(A)) # initial state
times = np.arange(0, 1, 0.0025)
num_traj = 500 # number of computed trajectories
opt = {"dt": 0.00125, "store_measurement": True}
```
Langhaarzombie marked this conversation as resolved.
Show resolved Hide resolved

```python
me_solution = mesolve(H, rho_0, times, c_ops=[mon_op], e_ops=[x])
```

```python
stoc_solution = smesolve(
H, rho_0, times, sc_ops=[mon_op], e_ops=[x], ntraj=num_traj, options=opt
)
```

## Comparison of Results

We plot the averaged homodyne current $J_x = \langle x \rangle + dW / dt$ and the average system behaviour $\langle x \rangle$ for 500 trajectories.
This is compared with the prediction of the regular `mesolve()` solver that does not include the conditioned trajectories.
Since the conditioned expectation values do not depend on the trajectories, we expect that this reproduces the result of the standard `me_solve`.

```python
stoc_meas_mean = np.array(stoc_solution.measurement).mean(axis=0)[0, :].real
```

```python
plt.figure()
plt.plot(times[1:], stoc_meas_mean, lw=2, label=r"$J_x$")
plt.plot(times, stoc_solution.expect[0], label=r"$\langle x \rangle$")
plt.plot(
times,
me_solution.expect[0],
"--",
color="gray",
label=r"$\langle x \rangle$ mesolve",
)

plt.legend()
plt.xlabel(r"$t \cdot \kappa$")
plt.show()
```

## About

```python
about()
```

## Testing

```python
Langhaarzombie marked this conversation as resolved.
Show resolved Hide resolved
assert np.allclose(
stoc_solution.expect[0] == me_solution.expect[0]
), "The smesolve and mesolve do not preoduce the same trajectory."
```
Langhaarzombie marked this conversation as resolved.
Show resolved Hide resolved
Loading