Time-Dependent Drive Example

Time-Dependent Drive Example#

Physics: Compile a Rabi-oscillation Hamiltonian with a time-dependent drive.

The Model

The classic Rabi problem combines a static qubit splitting with a resonant oscillating drive:

\[H(t) = \frac{\omega_0}{2} \sigma_z + \Omega \cos(\omega_d t) \sigma_x\]

where:

  • \(\omega_0\) is the qubit transition frequency

  • \(\Omega\) is the drive Rabi frequency (drive strength)

  • \(\omega_d\) is the drive frequency

  • \(\sigma_x\) is the Pauli X operator (in-plane rotation)

  • The \(\cos(\omega_d t)\) envelope creates an oscillating drive

This is the foundational model for qubit gates in superconducting circuits, trapped ions, and other platforms.

What you’ll learn

  • How to write time-dependent envelopes in LaTeX (\cos(\omega t), \sin(\omega t), \exp(-t), etc.)

  • How the parser automatically detects time dependence

  • How to extract the time-dependent Hamiltonian and args dictionary for use with QuTiP’s mesolve

Code

 1# flake8: noqa
 2"""
 3Single-qubit drive with a time-dependent cosine envelope.
 4
 5What this shows:
 6- Time-dependent scalar envelopes detected automatically from `t_name`.
 7- The QuTiP backend returns an H-list suitable for `mesolve`.
 8- How `time_dependent` is flagged on the compiled model.
 9"""
10
11from __future__ import annotations
12
13import sys
14from pathlib import Path
15
16ROOT = Path(__file__).resolve().parents[1]
17if str(ROOT) not in sys.path:
18    sys.path.insert(0, str(ROOT))
19
20from latex_parser.latex_api import compile_model as compile_latex_model
21
22
23def main() -> None:
24    H_latex = r"\frac{\omega_0}{2} \sigma_{z,1} + A \cos(\omega t) \sigma_{x,1}"
25    params = {"omega_0": 2.0, "A": 0.3, "omega": 1.5}
26    model = compile_latex_model(H_latex=H_latex, params=params, qubits=1, t_name="t")
27    print("Time-dependent flag:", model.time_dependent)
28    print("H representation (QuTiP list for td):\n", model.H)
29
30
31if __name__ == "__main__":
32    main()

Run it

python examples/example_time_dependent_drive.py

What happens

  1. The LaTeX includes the symbol t (the time variable), so the parser marks this as time-dependent

  2. The IR distinguishes between: - Static terms: \(\frac{\omega_0}{2} \sigma_z\) (depends on \(\omega_0\) only) - Time-dependent terms: \(\Omega \cos(\omega_d t) \sigma_x\) (depends on \(t\))

  3. QuTiP receives the Hamiltonian in list form: [H0, [H1, envelope_fn]]

  4. Each envelope is a callable fn(t, args) that the solver evaluates at each time step

Example Output

Static part (H0):
[[0.  0. ]
 [0.  1. ]]

Time-dependent part (H1):
[[0.  1.]
 [1.  0.]]

Envelope function: <function ...>

# When mesolve evaluates at time t=1.5:
envelope_fn(1.5, {}) = 0.07073...  (= cos(2*1.5))

Try this

  • Change the envelope to \(\sin(\omega_d t)\) in the LaTeX and re-run

  • Add exponential decay: \(\Omega \exp(-t/\tau) \cos(\omega_d t) \sigma_x\) (turn-off envelope)

  • Modify \(\omega_d\) to be off-resonance: change the parameter from 2.0 to 3.0

Numerical Simulation Example

To actually solve the Rabi equations:

from qutip import mesolve, basis
import numpy as np

# Compile the model (from the example)
# ... model = compile_model(...)

# Initial state: ground state
psi0 = basis(2, 0)

# Time points (0 to 2π / Ω ≈ 6.3 seconds for Rabi period)
times = np.linspace(0, 2*np.pi, 100)

# Solve the Schrödinger equation
result = mesolve(model.H, psi0, times, args=model.args)

# Analyze: Rabi oscillations between ground and excited states
excited_pop = [e[1] for e in result.expect[0]]

Next steps