<jupyter_start><jupyter_text>In the quantum teleportation protocol, party A will teleport a qubit state of qubit q to party B by utilizing quantum teleportation. Party A and B each have one qubit of an entangled bell pair. A first entangles their bell pair with the q, using a cnot gate with the bell pair being the target. They then do a hadmard gate on q. After that, they measure both q and their bell pair. A then classically sends the results of both measurements to B. B will then perform 0-2 quantum gates on their bell pair to get it back to q's original state based on the measurement results. If A's bell pair measured 1, B will do an X gate on their bell pair. If q measured 1, B will do a Z gate on their bell pair. B now has q's original state in their bell pair. A bell pair that both parties have one half of is needed for this to be possible.<jupyter_code>!pip install qiskit
from cmath import isclose
from math import sqrt

from qiskit import QuantumCircuit, Aer, execute
from qiskit.extensions import Initialize
from qiskit.visualization import plot_histogram
class Node:
    
    def __init__(self, psi = None):
        self.psi = psi
        
    def __str__(self):
        return str(self.psi)
class QuantumInternet:
    
    def __init__(self, nodes):
        self.__nodes = nodes
        self.__qc = None
    
    def __gen_bell_pair(self, ctrl, target):
        self.__qc.h(ctrl)
        self.__qc.cx(ctrl, target)

    def __sim(self):
        backend_sim = Aer.get_backend("statevector_simulator")
        sim = execute(self.__qc, backend_sim)
        return sim.result()
        
    def size(self):
        return len(self.__nodes);
    
    def teleport(self, sender, receiver):
        if sender < len(self.__nodes) and receiver < len(self.__nodes):
            data = 0
            src = 1
            dst = 2

            self.__qc = QuantumCircuit(3, 3)
            init = Initialize(self.__nodes[sender].psi)
            init.label = "init"
            self.__qc.append(init, [data])
            self.__gen_bell_pair(1, 2)
            
            self.__qc.cx(data, src)
            self.__qc.h(data)

            self.__qc.measure(data, data)
            self.__qc.measure(src, src)

            self.__qc.cx(src, dst)
            self.__qc.cz(data, dst)

            state = self.__sim().get_statevector()
            alpha_index = 0
            alpha = 0
            
            # index between statevector indices with dst measured as 0 and the indices with it measured as 1
            state_border = int((2 ** self.__qc.num_qubits) / 2)
            for i in range(state_border):
                if abs(state[i]) > abs(alpha):
                    alpha = state[i]
                    alpha_index = i
                    
            beta = max(state[state_border : ], key = abs)
            # set receiver node's psi to the outcome
            self.__nodes[receiver].psi = [alpha, beta] 
            
            sender_psi_0 = (alpha_index % 2 == 0)
            # set sender node's psi to the measurement outcome of their previous psi
            self.__nodes[sender].psi = [int(sender_psi_0), int(not sender_psi_0)]  
        else:
            print("Index %d or %d out of bounds of length %u" % (sender, receiver, len(self.__nodes)))
init_psi = [1j / sqrt(3), -sqrt(2 / 3)]
print("initial: %s" % init_psi)

a = Node(init_psi)
b = Node()
c = Node()
d = Node()

internet = QuantumInternet([a, b, c, d])
for i in range(internet.size() - 1):
    internet.teleport(i, i + 1)

print("a: %s" % a)
print("b: %s" % b)
print("c: %s" % c)
print("d: %s" % d)

success = True
for i in range(len(d.psi)):
    if not isclose(d.psi[i], init_psi[i]):
        success = False
        break
print("Qubit state successfully teleported across internet: %r" % success)<jupyter_output>initial: [0.5773502691896258j, -0.816496580927726]
a: [1, 0]
b: [0, 1]
c: [0, 1]
d: [0.5773502691896257j, (-0.8164965809277259+2.999759773043692e-16j)]
Qubit state successfully teleported across internet: True
{'fraction_non_alphanumeric': 0.09713574097135741, 'fraction_numerical': 0.02963885429638854, 'mean_word_length': 2.338320864505403, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '658679', 'license': 'MIT', 'n_tokens_mistral': 1329, 'n_tokens_neox': 1207, 'n_words': 437, 'path': 'qiskit/quantum_internet.ipynb', 'repo_name': 'milind-u/quantum-computing', 'size': '4015'}