"""
Damped Rabi Oscillations – Rotating Frame (Python)
Adapted from the MATLAB code by Sathyanarayan Rao (2015).
"""
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['text.usetex'] = True
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.size'] = 16
# --- Optical Bloch equations in rotating frame ---
def drho11(t, r12, r21, r22, gam, Omega, delta):
return 1j*0.5*np.conj(Omega)*r12 - 1j*0.5*Omega*r21 + gam*r22
def drho12(t, r11, r12, r22, gam, Omega, delta):
return 1j*0.5*Omega*(r11 - r22) - 1j*delta*r12 - 0.5*gam*r12
def drho21(t, r11, r21, r22, gam, Omega, delta):
return -1j*0.5*np.conj(Omega)*(r11 - r22) + 1j*delta*r21 - 0.5*gam*r21
def drho22(t, r12, r21, r22, gam, Omega, delta):
return -1j*0.5*np.conj(Omega)*r12 + 1j*0.5*Omega*r21 - gam*r22
# Parameters
Omega = 2*np.pi*10e6 # Rabi frequency 2π×10 MHz
delta = 0 # detuning
gamma = Omega # set a typical scale
N = 1000
t = np.linspace(0, 1e-6, N)
dt = t[1] - t[0]
def density_me(Omega, delta, gamma):
rho11 = np.ones(N, dtype=complex)
rho22 = np.zeros(N, dtype=complex)
rho12 = np.zeros(N, dtype=complex)
rho21 = np.zeros(N, dtype=complex)
for i in range(1, N):
k1 = drho22(t[i-1], rho12[i-1], rho21[i-1], rho22[i-1], gamma, Omega, delta)*dt
l1 = drho11(t[i-1], rho12[i-1], rho21[i-1], rho22[i-1], gamma, Omega, delta)*dt
m1 = drho12(t[i-1], rho11[i-1], rho12[i-1], rho22[i-1], gamma, Omega, delta)*dt
n1 = drho21(t[i-1], rho11[i-1], rho21[i-1], rho22[i-1], gamma, Omega, delta)*dt
k2 = drho22(t[i-1]+dt/2, rho12[i-1]+m1/2, rho21[i-1]+n1/2,
rho22[i-1]+k1/2, gamma, Omega, delta)*dt
l2 = drho11(t[i-1]+dt/2, rho12[i-1]+m1/2, rho21[i-1]+n1/2,
rho22[i-1]+k1/2, gamma, Omega, delta)*dt
m2 = drho12(t[i-1]+dt/2, rho11[i-1]+l1/2, rho12[i-1]+m1/2,
rho22[i-1]+k1/2, gamma, Omega, delta)*dt
n2 = drho21(t[i-1]+dt/2, rho11[i-1]+l1/2, rho21[i-1]+n1/2,
rho22[i-1]+k1/2, gamma, Omega, delta)*dt
k3 = drho22(t[i-1]+dt/2, rho12[i-1]+m2/2, rho21[i-1]+n2/2,
rho22[i-1]+k2/2, gamma, Omega, delta)*dt
l3 = drho11(t[i-1]+dt/2, rho12[i-1]+m2/2, rho21[i-1]+n2/2,
rho22[i-1]+k2/2, gamma, Omega, delta)*dt
m3 = drho12(t[i-1]+dt/2, rho11[i-1]+l2/2, rho12[i-1]+m2/2,
rho22[i-1]+k2/2, gamma, Omega, delta)*dt
n3 = drho21(t[i-1]+dt/2, rho11[i-1]+l2/2, rho21[i-1]+n2/2,
rho22[i-1]+k2/2, gamma, Omega, delta)*dt
k4 = drho22(t[i-1]+dt, rho12[i-1]+m3, rho21[i-1]+n3,
rho22[i-1]+k3, gamma, Omega, delta)*dt
l4 = drho11(t[i-1]+dt, rho12[i-1]+m3, rho21[i-1]+n3,
rho22[i-1]+k3, gamma, Omega, delta)*dt
m4 = drho12(t[i-1]+dt, rho11[i-1]+l3, rho12[i-1]+m3,
rho22[i-1]+k3, gamma, Omega, delta)*dt
n4 = drho21(t[i-1]+dt, rho11[i-1]+l3, rho21[i-1]+n3,
rho22[i-1]+k3, gamma, Omega, delta)*dt
rho22[i] = rho22[i-1] + (k1 + 2*(k2+k3) + k4)/6
rho11[i] = rho11[i-1] + (l1 + 2*(l2+l3) + l4)/6
rho12[i] = rho12[i-1] + (m1 + 2*(m2+m3) + m4)/6
rho21[i] = rho21[i-1] + (n1 + 2*(n2+n3) + n4)/6
return rho11, rho12, rho21, rho22
_,_,_, rho22_1 = density_me(Omega, delta, 0.1*gamma)
_,_,_, rho22_2 = density_me(Omega, delta, 0.25*gamma)
_,_,_, rho22_3 = density_me(Omega, delta, gamma)
plt.figure(figsize=(7.5,5))
plt.plot(t*Omega/(2*np.pi), np.real(rho22_1), linewidth=2, label=r'$\gamma=0.1\,\Omega_0$')
plt.plot(t*Omega/(2*np.pi), np.real(rho22_2), 'r--', linewidth=2, label=r'$\gamma=0.25\,\Omega_0$')
plt.plot(t*Omega/(2*np.pi), np.real(rho22_3), 'g:', linewidth=2, label=r'$\gamma=\Omega_0$')
plt.axhline(0.5, color='gray', linestyle=':', linewidth=1)
plt.xlabel(r'$t\,\Omega_0/(2\pi)$')
plt.ylabel(r'Excited state population $\rho_{ee}$')
plt.xlim([0, t[-1]*Omega/(2*np.pi)])
plt.ylim([0,1])
plt.legend(fontsize=12)
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()