Skip to content

Commit 9cc04fe

Browse files
committed
examples: add a second generation repeater
The idealized quantum repeater from https://arxiv.org/pdf/0809.3629.pdf is modelled with three repeater stations. fixes: #91
1 parent 4c76943 commit 9cc04fe

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

examples/repeater/swap_and_distil.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
from dataclasses import dataclass
2+
3+
from qunetsim.components import Host
4+
from qunetsim.objects import Logger, Qubit
5+
from qunetsim.components import Network
6+
7+
Logger.DISABLED = True
8+
9+
10+
@dataclass()
11+
class Ebit:
12+
val: tuple[int, int]
13+
14+
def __str__(self):
15+
return {
16+
(0, 0): "phi+",
17+
(0, 1): "psi+",
18+
(1, 0): "phi-",
19+
(1, 1): "psi-",
20+
}[self.val]
21+
22+
@staticmethod
23+
def from_bell_measurement(a: Qubit, b: Qubit):
24+
a.cnot(b)
25+
a.H()
26+
return Ebit((a.measure(), b.measure()))
27+
28+
29+
def send_epr(host, right_host_id):
30+
a, b = Qubit(host), Qubit(host)
31+
a.H()
32+
a.cnot(b)
33+
host.send_qubit(right_host_id, b)
34+
return a
35+
36+
37+
DATA_QUBITS = 10
38+
39+
40+
def boundary_protocol(host, left_host_id, right_host_id):
41+
conn = None
42+
qubit = []
43+
44+
# Send an EPR qubit right; receive an EPR qubit from the left.
45+
for _ in range(DATA_QUBITS):
46+
if left_host_id is not None:
47+
conn = left_host_id
48+
qubit.append(host.get_qubit(conn, wait=-1))
49+
elif right_host_id is not None:
50+
conn = right_host_id
51+
qubit.append(send_epr(host, conn))
52+
else:
53+
raise ValueError('boundary node has no connection')
54+
55+
for i in range(DATA_QUBITS):
56+
# Apply local ops to transform |ab> into |Φ+> (modulo phase).
57+
msg = host.get_next_classical(conn, wait=-1).content
58+
59+
if left_host_id is None:
60+
if msg == 'psi-':
61+
qubit[i].Y()
62+
elif right_host_id is None:
63+
if msg == 'psi+':
64+
qubit[i].X()
65+
elif msg == 'phi-':
66+
qubit[i].Z()
67+
68+
# confirm that the boundaries are correlated
69+
print(f"{host.host_id} measures {qubit[i].measure()}")
70+
71+
72+
def repeater_protocol(host, left_host_id, right_host_id):
73+
for _ in range(DATA_QUBITS):
74+
# Swap. Send EPR right; receive from the left.
75+
q_right = send_epr(host, right_host_id)
76+
q_left = host.get_qubit(left_host_id, wait=-1)
77+
78+
# measure and broadcast
79+
ebit = Ebit.from_bell_measurement(q_left, q_right)
80+
host.send_broadcast(str(ebit))
81+
82+
83+
def main():
84+
network = Network.get_instance()
85+
nodes = ["Alice", "Polly", "Bob"]
86+
87+
network.start(nodes)
88+
network.delay = 0.1
89+
90+
alice = Host("Alice")
91+
alice.add_connection("Polly")
92+
alice.start()
93+
94+
polly = Host("Polly")
95+
polly.add_connection("Alice")
96+
polly.add_connection("Bob")
97+
polly.start()
98+
99+
bob = Host("Bob")
100+
bob.add_connection("Polly")
101+
bob.start()
102+
103+
network.add_host(alice)
104+
network.add_host(polly)
105+
network.add_host(bob)
106+
network.start()
107+
108+
t1 = alice.run_protocol(boundary_protocol, (None, polly.host_id))
109+
t2 = bob.run_protocol(boundary_protocol, (polly.host_id, None))
110+
_ = polly.run_protocol(repeater_protocol, (alice.host_id, bob.host_id))
111+
112+
t1.join()
113+
t2.join()
114+
115+
network.stop(True)
116+
117+
118+
if __name__ == "__main__":
119+
main()

0 commit comments

Comments
 (0)