6 drag calibration
In [ ]:
Copied!
import numpy as np
import qubex as qx
from qubex.simulator import Control, QuantumSimulator, QuantumSystem, Transmon
import numpy as np
import qubex as qx
from qubex.simulator import Control, QuantumSimulator, QuantumSystem, Transmon
In [ ]:
Copied!
# units: GHz, ns
qubit = Transmon(
label="Q01",
dimension=3,
frequency=7.5,
anharmonicity=-7.5 / 19,
relaxation_rate=0.05e-3,
dephasing_rate=0.05e-3,
)
system = QuantumSystem(objects=[qubit])
simulator = QuantumSimulator(system)
# units: GHz, ns
qubit = Transmon(
label="Q01",
dimension=3,
frequency=7.5,
anharmonicity=-7.5 / 19,
relaxation_rate=0.05e-3,
dephasing_rate=0.05e-3,
)
system = QuantumSystem(objects=[qubit])
simulator = QuantumSimulator(system)
In [ ]:
Copied!
def drag_pulse(
duration: float,
amplitude: float,
beta: float,
):
"""Build a DRAG pulse with a Gaussian envelope."""
pulse = qx.pulse.Drag(
duration=duration, amplitude=amplitude, beta=beta, type="Gaussian"
)
return pulse
def drag_pulse(
duration: float,
amplitude: float,
beta: float,
):
"""Build a DRAG pulse with a Gaussian envelope."""
pulse = qx.pulse.Drag(
duration=duration, amplitude=amplitude, beta=beta, type="Gaussian"
)
return pulse
In [ ]:
Copied!
duration = 24 # ns
alpha = 2 * np.pi * qubit.anharmonicity
beta = -0.5 / alpha
pulse = drag_pulse(
duration=duration,
amplitude=1,
beta=beta,
)
norm_factor = np.pi / float(np.sum(np.abs(pulse.values) * pulse.SAMPLING_PERIOD))
pulse = pulse.scaled(norm_factor)
pulse.plot(divide_by_two_pi=True)
amplitude = np.max(pulse.real).astype(float)
amplitude, beta
duration = 24 # ns
alpha = 2 * np.pi * qubit.anharmonicity
beta = -0.5 / alpha
pulse = drag_pulse(
duration=duration,
amplitude=1,
beta=beta,
)
norm_factor = np.pi / float(np.sum(np.abs(pulse.values) * pulse.SAMPLING_PERIOD))
pulse = pulse.scaled(norm_factor)
pulse.plot(divide_by_two_pi=True)
amplitude = np.max(pulse.real).astype(float)
amplitude, beta
In [ ]:
Copied!
result = simulator.mesolve(
controls=[
Control(
target=qubit.label,
frequency=qubit.frequency,
waveform=pulse,
)
],
initial_state={
qubit.label: "0",
},
)
result.show_last_population(qubit.label)
result.plot_population_dynamics(qubit.label)
result.plot_bloch_vectors(qubit.label)
result.display_bloch_sphere(qubit.label)
result = simulator.mesolve(
controls=[
Control(
target=qubit.label,
frequency=qubit.frequency,
waveform=pulse,
)
],
initial_state={
qubit.label: "0",
},
)
result.show_last_population(qubit.label)
result.plot_population_dynamics(qubit.label)
result.plot_bloch_vectors(qubit.label)
result.display_bloch_sphere(qubit.label)
In [ ]:
Copied!
results = []
beta_range = np.linspace(-1, 1, 51)
for idx, beta in enumerate(beta_range):
pulse = drag_pulse(
duration=duration,
amplitude=amplitude,
beta=beta,
)
result = simulator.mesolve(
controls=[
Control(
target=qubit,
waveform=qx.PulseArray(
[
pulse,
pulse.scaled(-1),
]
),
)
],
)
results.append(result)
if idx % 10 == 0:
print(f"beta = {beta:.2f}")
result.display_bloch_sphere(qubit.label)
results = []
beta_range = np.linspace(-1, 1, 51)
for idx, beta in enumerate(beta_range):
pulse = drag_pulse(
duration=duration,
amplitude=amplitude,
beta=beta,
)
result = simulator.mesolve(
controls=[
Control(
target=qubit,
waveform=qx.PulseArray(
[
pulse,
pulse.scaled(-1),
]
),
)
],
)
results.append(result)
if idx % 10 == 0:
print(f"beta = {beta:.2f}")
result.display_bloch_sphere(qubit.label)
In [ ]:
Copied!
e_x = np.array([result.get_bloch_vectors(qubit.label)[-1][0] for result in results])
qx.viz.plot(
x=beta_range,
y=e_x,
title="Sweeping DRAG beta",
xlabel="β",
ylabel="〈X〉",
)
e_x = np.array([result.get_bloch_vectors(qubit.label)[-1][0] for result in results])
qx.viz.plot(
x=beta_range,
y=e_x,
title="Sweeping DRAG beta",
xlabel="β",
ylabel="〈X〉",
)
In [ ]:
Copied!
from scipy.optimize import root_scalar
e_x_fine = lambda x: np.interp(x, beta_range, e_x)
result = root_scalar(e_x_fine, bracket=[beta_range[0], beta_range[-1]])
beta = result.root
beta
from scipy.optimize import root_scalar
e_x_fine = lambda x: np.interp(x, beta_range, e_x)
result = root_scalar(e_x_fine, bracket=[beta_range[0], beta_range[-1]])
beta = result.root
beta
In [ ]:
Copied!
pulse = drag_pulse(
duration=duration,
amplitude=amplitude,
beta=beta,
)
pulse.plot(divide_by_two_pi=True)
result = simulator.mesolve(
controls=[
Control(
target=qubit.label,
frequency=qubit.frequency,
waveform=pulse,
)
],
initial_state={
qubit.label: "0",
},
)
result.show_last_population(qubit.label)
result.plot_population_dynamics(qubit.label)
result.plot_bloch_vectors(qubit.label)
result.display_bloch_sphere(qubit.label)
pulse = drag_pulse(
duration=duration,
amplitude=amplitude,
beta=beta,
)
pulse.plot(divide_by_two_pi=True)
result = simulator.mesolve(
controls=[
Control(
target=qubit.label,
frequency=qubit.frequency,
waveform=pulse,
)
],
initial_state={
qubit.label: "0",
},
)
result.show_last_population(qubit.label)
result.plot_population_dynamics(qubit.label)
result.plot_bloch_vectors(qubit.label)
result.display_bloch_sphere(qubit.label)
In [ ]:
Copied!
def drag_objective_func(x):
"""Objective function for DRAG calibration."""
amplitude, beta = x
pulse = drag_pulse(
duration=duration,
amplitude=amplitude,
beta=beta,
)
result = simulator.mesolve(
controls=[
Control(
target=qubit,
waveform=pulse,
)
],
)
state = result.get_bloch_vectors(qubit.label)[-1]
target = np.array([0, 0, -1])
return np.linalg.norm(state - target)
def drag_objective_func(x):
"""Objective function for DRAG calibration."""
amplitude, beta = x
pulse = drag_pulse(
duration=duration,
amplitude=amplitude,
beta=beta,
)
result = simulator.mesolve(
controls=[
Control(
target=qubit,
waveform=pulse,
)
],
)
state = result.get_bloch_vectors(qubit.label)[-1]
target = np.array([0, 0, -1])
return np.linalg.norm(state - target)
In [ ]:
Copied!
drag_objective_func([amplitude, beta])
drag_objective_func([amplitude, beta])
In [ ]:
Copied!
import cma
initial_guess = [
amplitude,
beta,
]
es = cma.CMAEvolutionStrategy(
initial_guess,
0.01,
{
"seed": 42,
"ftarget": 1e-6,
},
)
es.optimize(drag_objective_func)
es.result.xbest
import cma
initial_guess = [
amplitude,
beta,
]
es = cma.CMAEvolutionStrategy(
initial_guess,
0.01,
{
"seed": 42,
"ftarget": 1e-6,
},
)
es.optimize(drag_objective_func)
es.result.xbest
In [ ]:
Copied!
drag_objective_func(es.result.xbest)
drag_objective_func(es.result.xbest)
In [ ]:
Copied!
pulse = drag_pulse(
duration=duration,
amplitude=es.result.xbest[0],
beta=es.result.xbest[1],
)
pulse.plot(divide_by_two_pi=True)
pulse = drag_pulse(
duration=duration,
amplitude=es.result.xbest[0],
beta=es.result.xbest[1],
)
pulse.plot(divide_by_two_pi=True)
In [ ]:
Copied!
result = simulator.mesolve(
controls=[
Control(
target=qubit.label,
frequency=qubit.frequency,
waveform=pulse,
)
],
)
result.display_bloch_sphere(qubit.label)
result.show_last_population(qubit.label)
result = simulator.mesolve(
controls=[
Control(
target=qubit.label,
frequency=qubit.frequency,
waveform=pulse,
)
],
)
result.display_bloch_sphere(qubit.label)
result.show_last_population(qubit.label)
In [ ]:
Copied!
result = simulator.mesolve(
controls=[
Control(
target=qubit,
waveform=qx.PulseArray(
[pulse] * 2,
),
)
],
)
result.display_bloch_sphere(qubit.label)
result.show_last_population(qubit.label)
result = simulator.mesolve(
controls=[
Control(
target=qubit,
waveform=qx.PulseArray(
[pulse] * 2,
),
)
],
)
result.display_bloch_sphere(qubit.label)
result.show_last_population(qubit.label)
In [ ]:
Copied!
result = simulator.mesolve(
controls=[
Control(
target=qubit.label,
frequency=qubit.frequency,
waveform=qx.PulseArray(
[pulse] * 10,
),
)
],
)
result.display_bloch_sphere(qubit.label)
result.show_last_population(qubit.label)
result = simulator.mesolve(
controls=[
Control(
target=qubit.label,
frequency=qubit.frequency,
waveform=qx.PulseArray(
[pulse] * 10,
),
)
],
)
result.display_bloch_sphere(qubit.label)
result.show_last_population(qubit.label)