예제 #1
0
    def remote_receive_one_qubit(self, virtualNum, cnot_direction=0):
        """
        Recover the qubit from teleportation.

        Arguments
        a,b		received measurement outcomes from Alice
        virtualNum	number of the virtual qubit corresponding to the EPR pair received
        """

        logging.debug("LOCAL %s: Getting reference to qubit number %d.",
                      self.node.name, virtualNum)

        # Get a reference to our side of the EPR pair
        qA = yield self.virtRoot.callRemote("get_virtual_ref", virtualNum)

        # Create a fresh qubit
        q = yield self.virtRoot.callRemote("new_qubit_inreg", self.qReg)

        # Create the GHZ state by entangling the fresh qubit
        if cnot_direction == 0:
            yield qA.callRemote("apply_H")
            yield qA.callRemote("cnot_onto", q)
        else:
            yield q.callRemote("apply_H")
            yield q.callRemote("cnot_onto", qA)

        if simulaqron_settings.sim_backend == SimBackend.QUTIP.value:
            # Output state
            (realRho,
             imagRho) = yield self.virtRoot.callRemote("get_multiple_qubits",
                                                       [qA, q])
            rho = assemble_qubit(realRho, imagRho)
            expectedRho = [[0.5, 0, 0, 0.5], [0, 0, 0, 0], [0, 0, 0, 0],
                           [0.5, 0, 0, 0.5]]
            correct = np.all(np.isclose(rho, expectedRho))
        elif simulaqron_settings.sim_backend == SimBackend.PROJECTQ.value:
            (realvec,
             imagvec) = yield self.virtRoot.callRemote("get_register_RI", qA)
            state = [r + (1j * j) for r, j in zip(realvec, imagvec)]
            expectedState = [1 / np.sqrt(2), 0, 0, 1 / np.sqrt(2)]
            correct = np.all(np.isclose(state, expectedState))
        elif simulaqron_settings.sim_backend == SimBackend.STABILIZER.value:
            (array, _) = yield self.virtRoot.callRemote("get_register_RI", qA)
            state = StabilizerState(array)
            expectedState = StabilizerState([[1, 1, 0, 0], [0, 0, 1, 1]])
            correct = state == expectedState
        else:
            ValueError("Unknown backend {}".format(
                simulaqron_settings.sim_backend))

        return bool(correct)
예제 #2
0
    def alice(cls, qReg, virtRoot, myName, classicalNet, send_end):
        """
        Code to execute for the local client node. Called if all connections are established.

        Arguments
        qReg		quantum register (twisted object supporting remote method calls)
        virtRoot	virtual quantum ndoe (twisted object supporting remote method calls)
        myName		name of this node (string)
        classicalNet	servers in the classical communication network (dictionary of hosts)
        """

        logging.debug("LOCAL %s: Runing client side program.", myName)
        # Create a second register
        newReg = yield virtRoot.callRemote("add_register")

        # Create 2 qubits
        qA = yield virtRoot.callRemote("new_qubit_inreg", qReg)
        qB = yield virtRoot.callRemote("new_qubit_inreg", newReg)

        # Put qubits A and B in an EPR state
        yield qA.callRemote("apply_H")
        yield qA.callRemote("cnot_onto", qB)

        if simulaqron_settings.sim_backend == SimBackend.QUTIP.value:
            # Output state
            (realRho,
             imagRho) = yield virtRoot.callRemote("get_multiple_qubits",
                                                  [qA, qB])
            rho = assemble_qubit(realRho, imagRho)
            expectedRho = [[0.5, 0, 0, 0.5], [0, 0, 0, 0], [0, 0, 0, 0],
                           [0.5, 0, 0, 0.5]]
            correct = np.all(np.isclose(rho, expectedRho))
        elif simulaqron_settings.sim_backend == SimBackend.PROJECTQ.value:
            (realvec, imagvec, _, _,
             _) = yield virtRoot.callRemote("get_register", qA)
            state = [r + (1j * j) for r, j in zip(realvec, imagvec)]
            expectedState = [1 / np.sqrt(2), 0, 0, 1 / np.sqrt(2)]
            correct = np.all(np.isclose(state, expectedState))
        elif simulaqron_settings.sim_backend == SimBackend.STABILIZER.value:
            (array, _, _, _, _) = yield virtRoot.callRemote("get_register", qA)
            state = StabilizerState(array)
            expectedState = StabilizerState([[1, 1, 0, 0], [0, 0, 1, 1]])
            correct = state == expectedState
        else:
            ValueError("Unknown backend {}".format(
                simulaqron_settings.sim_backend))

        send_end.send(correct)

        reactor.stop()
예제 #3
0
    def got_both(self):
        """
        Recover the qubit from Bob. We should now have a tripartite GHZ state

        Arguments
        virtualNum	number of the virtual qubit corresponding to the EPR pair received
        """

        logging.debug("LOCAL %s: Got both qubits from Alice and Bob.",
                      self.node.name)

        # We'll test an operation that will cause a merge of the two remote registers
        yield self.q1.callRemote("apply_H")
        yield self.q1.callRemote("cnot_onto", self.q2)

        if simulaqron_settings.sim_backend == SimBackend.QUTIP.value:
            # Output state
            (realRho,
             imagRho) = yield self.virtRoot.callRemote("get_multiple_qubits",
                                                       [self.q1, self.q2])
            rho = assemble_qubit(realRho, imagRho)
            expectedRho = [[0.5, 0, 0, 0.5], [0, 0, 0, 0], [0, 0, 0, 0],
                           [0.5, 0, 0, 0.5]]
            correct = np.all(np.isclose(rho, expectedRho))
        elif simulaqron_settings.sim_backend == SimBackend.PROJECTQ.value:
            (realvec,
             imagvec) = yield self.virtRoot.callRemote("get_register_RI",
                                                       self.q1)
            state = [r + (1j * j) for r, j in zip(realvec, imagvec)]
            expectedState = [1 / np.sqrt(2), 0, 0, 1 / np.sqrt(2)]
            correct = np.all(np.isclose(state, expectedState))
        elif simulaqron_settings.sim_backend == SimBackend.STABILIZER.value:
            (array,
             _) = yield self.virtRoot.callRemote("get_register_RI", self.q1)
            state = StabilizerState(array)
            expectedState = StabilizerState([[1, 1, 0, 0], [0, 0, 1, 1]])
            correct = state == expectedState
        else:
            ValueError("Unknown backend {}".format(
                simulaqron_settings.sim_backend))

        return bool(correct)
예제 #4
0
    def remote_recover_teleport(self, a, b, virtualNum):
        """
        Recover the qubit from teleportation.

        Arguments
        a,b        received measurement outcomes from Alice
        virtualNum    number of the virtual qubit corresponding to the EPR pair received
        """

        logging.debug("LOCAL %s: Getting reference to qubit number %d.",
                      self.node.name, virtualNum)

        eprB = yield self.virtRoot.callRemote("get_virtual_ref", virtualNum)

        # Apply the desired correction info
        logging.debug("LOCAL %s: Correction info is a=%d, b=%d.",
                      self.node.name, a, b)
        if b == 1:
            yield eprB.callRemote("apply_X")
        if a == 1:
            yield eprB.callRemote("apply_Z")

        # Just print the qubit we received
        if simulaqron_settings.backend == "qutip":
            print("here")
            (realRho, imagRho) = yield eprB.callRemote("get_qubit")
            state = np.array(assemble_qubit(realRho, imagRho), dtype=complex)
        elif simulaqron_settings.backend == "projectq":
            realvec, imagvec = yield self.virtRoot.callRemote(
                "get_register_RI", eprB)
            state = [r + (1j * j) for r, j in zip(realvec, imagvec)]
        elif simulaqron_settings.backend == "stabilizer":
            array, _, = yield self.virtRoot.callRemote("get_register_RI", eprB)
            state = StabilizerState(array)
        else:
            ValueError("Unknown backend {}".format(
                simulaqron_settings.backend))

        print("Qubit is:\n{}".format(state))
예제 #5
0
def runClientNode(qReg, virtRoot, myName, classicalNet):
    """
    Code to execute for the local client node. Called if all connections are established.

    Arguments
    qReg        quantum register (twisted object supporting remote method calls)
    virtRoot    virtual quantum ndoe (twisted object supporting remote method calls)
    myName        name of this node (string)
    classicalNet    servers in the classical communication network (dictionary of hosts)
    """

    logging.debug("LOCAL %s: Runing client side program.", myName)

    # Create 3 qubits
    q1 = yield virtRoot.callRemote("new_qubit_inreg", qReg)

    # Prepare the first one in the |-> state
    # yield q1.callRemote("apply_X")
    yield q1.callRemote("apply_H")

    # For information purposes, let's print the state of that qubit
    if simulaqron_settings.backend == "qutip":
        realRho, imagRho = yield q1.callRemote("get_qubit")
        state = np.array(assemble_qubit(realRho, imagRho), dtype=complex)
    elif simulaqron_settings.backend == "projectq":
        realvec, imagvec = yield virtRoot.callRemote("get_register_RI", q1)
        state = [r + (1j * j) for r, j in zip(realvec, imagvec)]
    elif simulaqron_settings.backend == "stabilizer":
        array, _ = yield virtRoot.callRemote("get_register_RI", q1)
        state = StabilizerState(array)
    else:
        ValueError("Unknown backend {}".format(simulaqron_settings.backend))

    print("Qubit to be teleported is:\n{}".format(state))

    # Create qubit for teleportation
    qA = yield virtRoot.callRemote("new_qubit_inreg", qReg)
    qB = yield virtRoot.callRemote("new_qubit_inreg", qReg)

    # Put qubits A and B in an EPR state
    yield qA.callRemote("apply_H")
    yield qA.callRemote("cnot_onto", qB)

    # Send qubit B to Bob
    # Instruct the virtual node to transfer the qubit
    remoteNum = yield virtRoot.callRemote("send_qubit", qB, "Bob")
    logging.debug("LOCAL %s: Remote qubit is %d.", myName, remoteNum)

    # Apply the local teleportation operations
    yield q1.callRemote("cnot_onto", qA)
    yield q1.callRemote("apply_H")

    a = yield q1.callRemote("measure")
    b = yield qA.callRemote("measure")
    logging.debug("LOCAL %s: Correction info is a=%d, b=%d.", myName, a, b)

    # Tell Bob the number of the virtual qubit so the can use it locally
    bob = classicalNet.hostDict["Bob"]
    yield bob.root.callRemote("recover_teleport", a, b, remoteNum)

    reactor.stop()