Monte Carlo Solver¶
Introduction¶
Where as the density matrix formalism describes the ensemble average over many identical realizations of a quantum system, the Monte Carlo (MC), or quantum-jump approach to wave function evolution, allows for simulating an individual realization of the system dynamics. Here, the environment is continuously monitored, resulting in a series of quantum jumps in the system wave function, conditioned on the increase in information gained about the state of the system via the environmental measurements. In general, this evolution is governed by the Schrödinger equation with a non-Hermitian effective Hamiltonian
where again, the \(C_{n}\) are collapse operators, each corresponding to a separate irreversible process with rate \(\gamma_{n}\). Here, the strictly negative non-Hermitian portion of Eq. (1) gives rise to a reduction in the norm of the wave function, that to first-order in a small time \(\delta t\), is given by \(\left<\psi(t+\delta t)|\psi(t+\delta t)\right>=1-\delta p\) where
and \(\delta t\) is such that \(\delta p \ll 1\). With a probability of remaining in the state \(\left|\psi(t+\delta t)\right>\) given by \(1-\delta p\), the corresponding quantum jump probability is thus Eq. (2). If the environmental measurements register a quantum jump, say via the emission of a photon into the environment, or a change in the spin of a quantum dot, the wave function undergoes a jump into a state defined by projecting \(\left|\psi(t)\right>\) using the collapse operator \(C_{n}\) corresponding to the measurement
If more than a single collapse operator is present in Eq. (1), the probability of collapse due to the \(i\mathrm{th}\)-operator \(C_{i}\) is given by
Evaluating the MC evolution to first-order in time is quite tedious. Instead, QuTiP uses the following algorithm to simulate a single realization of a quantum system. Starting from a pure state \(\left|\psi(0)\right>\):
- I: Choose a random number \(r\) between zero and one, representing the probability that a quantum jump occurs.
- II: Integrate the Schrödinger equation, using the effective Hamiltonian (1) until a time \(\tau\) such that the norm of the wave function satisfies \(\left<\psi(\tau)\right.\left|\psi(\tau)\right>=r\), at which point a jump occurs.
- III: The resultant jump projects the system at time \(\tau\) into one of the renormalized states given by Eq. (3). The corresponding collapse operator \(C_{n}\) is chosen such that \(n\) is the smallest integer satisfying:
where the individual \(P_{n}\) are given by Eq. (4). Note that the left hand side of Eq. (5) is, by definition, normalized to unity.
- IV: Using the renormalized state from step III as the new initial condition at time \(\tau\), draw a new random number, and repeat the above procedure until the final simulation time is reached.
Monte Carlo in QuTiP¶
In QuTiP, Monte Carlo evolution is implemented with the qutip.mcsolve
function. It takes nearly the same arguments as the qutip.mesolve
function for master-equation evolution, except that the initial state must be a ket vector, as oppose to a density matrix, and there is an optional keyword parameter ntraj
that defines the number of stochastic trajectories to be simulated. By default, ntraj=500
indicating that 500 Monte Carlo trajectories will be performed.
To illustrate the use of the Monte Carlo evolution of quantum systems in QuTiP, let’s again consider the case of a two-level atom coupled to a leaky cavity. The only differences to the master-equation treatment is that in this case we invoke the qutip.mcsolve
function instead of qutip.mesolve
In [1]: times = np.linspace(0.0, 10.0, 200)
In [2]: psi0 = tensor(fock(2, 0), fock(10, 5))
In [3]: a = tensor(qeye(2), destroy(10))
In [4]: sm = tensor(destroy(2), qeye(10))
In [5]: H = 2 * np.pi * a.dag() * a + 2 * np.pi * sm.dag() * sm + 2 * np.pi * 0.25 * (sm * a.dag() + sm.dag() * a)
In [6]: data = mcsolve(H, psi0, times, [np.sqrt(0.1) * a], [a.dag() * a, sm.dag() * sm])
10.0%. Run time: 0.58s. Est. time left: 00:00:00:05
20.0%. Run time: 1.12s. Est. time left: 00:00:00:04
30.0%. Run time: 1.65s. Est. time left: 00:00:00:03
40.0%. Run time: 2.18s. Est. time left: 00:00:00:03
50.0%. Run time: 2.70s. Est. time left: 00:00:00:02
60.0%. Run time: 3.26s. Est. time left: 00:00:00:02
70.0%. Run time: 3.79s. Est. time left: 00:00:00:01
80.0%. Run time: 4.31s. Est. time left: 00:00:00:01
90.0%. Run time: 4.83s. Est. time left: 00:00:00:00
100.0%. Run time: 5.41s. Est. time left: 00:00:00:00
Total run time: 5.43s
In [7]: figure()