def test_polarization_get(): tl = Timeline() tl.seed(0) detectors = [{"efficiency": 1}] * 4 bsm = make_bsm("bsm", tl, encoding_type="polarization", detectors=detectors) parent = Parent() bsm.attach(parent) # get 2 photons in orthogonal states (map to Psi+) p1 = Photon("p1", location=1, quantum_state=(complex(1), complex(0))) p2 = Photon("p2", location=2, quantum_state=(complex(0), complex(1))) bsm.get(p1) bsm.get(p2) assert len(parent.results) == 1 # get 2 photons in same state (map to Phi+ / can't measure) tl.time = 1e6 p3 = Photon("p3", location=1, quantum_state=(complex(1), complex(0))) p4 = Photon("p4", location=2, quantum_state=(complex(1), complex(0))) bsm.get(p3) bsm.get(p4) assert len(parent.results) == 1
def test_time_bin_update(): tl = Timeline() tl.seed(0) detectors = [{}] * 2 bsm = make_bsm("bsm", tl, encoding_type="time_bin", detectors=detectors) parent = Parent() bsm.attach(parent) detector_list = bsm.detectors # test Psi+ bsm.trigger(detector_list[0], {'time': 0}) bsm.trigger(detector_list[0], {'time': 0 + time_bin["bin_separation"]}) assert len(parent.results) == 1 assert parent.results[0] == 0 # test Psi- bsm.trigger(detector_list[0], {'time': 1e6}) bsm.trigger(detector_list[1], {'time': 1e6 + time_bin["bin_separation"]}) assert len(parent.results) == 2 assert parent.results[1] == 1 # test invalid time separation bsm.trigger(detector_list[0], {'time': 2e6}) bsm.trigger(detector_list[0], {'time': 2e6}) assert len(parent.results) == 2 bsm.trigger(detector_list[0], {'time': 3e6}) bsm.trigger(detector_list[0], {'time': 4e6}) assert len(parent.results) == 2
def test_base_get(): tl = Timeline() tl.seed(0) photon1 = Photon("", location=1) photon2 = Photon("", location=2) photon3 = Photon("", location=3) photon1_2 = Photon("", location=1) detectors = [{}] * 2 bsm = make_bsm("bsm", tl, encoding_type="time_bin", detectors=detectors) bsm.get(photon1) assert len(bsm.photons) == 1 # same location bsm.get(photon1_2) assert len(bsm.photons) == 1 # different location bsm.get(photon2) assert len(bsm.photons) == 2 # later time tl.time = 1 bsm.get(photon3) assert len(bsm.photons) == 1
def test_construct_func(): tl = Timeline() tl.seed(0) detectors2 = [{}] * 2 detectors4 = [{}] * 4 # unknown encoding scheme with pytest.raises(Exception): bsm = make_bsm("bsm", tl, encoding_type="unknown", detectors=detectors4) # implemented encoding schemes polar_bsm = make_bsm("bsm", tl, encoding_type="polarization", detectors=detectors4) time_bin_bsm = make_bsm("bsm", tl, encoding_type="time_bin", detectors=detectors2) atom_bsm = make_bsm("bsm", tl, encoding_type="single_atom", detectors=detectors2) assert type(polar_bsm) == PolarizationBSM assert type(time_bin_bsm) == TimeBinBSM assert type(atom_bsm) == SingleAtomBSM
def test_QSDetectorTimeBin(): tl = Timeline() tl.seed(1) qsdetector = QSDetectorTimeBin("qsd", tl) [qsdetector.update_detector_params(i, "efficiency", 1) for i in range(3)] frequency = 1e5 start_time = 0 basis_list = [random.randint(2) for _ in range(1000)] qsdetector.set_basis_list(basis_list, start_time, frequency) for i in range(1000): tl.time = i * 1e12 / frequency basis = basis_list[i] bit = random.randint(2) photon = Photon(str(i), encoding_type=time_bin, quantum_state=time_bin["bases"][basis][bit]) qsdetector.get(photon) tl.time = 0 tl.run() trigger_times = qsdetector.get_photon_times() length = len(trigger_times[0] + trigger_times[1] + trigger_times[2]) assert abs(length / 1000 - 7 / 8) < 0.1
def test_QSDetectorPolarization_update_detector_params(): tl = Timeline() tl.seed(1) qsdetector = QSDetectorPolarization("qsd", tl) qsdetector.update_detector_params(0, "dark_count", 99) assert qsdetector.detectors[ 0].dark_count == 99 and qsdetector.detectors[1].dark_count != 99
def test_init(): tl = Timeline() tl.seed(0) detectors = [{"dark_count": 1}] * 2 bsm = make_bsm("bsm", tl, encoding_type="time_bin", detectors=detectors) tl.init() assert len(tl.events) == len(detectors) * 2
def test_QSDetectorPolarization_update_splitter_params(): fidelity = 0.9 tl = Timeline() tl.seed(1) qsdetector = QSDetectorPolarization("qsd", tl) qsdetector.update_splitter_params("fidelity", fidelity) assert qsdetector.splitter.fidelity == fidelity
def test_single_atom_get(): class PhotonSendWrapper(): def __init__(self, mem1, mem2, bsm): self.bsm = bsm mem1.owner = self mem2.owner = self def send_qubit(self, dst, photon): self.bsm.get(photon) tl = Timeline() tl.seed(0) detectors = [{"efficiency": 1}] * 2 bsm = make_bsm("bsm", tl, encoding_type="single_atom", detectors=detectors) parent = Parent() bsm.attach(parent) mem_1 = Memory("mem_1", tl, fidelity=1, frequency=0, efficiency=1, coherence_time=1, wavelength=500) mem_2 = Memory("mem_2", tl, fidelity=1, frequency=0, efficiency=1, coherence_time=1, wavelength=500) pw = PhotonSendWrapper(mem_1, mem_2, bsm) # initially opposite states tl.time = 0 mem_1.update_state([complex(1), complex(0)]) mem_2.update_state([complex(0), complex(1)]) mem_1.excite() # send w/o destination as have direct_receiver set mem_2.excite() assert len(parent.results) == 1 # flip state and resend tl.time = 1e6 circ = Circuit(1) circ.x(0) tl.quantum_manager.run_circuit(circ, [mem_1.qstate_key]) tl.quantum_manager.run_circuit(circ, [mem_2.qstate_key]) mem_1.excite() mem_2.excite() assert len(parent.results) == 2 # check that we've entangled assert len(tl.quantum_manager.get(mem_1.qstate_key).state) == 4 assert tl.quantum_manager.get(mem_1.qstate_key) is tl.quantum_manager.get( mem_2.qstate_key)
def test_QSDetector_update(): tl = Timeline() tl.seed(1) qsdetector = QSDetectorPolarization("qsd", tl) args = [[0, 10], [1, 20], [1, 40]] for arg in args: qsdetector.trigger(qsdetector.detectors[arg[0]], {'time': arg[1]}) trigger_times = qsdetector.trigger_times assert trigger_times[arg[0]][-1] == arg[1]
def create_scenario(state1, state2, seed): tl = Timeline() tl.seed(seed) a1 = FakeNode("a1", tl) a2 = FakeNode("a2", tl) a3 = FakeNode("a3", tl) cc0 = ClassicalChannel("a2-a1", tl, 0, 1e5) cc1 = ClassicalChannel("a2-a3", tl, 0, 1e5) cc0.set_ends(a2, a1) cc1.set_ends(a2, a3) tl.init() memo1 = Memory("a1.0", timeline=tl, fidelity=0.9, frequency=0, efficiency=1, coherence_time=1, wavelength=500) memo2 = Memory("a2.0", tl, 0.9, 0, 1, 1, 500) memo3 = Memory("a2.1", tl, 0.9, 0, 1, 1, 500) memo4 = Memory("a3.0", tl, 0.9, 0, 1, 1, 500) memo1.fidelity = memo2.fidelity = memo3.fidelity = memo4.fidelity = 1 memo1.entangled_memory = {'node_id': 'a2', 'memo_id': memo2.name} memo2.entangled_memory = {'node_id': 'a1', 'memo_id': memo1.name} memo3.entangled_memory = {'node_id': 'a3', 'memo_id': memo4.name} memo4.entangled_memory = {'node_id': 'a2', 'memo_id': memo3.name} tl.quantum_manager.set([memo1.qstate_key, memo2.qstate_key], state1) tl.quantum_manager.set([memo3.qstate_key, memo4.qstate_key], state2) es1 = EntanglementSwappingB(a1, "a1.ESb0", memo1) a1.protocols.append(es1) es2 = EntanglementSwappingA(a2, "a2.ESa0", memo2, memo3) a2.protocols.append(es2) es3 = EntanglementSwappingB(a3, "a3.ESb1", memo4) a3.protocols.append(es3) es1.set_others(es2) es3.set_others(es2) es2.set_others(es1) es2.set_others(es3) es2.start() tl.run() ket1, ket2, ket3, ket4 = map(tl.quantum_manager.get, [memo1.qstate_key, memo2.qstate_key, memo3.qstate_key, memo4.qstate_key]) assert id(ket1) == id(ket4) assert id(ket2) != id(ket3) assert len(ket1.keys) == 2 and memo1.qstate_key in ket1.keys and memo4.qstate_key in ket1.keys assert len(ket2.keys) == 1 assert memo2.entangled_memory == memo3.entangled_memory == {'node_id': None, 'memo_id': None} assert memo1.entangled_memory["node_id"] == "a3" and memo4.entangled_memory["node_id"] == "a1" assert a1.resource_manager.log[-1] == (memo1, "ENTANGLED") assert a3.resource_manager.log[-1] == (memo4, "ENTANGLED") return ket1, ket2, ket3, ket4, a3
def test_QSDetectorPolarization_set_basis_list(): tl = Timeline() tl.seed(1) qsdetector = QSDetectorPolarization("qsd", tl) basis_list = [] start_time = 0 frequency = 1e6 qsdetector.set_basis_list(basis_list, start_time, frequency) assert qsdetector.splitter.basis_list == basis_list and \ qsdetector.splitter.start_time == start_time and \ qsdetector.splitter.frequency == frequency
def create_detector(efficiency=0.9, dark_count=0, count_rate=25e6, time_resolution=150): class Parent(): def __init__(self, tl): self.timeline = tl self.log = [] def trigger(self, detector, msg): self.log.append((self.timeline.now(), msg['time'], detector)) tl = Timeline() tl.seed(1) detector = Detector("", tl, efficiency=efficiency, dark_count=dark_count, count_rate=count_rate, time_resolution=time_resolution) parent = Parent(tl) detector.attach(parent) return detector, parent, tl
def test_time_bin_get(): tl = Timeline() tl.seed(0) detectors = [{"efficiency": 1, "count_rate": 1e9}] * 2 bsm = make_bsm("bsm", tl, encoding_type="time_bin", detectors=detectors) parent = Parent() bsm.attach(parent) detector_list = bsm.detectors # get 2 photons in orthogonal states (map to Psi+) p1 = Photon("p1", encoding_type=time_bin, location=1, quantum_state=(complex(1), complex(0))) p2 = Photon("p2", encoding_type=time_bin, location=2, quantum_state=(complex(0), complex(1))) process = Process(bsm, "get", [p1]) event = Event(0, process) tl.schedule(event) process = Process(bsm, "get", [p2]) event = Event(0, process) tl.schedule(event) tl.run() assert len(parent.results) == 1 # get 2 photons in same state (map to Phi+ / can't measure) p3 = Photon("p3", encoding_type=time_bin, location=1, quantum_state=(complex(1), complex(0))) p4 = Photon("p4", encoding_type=time_bin, location=2, quantum_state=(complex(1), complex(0))) process = Process(bsm, "get", [p3]) event = Event(1e6, process) tl.schedule(event) process = Process(bsm, "get", [p4]) event = Event(1e6, process) tl.schedule(event) tl.run() assert len(parent.results) == 1
def create_scenario(state1, state2, seed): tl = Timeline() tl.seed(seed) a1 = FakeNode("a1", tl) a2 = FakeNode("a2", tl) cc0 = ClassicalChannel("cc0", tl, 0, 1e5) cc1 = ClassicalChannel("cc1", tl, 0, 1e5) cc0.delay = ONE_MILLISECOND cc1.delay = ONE_MILLISECOND cc0.set_ends(a1, a2) cc1.set_ends(a2, a1) kept1 = Memory('kept1', tl, fidelity=1, frequency=0, efficiency=1, coherence_time=1, wavelength=HALF_MICRON) kept2 = Memory('kept2', tl, fidelity=1, frequency=0, efficiency=1, coherence_time=1, wavelength=HALF_MICRON) meas1 = Memory('mea1', tl, fidelity=1, frequency=0, efficiency=1, coherence_time=1, wavelength=HALF_MICRON) meas2 = Memory('mea2', tl, fidelity=1, frequency=0, efficiency=1, coherence_time=1, wavelength=HALF_MICRON) tl.init() tl.quantum_manager.set([kept1.qstate_key, kept2.qstate_key], state1) tl.quantum_manager.set([meas1.qstate_key, meas2.qstate_key], state2) kept1.entangled_memory = {'node_id': 'a2', 'memo_id': 'kept2'} kept2.entangled_memory = {'node_id': 'a1', 'memo_id': 'kept1'} meas1.entangled_memory = {'node_id': 'a2', 'memo_id': 'meas2'} meas2.entangled_memory = {'node_id': 'a1', 'memo_id': 'meas1'} kept1.fidelity = kept2.fidelity = meas1.fidelity = meas2.fidelity = 1 ep1 = BBPSSW(a1, "a1.ep1", kept1, meas1) ep2 = BBPSSW(a2, "a2.ep2", kept2, meas2) a1.protocols.append(ep1) a2.protocols.append(ep2) ep1.set_others(ep2) ep2.set_others(ep1) ep1.start() ep2.start() tl.run() assert meas1.entangled_memory == meas2.entangled_memory == {'node_id': None, 'memo_id': None} return tl, kept1, kept2, meas1, meas2, ep1, ep2
def test_QSDetectorPolarization(): tl = Timeline() tl.seed(1) qsdetector = QSDetectorPolarization("qsd", tl) qsdetector.update_detector_params(0, "efficiency", 1) qsdetector.update_detector_params(1, "efficiency", 1) frequency = 1e5 start_time = 0 basis_list = [random.randint(2) for _ in range(1000)] qsdetector.set_basis_list(basis_list, start_time, frequency) for i in range(1000): tl.time = i * 1e12 / frequency basis = basis_list[i] bit = random.randint(2) photon = Photon(str(i), quantum_state=polarization["bases"][basis][bit]) qsdetector.get(photon) trigger_times = qsdetector.get_photon_times() length = len(trigger_times[0] + trigger_times[1]) assert length == 1000 assert qsdetector.get_photon_times() == [[], []]
def test_polarization_update(): tl = Timeline() tl.seed(0) detectors = [{"time_resolution": 1}] * 4 bsm = make_bsm("bsm", tl, encoding_type="polarization", detectors=detectors) parent = Parent() bsm.attach(parent) detector_list = bsm.detectors # test Psi+ bsm.trigger(detector_list[0], {'time': 0}) bsm.trigger(detector_list[1], {'time': 0}) assert len(parent.results) == 1 assert parent.results[0] == 0 # test Psi- bsm.trigger(detector_list[0], {'time': 1}) bsm.trigger(detector_list[3], {'time': 1}) assert len(parent.results) == 2 assert parent.results[1] == 1 # test not matching times bsm.trigger(detector_list[0], {'time': 2}) bsm.trigger(detector_list[3], {'time': 3}) assert len(parent.results) == 2 # test invalid measurement bsm.trigger(detector_list[0], {'time': 4}) bsm.trigger(detector_list[2], {'time': 4}) assert len(parent.results) == 2
def test_QSDetectorPolarization_init(): tl = Timeline() tl.seed(1) qsdetector = QSDetectorPolarization("qsd", tl) tl.init()
NUM_EXPERIMENTS = 10 runtime = 12e12 dist_list = [] tp_list = [] key_error_list = [] latency_list = [] setup_time_list = [] start_time_list = [] bb84_latency_list = [] for id in range(NUM_EXPERIMENTS): distance = max(1000, 10000 * int(id)) tl = Timeline(runtime) tl.seed(2) tl.show_progress = True qc0 = QuantumChannel("qc0", tl, distance=distance, polarization_fidelity=0.97, attenuation=0.0002) qc1 = QuantumChannel("qc1", tl, distance=distance, polarization_fidelity=0.97, attenuation=0.0002) cc0 = ClassicalChannel("cc0", tl, distance=distance) cc1 = ClassicalChannel("cc1", tl, distance=distance) cc0.delay += 10e9
runtime = 1e12 dark_count = 425 distances = [1] # distances = [1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120] # distances in km errors = [] # store error rates throughputs = [] # store throughputs latencies = [] # store latencies # open file to store experiment results Path("results/timebin").mkdir(parents=True, exist_ok=True) filename = "results/timebin/distance_no_cascade.log" fh = open(filename, 'w') for distance in distances: tl = Timeline(runtime) tl.seed(1) qc = QuantumChannel("qc", tl, distance=distance * 1e3, attenuation=0.0002) cc = ClassicalChannel("cc", tl, distance=distance * 1e3) # Alice ls_params = {"frequency": 2e6, "mean_photon_num": 0.1} alice = QKDNode("alice", tl, encoding=time_bin, stack_size=1) for name, param in ls_params.items(): alice.update_lightsource_params(name, param) # Bob detector_params = [{