Skip to content

Commit

Permalink
examples: add a second generation repeater
Browse files Browse the repository at this point in the history
The idealized quantum repeater from https://arxiv.org/pdf/0809.3629.pdf
is modelled with three repeater stations.

fixes: tqsd#91
  • Loading branch information
atomgardner committed Jun 13, 2023
1 parent 4c76943 commit 9cc04fe
Showing 1 changed file with 119 additions and 0 deletions.
119 changes: 119 additions & 0 deletions examples/repeater/swap_and_distil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from dataclasses import dataclass

from qunetsim.components import Host
from qunetsim.objects import Logger, Qubit
from qunetsim.components import Network

Logger.DISABLED = True


@dataclass()
class Ebit:
val: tuple[int, int]

def __str__(self):
return {
(0, 0): "phi+",
(0, 1): "psi+",
(1, 0): "phi-",
(1, 1): "psi-",
}[self.val]

@staticmethod
def from_bell_measurement(a: Qubit, b: Qubit):
a.cnot(b)
a.H()
return Ebit((a.measure(), b.measure()))


def send_epr(host, right_host_id):
a, b = Qubit(host), Qubit(host)
a.H()
a.cnot(b)
host.send_qubit(right_host_id, b)
return a


DATA_QUBITS = 10


def boundary_protocol(host, left_host_id, right_host_id):
conn = None
qubit = []

# Send an EPR qubit right; receive an EPR qubit from the left.
for _ in range(DATA_QUBITS):
if left_host_id is not None:
conn = left_host_id
qubit.append(host.get_qubit(conn, wait=-1))
elif right_host_id is not None:
conn = right_host_id
qubit.append(send_epr(host, conn))
else:
raise ValueError('boundary node has no connection')

for i in range(DATA_QUBITS):
# Apply local ops to transform |ab> into |Φ+> (modulo phase).
msg = host.get_next_classical(conn, wait=-1).content

if left_host_id is None:
if msg == 'psi-':
qubit[i].Y()
elif right_host_id is None:
if msg == 'psi+':
qubit[i].X()
elif msg == 'phi-':
qubit[i].Z()

# confirm that the boundaries are correlated
print(f"{host.host_id} measures {qubit[i].measure()}")


def repeater_protocol(host, left_host_id, right_host_id):
for _ in range(DATA_QUBITS):
# Swap. Send EPR right; receive from the left.
q_right = send_epr(host, right_host_id)
q_left = host.get_qubit(left_host_id, wait=-1)

# measure and broadcast
ebit = Ebit.from_bell_measurement(q_left, q_right)
host.send_broadcast(str(ebit))


def main():
network = Network.get_instance()
nodes = ["Alice", "Polly", "Bob"]

network.start(nodes)
network.delay = 0.1

alice = Host("Alice")
alice.add_connection("Polly")
alice.start()

polly = Host("Polly")
polly.add_connection("Alice")
polly.add_connection("Bob")
polly.start()

bob = Host("Bob")
bob.add_connection("Polly")
bob.start()

network.add_host(alice)
network.add_host(polly)
network.add_host(bob)
network.start()

t1 = alice.run_protocol(boundary_protocol, (None, polly.host_id))
t2 = bob.run_protocol(boundary_protocol, (polly.host_id, None))
_ = polly.run_protocol(repeater_protocol, (alice.host_id, bob.host_id))

t1.join()
t2.join()

network.stop(True)


if __name__ == "__main__":
main()

0 comments on commit 9cc04fe

Please sign in to comment.