One qubit Rabi floppingĀ¶
Rabi flopping is the oscillation of a qubit in the presence of a driving field. The qubit, initialized in the $|0\rangle$ state, will precess around the XY-plane of the Bloch sphere.
The driving Hamiltonian here is simply the Pauli $X$ operator, $$ X = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} $$
In this example, we implement a single-qubit Rabi flopping and emulate the qubit oscillation using the classical backend.
InĀ [1]:
Copied!
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
from oqd_core.interface.analog.operator import *
from oqd_core.interface.analog.operation import *
from oqd_core.backend.metric import *
from oqd_core.backend.task import Task, TaskArgsAnalog
from oqd_analog_emulator.qutip_backend import QutipBackend
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
from oqd_core.interface.analog.operator import *
from oqd_core.interface.analog.operation import *
from oqd_core.backend.metric import *
from oqd_core.backend.task import Task, TaskArgsAnalog
from oqd_analog_emulator.qutip_backend import QutipBackend
InĀ [2]:
Copied!
X = PauliX()
Z = PauliZ()
Hx = AnalogGate(hamiltonian=X)
circuit = AnalogCircuit()
circuit.evolve(duration=10, gate=Hx)
circuit.measure()
X = PauliX()
Z = PauliZ()
Hx = AnalogGate(hamiltonian=X)
circuit = AnalogCircuit()
circuit.evolve(duration=10, gate=Hx)
circuit.measure()
InĀ [3]:
Copied!
# define task args
args = TaskArgsAnalog(
n_shots=1000,
fock_cutoff=4,
metrics={
"Z": Expectation(operator=Z),
},
dt=1e-3,
)
task = Task(program=circuit, args=args)
# define task args
args = TaskArgsAnalog(
n_shots=1000,
fock_cutoff=4,
metrics={
"Z": Expectation(operator=Z),
},
dt=1e-3,
)
task = Task(program=circuit, args=args)
InĀ [4]:
Copied!
backend = QutipBackend()
results = backend.run(task=task)
backend = QutipBackend()
results = backend.run(task=task)
InĀ [5]:
Copied!
fig, ax = plt.subplots(1, 1, figsize=[6, 3])
colors = sns.color_palette(palette="crest", n_colors=4)
for k, (name, metric) in enumerate(results.metrics.items()):
ax.plot(results.times, metric, label=f"$\\langle {name} \\rangle$", color=colors[k])
ax.legend();
fig, ax = plt.subplots(1, 1, figsize=[6, 3])
colors = sns.color_palette(palette="crest", n_colors=4)
for k, (name, metric) in enumerate(results.metrics.items()):
ax.plot(results.times, metric, label=f"$\\langle {name} \\rangle$", color=colors[k])
ax.legend();
InĀ [6]:
Copied!
fig, axs = plt.subplots(4, 1, sharex=True, figsize=[5, 9])
state = np.array([basis.real + 1j * basis.imag for basis in results.state])
bases = ["0", "1"]
counts = {basis: results.counts.get(basis, 0) for basis in bases}
ax = axs[0]
ax.bar(x=bases, height=np.abs(state) ** 2, color=colors[0])
ax.set(ylabel="Probability")
ax = axs[1]
ax.bar(x=bases, height=list(counts.values()), color=colors[1])
ax.set(ylabel="Count")
ax = axs[2]
ax.bar(x=bases, height=state.real, color=colors[2])
ax.set(ylabel="Amplitude (real)")
ax = axs[3]
ax.bar(x=bases, height=state.imag, color=colors[3])
ax.set(xlabel="Basis state", ylabel="Amplitude (imag)", ylim=[-np.pi, np.pi]);
fig, axs = plt.subplots(4, 1, sharex=True, figsize=[5, 9])
state = np.array([basis.real + 1j * basis.imag for basis in results.state])
bases = ["0", "1"]
counts = {basis: results.counts.get(basis, 0) for basis in bases}
ax = axs[0]
ax.bar(x=bases, height=np.abs(state) ** 2, color=colors[0])
ax.set(ylabel="Probability")
ax = axs[1]
ax.bar(x=bases, height=list(counts.values()), color=colors[1])
ax.set(ylabel="Count")
ax = axs[2]
ax.bar(x=bases, height=state.real, color=colors[2])
ax.set(ylabel="Amplitude (real)")
ax = axs[3]
ax.bar(x=bases, height=state.imag, color=colors[3])
ax.set(xlabel="Basis state", ylabel="Amplitude (imag)", ylim=[-np.pi, np.pi]);