Additionally, the OPX+ allows switching between an unlimited number of frequencies while preserving the rotating frame of each tone (offering unprecedented control over the NV center qubits used). Such switching is crucial when the same output channel is driving different transitions. This is done in QUA by using the update_frequency(‘system’,‘frequency’)
command as in the Nuclear_spin_init()
macro you previously saw.
We can see an example of the switching by running a simple code in QUA:
This code plays pulses with an arbitrary frequency out of two OPX+ outputs. Then, one of the frequencies is changed and changed back. In Fig. 2, we show what an observing oscilloscope would measure at the outputs. Thanks to the OPX+ phase tracking, once the frequency of output1
is restored to the original frequency, the resulting output will still be in phase with its original twin output2
. The tracking of a phase can also be reset by the reset_phase()
command.
qmm = QuantumMachinesManager()
qm = qmm.open_qm(config)
N_max1=1000
N_max2=500
a1 = 0.2 ##amplitude for the qubit1 conditional rotations
t1 = 100 ##duration for the qubit1 conditional rotations
a2 = 0.2 ##amplitude for the qubit2 conditional rotations
t2 = 100 ##duration for the qubit2 conditional rotations
entanglement_threshold = 1
SSRO1_threshold = 1
SSRO2_threshold = 1
threshold = 1
def entangle():
times_internal = declare(int, size=100)
counts_internal = declare(int)
assign(entangled, False)
play("laser", "qubit1")
wait(4, "qubit1")
play("pi_half", "qubit1")
wait(4, "qubit1")
play("laser", "qubit2")
wait(4, "qubit2")
play("pi_half", "qubit2")
wait(4, "qubit2")
align("qubit1","qubit2","laser_red_Ey")
play("laser_pi" , "laser_red_Ey")
play("pi_plus_2ns_wait", "qubit1")
play("pi_plus_2ns_wait", "qubit2")
align("qubit1","detector")
measure("entanglement_readout", "detector", None, time_tagging.analog(times_internal, 300, counts_internal))
with if_(counts_internal > entanglement_threshold):
wait(66, "laser_red_Ey")
align("qubit1","qubit2","laser_red_Ey")
play("pi", "qubit1")
wait(70, "qubit1")
play("pi", "qubit2")
wait(70, "qubit2")
align("qubit1","qubit2","laser_red_Ey")
play("laser_pi", "laser_red_Ey")
play("pi_plus_2ns_wait", "qubit1")
play("pi_plus_2ns_wait", "qubit2")
align("detector", "qubit1")
measure("entanglement_readout", "detector", None, time_tagging.analog(times_internal, 300, counts_internal))
wait(4, "laser_red_Ey")
align("qubit1","qubit2","laser_red_Ey")
assign(entangled, counts_internal > entanglement_threshold)
def xy8_n(system,n,t):
i_internal = declare(int)
wait(t, f"qubit{system}")
xy8_block(f"qubit{system}",t)
with for_(i_internal, 0, i_internal < n - 1, i_internal + 1):
wait(2 * t, f"qubit{system}")
xy8_block(f"qubit{system}",t)
wait(t, f"qubit{system}")
def xy8_block(qubit,t):
# A single XY8 block, ends at x frame.
play("pi", qubit) # 1 X
wait(2 * t, qubit)
frame_rotation(np.pi / 2, qubit)
play("pi", qubit) # 2 Y
wait(2 * t, qubit)
reset_frame(qubit)
play("pi", qubit) # 3 X
wait(2 * t, qubit)
frame_rotation(np.pi / 2, qubit)
play("pi", qubit) # 4 Y
wait(2 * t, qubit)
play("pi", qubit) # 5 Y
wait(2 * t, qubit)
reset_frame(qubit)
play("pi", qubit) # 6 X
wait(2 * t, qubit)
frame_rotation(np.pi / 2, qubit)
play("pi", qubit) # 7 Y
wait(2 * t, qubit)
reset_frame(qubit)
play("pi", qubit) # 8 X
def C13_pi_pulse(system):
if system==1:
xy8_n(1,6,12)
else:
xy8_n(2,8, 14)
def C13_pi_half_pulse(system):
if system==1:
xy8_n(1,3, 12)
else:
xy8_n(2,4, 14)
def C13_phase_pulse(system,repetitions):
if system==1:
xy8_n(1,repetitions,12)
else:
xy8_n(2,repetitions, 14)
def Nuclear_spin_init(system, total_counts,a,t):
i_internal = declare(int)
times_internal = declare(int, size=100)
counts_internal = declare(int)
frame_rotation(np.pi / 2, f"qubit{system}")
play("pi_half", f"qubit{system}")
wait(4,f"qubit{system}")
reset_frame(f"qubit{system}")
C13_pi_half_pulse(system)
wait(4, f"qubit{system}")
play("pi_half", f"qubit{system}")
wait(4, f"qubit{system}")
C13_pi_half_pulse(system)
update_frequency(f"qubit{system}",NV2_conditional_freq)
assign(total_counts, 0)
with for_(i_internal, 0, i_internal < 2, i_internal + 1):
play("pi" * amp(a), f"qubit{system}", duration=t)
measure("readout", f"qubit{system}", None, time_tagging.analog(times_internal, 300, counts_internal))
assign(total_counts,total_counts+counts_internal)
update_frequency(f"qubit{system}",NV_IF)
def SWAP(system):
times_internal = declare(int, size=100)
counts_internal = declare(int)
C13_pi_half_pulse(system)
wait(4, f"qubit{system}")
play("pi_half", f"qubit{system}")
wait(4, f"qubit{system}")
C13_pi_half_pulse(system)
wait(4, f"qubit{system}")
frame_rotation(np.pi / 2, f"qubit{system}")
play("pi_half", f"qubit{system}")
reset_frame(f"qubit{system}")
measure("readout", f"qubit{system}", None, time_tagging.analog(times_internal, 300, counts_internal))
def purifying_gate(system):
times_internal = declare(int, size=100)
counts_internal = declare(int)
frame_rotation(np.pi / 2, f"qubit{system}")
play("pi_half", f"qubit{system}")
reset_frame(f"qubit{system}")
wait(4, f"qubit{system}")
C13_pi_half_pulse(system)
wait(4, f"qubit{system}")
play("pi_half", f"qubit{system}")
measure("readout", f"qubit{system}", None, time_tagging.analog(times_internal, 300, counts_internal))
def Charge_resonance_check():
times1 = declare(int, size=100)
counts1 = declare(int)
times2 = declare(int, size=100)
counts2 = declare(int)
assign(state_initialization, False)
play("laser", "qubit1")
play("laser", "qubit2")
align("qubit1","qubit2","laser_red_A1_1","laser_red_A1_2")
play("laser_on", "laser_red_A1_1")
play("laser_on", "laser_red_A1_2")
measure("SSRO_readout", "qubit1", None, time_tagging.analog(times1, 300, counts1))
measure("SSRO_readout", "qubit2", None, time_tagging.analog(times2, 300, counts2))
wait(200,"qubit1")
align("qubit1","qubit2","laser_red_Ey","laser_red_A1_1","laser_red_A1_2")
with if_(counts1 > threshold & counts2 > threshold):
play("laser_on", "laser_red_Ey")
play("laser_on", "laser_red_A1_1")
play("laser_on", "laser_red_A1_2")
measure("SSRO_readout", "qubit1", None, time_tagging.analog(times1, 300, counts1))
measure("SSRO_readout", "qubit2", None, time_tagging.analog(times2, 300, counts2))
with if_(counts1 > threshold & counts2 > threshold):
assign(state_initialization, True)
def SSRO(system,SSRO_threshold):
times_internal = declare(int, size=100)
counts_internal = declare(int)
play("laser", f"qubit{system}")
align(f"qubit{system}",f"laser_red_A1_{system}")
play("laser_on", f"laser_red_A1_{system}")
measure("SSRO_readout", f"qubit{system}", None, time_tagging.analog(times_internal, 300, counts_internal))
return (counts_internal < SSRO_threshold)
def Tomography_X(system,a,t,counts_total):
i_internal = declare(int)
times_internal = declare(int, size=100)
counts_internal = declare(int)
frame_rotation(np.pi / 2, f"qubit{system}")
play("pi_half", f"qubit{system}")
reset_frame(f"qubit{system}")
wait(4, f"qubit{system}")
C13_pi_half_pulse(system)
wait(4, f"qubit{system}")
play("pi_half", f"qubit{system}")
update_frequency(f"qubit{system}", NV1_conditional_freq)
play("laser", f"qubit{system}")
play("pi" * amp(a), f"qubit{system}", duration=t)
align(f"qubit{system}", f"laser_red_A1_{system}")
play("laser_on", f"laser_red_A1_{system}")
assign(counts_total, 0)
with for_(i_internal, 0, i_internal < 5, i_internal+1):
play("laser", f"qubit{system}")
play("pi" * amp(a), f"qubit{system}", duration=t)
align(f"qubit{system}", f"laser_red_A1_{system}")
play("laser_on", f"laser_red_A1_{system}")
measure("SSRO_readout", f"qubit{system}", None, time_tagging.analog(times_internal, 300, counts_internal))
assign(counts_total,counts_total+counts_internal)
update_frequency(f"qubit{system}", NV_IF)
with program() as sp_ent:
times1_total = declare(int, size=100)
counts1_total = declare(int)
times2_total = declare(int, size=100)
counts2_total = declare(int)
N = declare(int)
entanglement_repetitions = declare(int)
qubit1_state0 = declare(bool, value=False)
qubit2_state0 = declare(bool, value=False)
state_initialization = declare(bool,value=False)
entangled = declare(bool,value=False)
with while_(entangled == False):
assign(qubit1_state0, False)
assign(qubit2_state0, False)
with while_((qubit1_state0 == False)|(qubit2_state0 == False)):
assign(entangled, False)
with while_(entangled == False):
assign(state_initialization, False)
with while_(state_initialization == False): ## initialization of both NV's
Charge_resonance_check()
## if successful then C13 initialization
Nuclear_spin_init(1, counts1_total,a1,t1)
Nuclear_spin_init(2, counts2_total,a2,t2)
align("qubit1", "qubit2")
## spin photon entanglement // if 1000 tries go back to the start
assign(N, 0)
with while_((entangled == False) & (N < N_max1)):
entangle()
assign(N,N+1)
## Swap the state between NV and C13
SWAP(1)
SWAP(2)
## Single Shot readout of both NV's
assign(qubit1_state0,SSRO(1,SSRO1_threshold))
assign(qubit2_state0,SSRO(2,SSRO2_threshold))
align("qubit1", "qubit2")
## spin photon entanglement 2// if 500 tries go back to the start
assign(entanglement_repetitions, N)
assign(N, 0)
assign(entangled, False)
with while_((entangled == False) & (N < N_max2)):
entangle()
assign(N,N+1)
assign(entanglement_repetitions, entanglement_repetitions + N)
C13_phase_pulse(1, entanglement_repetitions)
C13_phase_pulse(2, entanglement_repetitions)
purifying_gate(1)
purifying_gate(2)
align("qubit1","qubit2")
with if_(SSRO(1,SSRO1_threshold)):
play("pi","qubit1")
with if_(SSRO(2,SSRO2_threshold)):
play("pi","qubit2")
Tomography_X(1,a1,t1,counts1_total)
Tomography_X(2,a2,t2,counts2_total)
[1] Kimble, H. Jeff. Nature 453.7198 (2008): 1023-1030.
[2] Bennett, C. H., et al. Physical Review A 54.5 (1996): 3824.