def test_build(): reg_ = Register.rectangle(2, 1, prefix="q") sb = Sequence(reg_, device) var = sb.declare_variable("var") targ_var = sb.declare_variable("targ_var", size=2, dtype=int) sb.declare_channel("ch1", "rydberg_local") sb.declare_channel("ch2", "raman_local") sb.target_index(targ_var[0], "ch2") sb.target_index(targ_var[1], "ch1") wf = BlackmanWaveform(var * 100, np.pi) pls = Pulse.ConstantDetuning(wf, var, var) sb.add(pls, "ch1") sb.delay(var * 50, "ch1") sb.align("ch2", "ch1") sb.phase_shift_index(var, targ_var[0]) pls2 = Pulse.ConstantPulse(var * 100, var, var, 0) sb.add(pls2, "ch2") sb.measure() with pytest.warns(UserWarning, match="No declared variables"): sb.build(t=100, var=2, targ_var=reg_.find_indices(["q1", "q0"])) with pytest.raises(TypeError, match="Did not receive values for"): sb.build(var=2) seq = sb.build(var=2, targ_var=reg_.find_indices(["q1", "q0"])) assert seq._schedule["ch2"][-1].tf == 500 assert seq.current_phase_ref("q1") == 2.0 assert seq.current_phase_ref("q0") == 0.0 assert seq._measurement == "ground-rydberg" s = sb.serialize() sb_ = Sequence.deserialize(s) assert str(sb) == str(sb_) s2 = sb_.serialize() sb_2 = Sequence.deserialize(s2) assert str(sb) == str(sb_2)
def test_dephasing(): np.random.seed(123) reg = Register.from_coordinates([(0, 0)], prefix="q") seq = Sequence(reg, Chadoq2) seq.declare_channel("ch0", "rydberg_global") duration = 2500 pulse = Pulse.ConstantPulse(duration, np.pi, 0.0 * 2 * np.pi, 0) seq.add(pulse, "ch0") sim = Simulation(seq, sampling_rate=0.01, config=SimConfig(noise="dephasing")) assert sim.run().sample_final_state() == Counter({"0": 595, "1": 405}) assert len(sim._collapse_ops) != 0 with pytest.warns(UserWarning, match="first-order"): reg = Register.from_coordinates([(0, 0), (0, 10)], prefix="q") seq2 = Sequence(reg, Chadoq2) seq2.declare_channel("ch0", "rydberg_global") duration = 2500 pulse = Pulse.ConstantPulse(duration, np.pi, 0.0 * 2 * np.pi, 0) seq2.add(pulse, "ch0") sim = Simulation( seq2, sampling_rate=0.01, config=SimConfig(noise="dephasing", dephasing_prob=0.5), )
def test_slm_mask(): reg = Register({"q0": (0, 0), "q1": (10, 10), "q2": (-10, -10)}) targets = ["q0", "q2"] pulse1 = Pulse.ConstantPulse(100, 10, 0, 0) pulse2 = Pulse.ConstantPulse(200, 10, 0, 0) # Set mask when an XY pulse is already in the schedule seq_xy1 = Sequence(reg, MockDevice) seq_xy1.declare_channel("ch_xy", "mw_global") seq_xy1.add(pulse1, "ch_xy") seq_xy1.config_slm_mask(targets) assert seq_xy1._slm_mask_time == [0, 100] # Set mask and then add an XY pulse to the schedule seq_xy2 = Sequence(reg, MockDevice) seq_xy2.config_slm_mask(targets) seq_xy2.declare_channel("ch_xy", "mw_global") seq_xy2.add(pulse1, "ch_xy") assert seq_xy2._slm_mask_time == [0, 100] # Check that adding extra pulses does not change SLM mask time seq_xy2.add(pulse2, "ch_xy") assert seq_xy2._slm_mask_time == [0, 100] # Check that SLM mask time is updated accordingly if a new pulse with # earlier start is added seq_xy3 = Sequence(reg, MockDevice) seq_xy3.declare_channel("ch_xy1", "mw_global") seq_xy3.config_slm_mask(targets) seq_xy3.delay(duration=100, channel="ch_xy1") seq_xy3.add(pulse1, "ch_xy1") assert seq_xy3._slm_mask_time == [100, 200] seq_xy3.declare_channel("ch_xy2", "mw_global") seq_xy3.add(pulse1, "ch_xy2", "no-delay") assert seq_xy3._slm_mask_time == [0, 100] # Same as previous check, but mask is added afterwards seq_xy4 = Sequence(reg, MockDevice) seq_xy4.declare_channel("ch_xy1", "mw_global") seq_xy4.delay(duration=100, channel="ch_xy1") seq_xy4.add(pulse1, "ch_xy1") seq_xy4.declare_channel("ch_xy2", "mw_global") seq_xy4.add(pulse1, "ch_xy2", "no-delay") seq_xy4.config_slm_mask(targets) assert seq_xy4._slm_mask_time == [0, 100] # Check that paramatrize works with SLM mask seq_xy5 = Sequence(reg, MockDevice) seq_xy5.declare_channel("ch", "mw_global") var = seq_xy5.declare_variable("var") seq_xy5.add(Pulse.ConstantPulse(200, var, 0, 0), "ch") assert seq_xy5.is_parametrized() seq_xy5.config_slm_mask(targets) seq_xy5_str = seq_xy5.serialize() seq_xy5_ = Sequence.deserialize(seq_xy5_str) assert str(seq_xy5) == str(seq_xy5_) # Check drawing method with patch("matplotlib.pyplot.show"): seq_xy2.draw()
def test_min_pulse_duration(): seq = Sequence(reg, device) seq.declare_channel("ch0", "rydberg_global") seq.declare_channel("ch1", "rydberg_local") seq.target("q0", "ch1") pulse0 = Pulse.ConstantPulse(60, 1, 1, 0) pulse1 = Pulse.ConstantPulse(80, 1, 1, 0) seq.add(pulse1, "ch1") assert seq._min_pulse_duration() == 80 seq.add(pulse0, "ch0") seq.delay(52, "ch0") seq.target("q1", "ch1") seq.add(pulse1, "ch1") assert seq._min_pulse_duration() == 60
def test_mask_two_pulses(): """Similar to test_mask_equals_remove, but with more pulses afterwards. Three global pulses act on a three qubit register, with one qubit masked during the first pulse. """ reg_three = Register({"q0": (0, 0), "q1": (10, 10), "q2": (-10, -10)}) reg_two = Register({"q0": (0, 0), "q1": (10, 10)}) pulse = Pulse.ConstantPulse(100, 10, 0, 0) no_pulse = Pulse.ConstantPulse(100, 0, 0, 0) for channel_type in ["mw_global", "rydberg_global", "raman_global"]: # Masked simulation seq_masked = Sequence(reg_three, MockDevice) seq_masked.declare_channel("ch_masked", channel_type) masked_qubits = ["q2"] seq_masked.config_slm_mask(masked_qubits) seq_masked.add(pulse, "ch_masked") # First pulse: masked seq_masked.add(pulse, "ch_masked") # Second pulse: unmasked seq_masked.add(pulse, "ch_masked") # Third pulse: unmasked sim_masked = Simulation(seq_masked) # Unmasked simulation on full register seq_three = Sequence(reg_three, MockDevice) seq_three.declare_channel("ch_three", channel_type) seq_three.add(no_pulse, "ch_three") seq_three.add(pulse, "ch_three") seq_three.add(pulse, "ch_three") sim_three = Simulation(seq_three) # Unmasked simulation on reduced register seq_two = Sequence(reg_two, MockDevice) seq_two.declare_channel("ch_two", channel_type) seq_two.add(pulse, "ch_two") seq_two.add(no_pulse, "ch_two") seq_two.add(no_pulse, "ch_two") sim_two = Simulation(seq_two) ti = seq_masked._slm_mask_time[0] tf = seq_masked._slm_mask_time[1] for t in sim_masked.sampling_times: ham_masked = sim_masked.get_hamiltonian(t) ham_three = sim_three.get_hamiltonian(t) ham_two = sim_two.get_hamiltonian(t) if ti <= t <= tf: assert ham_masked == qutip.tensor(ham_two, qutip.qeye(2)) else: assert ham_masked == ham_three
def test_get_xy_hamiltonian(): simple_reg = Register.from_coordinates([[0, 10], [10, 0], [0, 0]], prefix="atom") detun = 1.0 amp = 3.0 rise = Pulse.ConstantPulse(1500, amp, detun, 0.0) simple_seq = Sequence(simple_reg, MockDevice) simple_seq.declare_channel("ch0", "mw_global") simple_seq.set_magnetic_field(0, 1.0, 0.0) simple_seq.add(rise, "ch0") assert np.isclose(np.linalg.norm(simple_seq.magnetic_field[0:2]), 1) simple_sim = Simulation(simple_seq, sampling_rate=0.03) with pytest.raises(ValueError, match="less than or equal to the sequence duration"): simple_sim.get_hamiltonian(1650) with pytest.raises(ValueError, match="greater than or equal to 0"): simple_sim.get_hamiltonian(-10) # Constant detuning, so |ud><du| term is C_3/r^3 - 2*detuning for any time simple_ham = simple_sim.get_hamiltonian(143) assert simple_ham[1, 2] == 0.5 * MockDevice.interaction_coeff_xy / 10**3 assert (np.abs(simple_ham[1, 4] - (-2 * 0.5 * MockDevice.interaction_coeff_xy / 10**3)) < 1e-10) assert simple_ham[0, 1] == 0.5 * amp assert simple_ham[3, 3] == -2 * detun
def test_config(): np.random.seed(123) reg = Register.from_coordinates([(0, 0), (0, 5)], prefix="q") seq = Sequence(reg, Chadoq2) seq.declare_channel("ch0", "rydberg_global") duration = 2500 pulse = Pulse.ConstantPulse(duration, np.pi, 0.0 * 2 * np.pi, 0) seq.add(pulse, "ch0") sim = Simulation(seq, config=SimConfig(noise="SPAM")) sim.reset_config() assert sim.config == SimConfig() sim.show_config() with pytest.raises(ValueError, match="not a valid"): sim.set_config("bad_config") clean_ham = sim.get_hamiltonian(123) new_cfg = SimConfig(noise="doppler", temperature=10000) sim.set_config(new_cfg) assert sim.config == new_cfg noisy_ham = sim.get_hamiltonian(123) assert (noisy_ham[0, 0] != clean_ham[0, 0] and noisy_ham[3, 3] == clean_ham[3, 3]) sim.set_config(SimConfig(noise="amplitude")) noisy_amp_ham = sim.get_hamiltonian(123) assert (noisy_amp_ham[0, 0] == clean_ham[0, 0] and noisy_amp_ham[0, 1] != clean_ham[0, 1])
def test_noisy_xy(): np.random.seed(15092021) simple_reg = Register.square(2, prefix="atom") detun = 1.0 amp = 3.0 rise = Pulse.ConstantPulse(1500, amp, detun, 0.0) simple_seq = Sequence(simple_reg, MockDevice) simple_seq.declare_channel("ch0", "mw_global") simple_seq.add(rise, "ch0") sim = Simulation(simple_seq, sampling_rate=0.01) with pytest.raises(NotImplementedError, match="mode 'XY' does not support simulation of"): sim.set_config(SimConfig(("SPAM", "doppler"))) sim.set_config(SimConfig("SPAM", eta=0.4)) assert sim._bad_atoms == { "atom0": True, "atom1": False, "atom2": True, "atom3": False, } with pytest.raises(NotImplementedError, match="simulation of noise types: amplitude"): sim.add_config(SimConfig("amplitude"))
def test_delay_min_duration(): # Check that a delay shorter than a channel's minimal duration # is automatically extended to that minimal duration seq = Sequence(reg, device) seq.declare_channel("ch0", "rydberg_global") seq.declare_channel("ch1", "rydberg_local") seq.target("q0", "ch1") pulse0 = Pulse.ConstantPulse(52, 1, 1, 0) pulse1 = Pulse.ConstantPulse(180, 1, 1, 0) seq.add(pulse1, "ch1") seq.add(pulse0, "ch0") seq.target("q1", "ch1") seq.add(pulse1, "ch1") min_duration = seq._channels["ch1"].min_duration assert seq._schedule["ch1"][3] == _TimeSlot("delay", 220, 220 + min_duration, {"q1"})
def test_add_max_step_and_delays(): reg = Register.from_coordinates([(0, 0)]) seq = Sequence(reg, Chadoq2) seq.declare_channel("ch", "rydberg_global") seq.delay(1500, "ch") seq.add(Pulse.ConstantDetuning(BlackmanWaveform(600, np.pi), 0, 0), "ch") seq.delay(2000, "ch") seq.add(Pulse.ConstantDetuning(BlackmanWaveform(600, np.pi / 2), 0, 0), "ch") sim = Simulation(seq) res_large_max_step = sim.run(max_step=1) res_auto_max_step = sim.run() r = qutip.basis(2, 0) occ_large = res_large_max_step.expect([r.proj()])[0] occ_auto = res_auto_max_step.expect([r.proj()])[0] assert np.isclose(occ_large[-1], 0, 1e-4) assert np.isclose(occ_auto[-1], 0.5, 1e-4)
def test_single_atom_simulation(): one_reg = Register.from_coordinates([(0, 0)], 'atom') one_seq = Sequence(one_reg, Chadoq2) one_seq.declare_channel('ch0', 'rydberg_global') one_seq.add(Pulse.ConstantDetuning(ConstantWaveform(16, 1.), 1., 0), 'ch0') one_sim = Simulation(seq) one_res = one_sim.run() assert (one_res._size == one_sim._size)
def test_mappable_register(): layout = TriangularLatticeLayout(100, 5) mapp_reg = layout.make_mappable_register(10) seq = Sequence(mapp_reg, Chadoq2) assert seq.is_register_mappable() reserved_qids = tuple([f"q{i}" for i in range(10)]) assert seq._qids == set(reserved_qids) with pytest.raises(RuntimeError, match="Can't access the qubit info"): seq.qubit_info with pytest.raises(RuntimeError, match="Can't access the sequence's register"): seq.register seq.declare_channel("ryd", "rydberg_global") seq.declare_channel("ram", "raman_local", initial_target="q2") seq.add(Pulse.ConstantPulse(100, 1, 0, 0), "ryd") seq.add(Pulse.ConstantPulse(200, 1, 0, 0), "ram") assert seq._last("ryd").targets == set(reserved_qids) assert seq._last("ram").targets == {"q2"} with pytest.raises(ValueError, match="Can't draw the register"): seq.draw(draw_register=True) # Can draw if 'draw_register=False' with patch("matplotlib.pyplot.show"): seq.draw() with pytest.raises(ValueError, match="'qubits' must be specified"): seq.build() with pytest.raises(ValueError, match="targeted but have not been assigned"): seq.build(qubits={"q0": 1, "q1": 10}) with pytest.warns(UserWarning, match="No declared variables named: a"): seq.build(qubits={"q2": 20, "q0": 10}, a=5) seq_ = seq.build(qubits={"q2": 20, "q0": 10}) assert seq_._last("ryd").targets == {"q2", "q0"} assert not seq_.is_register_mappable() assert seq_.register == Register({ "q0": layout.traps_dict[10], "q2": layout.traps_dict[20] }) with pytest.raises(ValueError, match="already has a concrete register"): seq_.build(qubits={"q2": 20, "q0": 10})
def test_mask_equals_remove(): """Check that masking is equivalent to removing the masked qubits. A global pulse acting on three qubits of which one is masked, should be equivalent to acting on a register with only the two unmasked qubits. """ reg_three = Register({"q0": (0, 0), "q1": (10, 10), "q2": (-10, -10)}) reg_two = Register({"q0": (0, 0), "q1": (10, 10)}) pulse = Pulse.ConstantPulse(100, 10, 0, 0) local_pulse = Pulse.ConstantPulse(200, 10, 0, 0) for channel_type in ["mw_global", "rydberg_global", "raman_global"]: # Masked simulation seq_masked = Sequence(reg_three, MockDevice) if channel_type == "mw_global": seq_masked.set_magnetic_field(0, 1.0, 0.0) else: # Add a local channel acting on a masked qubit (has no effect) seq_masked.declare_channel( "local", channel_type[:-len("global")] + "local", initial_target="q2", ) seq_masked.add(local_pulse, "local") seq_masked.declare_channel("ch_masked", channel_type) masked_qubits = ["q2"] seq_masked.config_slm_mask(masked_qubits) seq_masked.add(pulse, "ch_masked") sim_masked = Simulation(seq_masked) # Simulation on reduced register seq_two = Sequence(reg_two, MockDevice) if channel_type == "mw_global": seq_two.set_magnetic_field(0, 1.0, 0.0) seq_two.declare_channel("ch_two", channel_type) if channel_type != "mw_global": seq_two.delay(local_pulse.duration, "ch_two") seq_two.add(pulse, "ch_two") sim_two = Simulation(seq_two) # Check equality for t in sim_two.sampling_times: ham_masked = sim_masked.get_hamiltonian(t) ham_two = sim_two.get_hamiltonian(t) assert ham_masked == qutip.tensor(ham_two, qutip.qeye(2))
def test_magnetic_field(): seq = Sequence(reg, MockDevice) with pytest.raises( AttributeError, match="only defined when the sequence " "is in 'XY Mode'.", ): seq.magnetic_field seq.declare_channel("ch0", "mw_global") # seq in XY mode # mag field is the default assert np.all(seq.magnetic_field == np.array((0.0, 0.0, 30.0))) seq.set_magnetic_field(bx=1.0, by=-1.0, bz=0.5) assert np.all(seq.magnetic_field == np.array((1.0, -1.0, 0.5))) with pytest.raises(ValueError, match="magnitude greater than 0"): seq.set_magnetic_field(bz=0.0) assert seq._empty_sequence seq.add(Pulse.ConstantPulse(100, 1, 1, 0), "ch0") assert not seq._empty_sequence with pytest.raises(ValueError, match="can only be set on an empty seq"): seq.set_magnetic_field(1.0, 0.0, 0.0) seq2 = Sequence(reg, MockDevice) seq2.declare_channel("ch0", "rydberg_global") # not in XY mode with pytest.raises(ValueError, match="can only be set in 'XY Mode'."): seq2.set_magnetic_field(1.0, 0.0, 0.0) seq3 = Sequence(reg, MockDevice) seq3.set_magnetic_field(1.0, 0.0, 0.0) # sets seq to XY mode assert set(seq3.available_channels) == {"mw_global"} seq3.declare_channel("ch0", "mw_global") # Does not change to default assert np.all(seq3.magnetic_field == np.array((1.0, 0.0, 0.0))) var = seq3.declare_variable("var") # Sequence is marked as non-empty when parametrized too seq3.add(Pulse.ConstantPulse(100, var, 1, 0), "ch0") assert seq3.is_parametrized() with pytest.raises(ValueError, match="can only be set on an empty seq"): seq3.set_magnetic_field() seq3_str = seq3.serialize() seq3_ = Sequence.deserialize(seq3_str) assert seq3_._in_xy assert str(seq3) == str(seq3_) assert np.all(seq3_.magnetic_field == np.array((1.0, 0.0, 0.0)))
def test_single_atom_simulation(): one_reg = Register.from_coordinates([(0, 0)], "atom") one_seq = Sequence(one_reg, Chadoq2) one_seq.declare_channel("ch0", "rydberg_global") one_seq.add(Pulse.ConstantDetuning(ConstantWaveform(16, 1.0), 1.0, 0), "ch0") one_sim = Simulation(one_seq) one_res = one_sim.run() assert one_res._size == one_sim._size one_sim = Simulation(one_seq, evaluation_times="Minimal") one_resb = one_sim.run() assert one_resb._size == one_sim._size
def test_str(): reg_ = Register.rectangle(2, 1, prefix="q") sb = Sequence(reg_, device) sb.declare_channel("ch1", "rydberg_global") with pytest.warns(UserWarning, match="Building a non-parametrized"): seq = sb.build() var = sb.declare_variable("var") pls = Pulse.ConstantPulse(var * 100, var, -1, var) sb.add(pls, "ch1") s = (f"Prelude\n-------\n{str(seq)}Stored calls\n------------\n\n" + "1. add(Pulse.ConstantPulse(mul(var, 100), var, -1, var), ch1)") assert s == str(sb)
def test_str(): seq = Sequence(reg, device) seq.declare_channel("ch0", "raman_local", initial_target="q0") pulse = Pulse.ConstantPulse(500, 2, -10, 0, post_phase_shift=np.pi) seq.add(pulse, "ch0") seq.delay(200, "ch0") seq.target("q7", "ch0") seq.measure("digital") msg = ("Channel: ch0\nt: 0 | Initial targets: q0 | Phase Reference: 0.0 " + "\nt: 0->500 | Pulse(Amp=2 rad/µs, Detuning=-10 rad/µs, Phase=0) " + "| Targets: q0\nt: 500->700 | Delay \nt: 700->700 | Target: q7 | " + "Phase Reference: 0.0\n\nMeasured in basis: digital") assert seq.__str__() == msg
def test_str(): seq = Sequence(reg, device) seq.declare_channel('ch0', 'raman_local', initial_target='q0') pulse = Pulse.ConstantPulse(500, 2, -10, 0, post_phase_shift=np.pi) seq.add(pulse, 'ch0') seq.delay(200, 'ch0') seq.target('q7', 'ch0') seq.measure('digital') msg = ('Channel: ch0\nt: 0 | Initial targets: q0 | Phase Reference: 0.0 ' + '\nt: 0->500 | Pulse(Amp=2 rad/µs, Detuning=-10 rad/µs, Phase=0) ' + '| Targets: q0\nt: 500->700 | Delay \nt: 700->700 | Target: q7 | ' + 'Phase Reference: 0.0\n\nMeasured in basis: digital') assert seq.__str__() == msg
def test_creation(): with pytest.raises(TypeError): Pulse(10, 0, 0, post_phase_shift=2) Pulse(cwf, 1, 0) Pulse(0, bwf, 1) Pulse(bwf, cwf, bwf) Pulse(bwf, cwf, 0, post_phase_shift=cwf) with pytest.raises(ValueError, match="The duration of"): Pulse(bwf, cwf, 0) with pytest.raises(ValueError, match="All samples of an amplitude"): Pulse(cwf, cwf, 0) Pulse.ConstantAmplitude(-1, cwf, 0) Pulse.ConstantPulse(100, -1, 0, 0) assert pls.phase == 0 assert pls2 == pls3 assert pls != pls4 assert pls4.detuning != cwf assert pls4.amplitude == pls.amplitude
def test_get_hamiltonian(): simple_reg = Register.from_coordinates([[10, 0], [0, 0]], prefix='atom') detun = 1. rise = Pulse.ConstantDetuning(RampWaveform(1500, 0., 2.), detun, 0.) simple_seq = Sequence(simple_reg, Chadoq2) simple_seq.declare_channel('ising', 'rydberg_global') simple_seq.add(rise, 'ising') simple_sim = Simulation(simple_seq, sampling_rate=0.01) with pytest.raises(ValueError, match='larger than'): simple_sim.get_hamiltonian(1650) with pytest.raises(ValueError, match='negative'): simple_sim.get_hamiltonian(-10) # Constant detuning, so |rr><rr| term is C_6/r^6 - 2*detuning for any time simple_ham = simple_sim.get_hamiltonian(143) assert (simple_ham[0, 0] == Chadoq2.interaction_coeff / 10**6 - 2 * detun)
def test_get_hamiltonian(): simple_reg = Register.from_coordinates([[10, 0], [0, 0]], prefix="atom") detun = 1.0 rise = Pulse.ConstantDetuning(RampWaveform(1500, 0.0, 2.0), detun, 0.0) simple_seq = Sequence(simple_reg, Chadoq2) simple_seq.declare_channel("ising", "rydberg_global") simple_seq.add(rise, "ising") simple_sim = Simulation(simple_seq, sampling_rate=0.01) with pytest.raises(ValueError, match="less than or equal to"): simple_sim.get_hamiltonian(1650) with pytest.raises(ValueError, match="greater than or equal to"): simple_sim.get_hamiltonian(-10) # Constant detuning, so |rr><rr| term is C_6/r^6 - 2*detuning for any time simple_ham = simple_sim.get_hamiltonian(143) assert np.isclose(simple_ham[0, 0], Chadoq2.interaction_coeff / 10**6 - 2 * detun) np.random.seed(123) simple_sim_noise = Simulation(simple_seq, config=SimConfig(noise="doppler", temperature=20000)) simple_ham_noise = simple_sim_noise.get_hamiltonian(144) assert np.isclose( simple_ham_noise.full(), np.array([ [ 4.47984523 + 0.0j, 0.09606404 + 0.0j, 0.09606404 + 0.0j, 0.0 + 0.0j, ], [ 0.09606404 + 0.0j, 12.03082372 + 0.0j, 0.0 + 0.0j, 0.09606404 + 0.0j, ], [ 0.09606404 + 0.0j, 0.0 + 0.0j, -12.97113702 + 0.0j, 0.09606404 + 0.0j, ], [0.0 + 0.0j, 0.09606404 + 0.0j, 0.09606404 + 0.0j, 0.0 + 0.0j], ]), ).all()
def test_results_xy(): q_dict = { "A": np.array([0.0, 0.0]), "B": np.array([0.0, 10.0]), } reg = Register(q_dict) duration = 1000 pi = Pulse.ConstantDetuning(BlackmanWaveform(duration, np.pi), 0.0, 0) seq = Sequence(reg, MockDevice) # Declare Channels seq.declare_channel("ch0", "mw_global") seq.add(pi, "ch0") seq.measure("XY") sim = Simulation(seq) results = sim.run() ground = qutip.tensor([qutip.basis(2, 1), qutip.basis(2, 1)]) assert results._dim == 2 assert results._size == 2 assert results._basis_name == "XY" assert results._meas_basis == "XY" assert results.states[0] == ground with pytest.raises(TypeError, match="Can't reduce a system in"): results.get_final_state(reduce_to_basis="all") with pytest.raises(TypeError, match="Can't reduce a system in"): results.get_final_state(reduce_to_basis="ground-rydberg") with pytest.raises(TypeError, match="Can't reduce a system in"): results.get_final_state(reduce_to_basis="digital") state = results.get_final_state(reduce_to_basis="XY") assert np.all( np.isclose(np.abs(state.full()), np.abs(results.states[-1].full()), atol=1e-5)) # Check that measurement projectors are correct assert results._meas_projector(0) == qutip.basis(2, 1).proj() assert results._meas_projector(1) == qutip.basis(2, 0).proj()
def test_creation(): with pytest.raises(TypeError): Pulse(10, 0, 0, post_phase_shift=2) Pulse(cwf, 1, 0) Pulse(0, bwf, 1) Pulse(bwf, cwf, bwf) Pulse(bwf, cwf, 0, post_phase_shift=cwf) with pytest.raises(ValueError, match="durations don't match"): Pulse(bwf, cwf, 0) with pytest.raises(ValueError, match="has always to be non-negative."): Pulse(cwf, cwf, 0) Pulse.ConstantAmplitude(-1, cwf, 0) Pulse.ConstantPulse(100, -1, 0, 0) assert pls.phase == 0 assert pls2.amplitude == pls3.amplitude assert pls2.detuning == pls3.detuning assert pls2.phase == np.pi assert pls3.phase == 1 assert pls4.detuning != cwf assert pls4.amplitude == pls.amplitude
def test_effective_size_disjoint(): simple_reg = Register.square(2, prefix="atom") rise = Pulse.ConstantPulse(1500, 0, 0, 0) for channel_type in ["mw_global", "rydberg_global", "raman_global"]: np.random.seed(15092021) seq = Sequence(simple_reg, MockDevice) seq.declare_channel("ch0", channel_type) seq.add(rise, "ch0") seq.config_slm_mask(["atom1"]) sim = Simulation(seq, sampling_rate=0.01) sim.set_config(SimConfig("SPAM", eta=0.4)) assert sim._bad_atoms == { "atom0": True, "atom1": False, "atom2": True, "atom3": False, } assert sim.get_hamiltonian(0) == 0 * sim.build_operator( [("I", "global")])
def test_initialization_and_construction_of_hamiltonian(): fake_sequence = {"pulse1": "fake", "pulse2": "fake"} with pytest.raises(TypeError, match="sequence has to be a valid"): Simulation(fake_sequence) sim = Simulation(seq, sampling_rate=0.011) assert sim._seq == seq assert sim._qdict == seq.qubit_info assert sim._size == len(seq.qubit_info) assert sim._tot_duration == duration * d assert sim._qid_index == {"control1": 0, "target": 1, "control2": 2} with pytest.raises(ValueError, match="too small, less than"): Simulation(seq, sampling_rate=0.0001) with pytest.raises(ValueError, match="`sampling_rate`"): Simulation(seq, sampling_rate=5) with pytest.raises(ValueError, match="`sampling_rate`"): Simulation(seq, sampling_rate=-1) assert sim._sampling_rate == 0.011 assert len(sim.sampling_times) == int(sim._sampling_rate * sim._tot_duration) assert isinstance(sim._hamiltonian, qutip.QobjEvo) # Checks adapt() method: assert bool(set(sim._hamiltonian.tlist).intersection(sim.sampling_times)) for qobjevo in sim._hamiltonian.ops: for sh in qobjevo.qobj.shape: assert sh == sim.dim**sim._size assert not seq.is_parametrized() seq_copy = seq.build() # Take a copy of the sequence x = seq_copy.declare_variable("x") seq_copy.add(Pulse.ConstantPulse(x, 1, 0, 0), "ryd") assert seq_copy.is_parametrized() with pytest.raises(ValueError, match="needs to be built"): Simulation(seq_copy) layout = RegisterLayout([[0, 0], [10, 10]]) mapp_reg = layout.make_mappable_register(1) seq_ = Sequence(mapp_reg, Chadoq2) assert seq_.is_register_mappable() and not seq_.is_parametrized() with pytest.raises(ValueError, match="needs to be built"): Simulation(seq_)
def test_measure(): pulse = Pulse.ConstantPulse(500, 2, -10, 0, post_phase_shift=np.pi) seq = Sequence(reg, MockDevice) seq.declare_channel("ch0", "rydberg_global") assert "XY" in MockDevice.supported_bases with pytest.raises(ValueError, match="not supported"): seq.measure(basis="XY") seq.measure() with pytest.raises(RuntimeError, match="already been measured"): seq.measure(basis="digital") with pytest.raises(RuntimeError, match="Nothing more can be added."): seq.add(pulse, "ch0") seq = Sequence(reg, MockDevice) seq.declare_channel("ch0", "mw_global") assert "digital" in MockDevice.supported_bases with pytest.raises(ValueError, match="not supported"): seq.measure(basis="digital") seq.measure(basis="XY")
def test_draw_register(): # Draw 2d register from sequence reg = Register({"q0": (0, 0), "q1": (10, 10), "q2": (-10, -10)}) targets = ["q0", "q2"] pulse = Pulse.ConstantPulse(100, 10, 0, 0) seq = Sequence(reg, MockDevice) seq.declare_channel("ch_xy", "mw_global") seq.add(pulse, "ch_xy") seq.config_slm_mask(targets) with patch("matplotlib.pyplot.show"): seq.draw(draw_register=True) # Draw 3d register from sequence reg3d = Register3D.cubic(3, 8) seq3d = Sequence(reg3d, MockDevice) seq3d.declare_channel("ch_xy", "mw_global") seq3d.add(pulse, "ch_xy") seq3d.config_slm_mask([6, 15]) with patch("matplotlib.pyplot.show"): seq3d.draw(draw_register=True)
def test_add_config(): reg = Register.from_coordinates([(0, 0)], prefix="q") seq = Sequence(reg, Chadoq2) seq.declare_channel("ch0", "rydberg_global") duration = 2500 pulse = Pulse.ConstantPulse(duration, np.pi, 0.0 * 2 * np.pi, 0) seq.add(pulse, "ch0") sim = Simulation(seq, sampling_rate=0.01, config=SimConfig(noise="SPAM", eta=0.5)) with pytest.raises(ValueError, match="is not a valid"): sim.add_config("bad_cfg") sim.add_config( SimConfig(noise=("dephasing", "SPAM", "doppler"), temperature=20000)) assert "dephasing" in sim.config.noise and "SPAM" in sim.config.noise assert sim.config.eta == 0.5 assert sim.config.temperature == 20000.0e-6 sim.set_config(SimConfig(noise="dephasing", laser_waist=175.0)) sim.add_config(SimConfig(noise=("SPAM", "amplitude"), laser_waist=172.0)) assert "amplitude" in sim.config.noise and "SPAM" in sim.config.noise assert sim.config.laser_waist == 172.0
def test_cuncurrent_pulses(): reg = Register({"q0": (0, 0)}) seq = Sequence(reg, Chadoq2) seq.declare_channel("ch_local", "rydberg_local", initial_target="q0") seq.declare_channel("ch_global", "rydberg_global") pulse = Pulse.ConstantPulse(20, 10, 0, 0) seq.add(pulse, "ch_local") seq.add(pulse, "ch_global", protocol="no-delay") # Clean simulation sim_no_noise = Simulation(seq) # Noisy simulation sim_with_noise = Simulation(seq) config_doppler = SimConfig(noise=("doppler")) sim_with_noise.set_config(config_doppler) for t in sim_no_noise.evaluation_times: ham_no_noise = sim_no_noise.get_hamiltonian(t) ham_with_noise = sim_with_noise.get_hamiltonian(t) assert ham_no_noise[0, 1] == ham_with_noise[0, 1]
def test_run_xy(): simple_reg = Register.from_coordinates([[10, 0], [0, 0]], prefix="atom") detun = 1.0 amp = 3.0 rise = Pulse.ConstantPulse(1500, amp, detun, 0.0) simple_seq = Sequence(simple_reg, MockDevice) simple_seq.declare_channel("ch0", "mw_global") simple_seq.add(rise, "ch0") sim = Simulation(simple_seq, sampling_rate=0.01) good_initial_array = np.r_[1, np.zeros(sim.dim**sim._size - 1)] good_initial_qobj = qutip.tensor( [qutip.basis(sim.dim, 0) for _ in range(sim._size)]) sim.initial_state = good_initial_array sim.run() sim.initial_state = good_initial_qobj sim.run() assert not hasattr(sim._seq, "_measurement") simple_seq.measure(basis="XY") sim.run() assert sim._seq._measurement == "XY"