예제 #1
0
    def generate_program(cls, nqbits: int):
        pr = Program()
        # TODO extend to nqbits
        nqbits = 1
        to_teleport = pr.qalloc(nqbits)
        to_teleport_c = pr.calloc(nqbits)
        epr_pair_a = pr.qalloc()
        epr_pair_a_c = pr.calloc()
        epr_pair_b = pr.qalloc()

        # Prepare EPR pair
        pr.apply(H, *epr_pair_a)
        pr.apply(CNOT, *epr_pair_a, *epr_pair_b)

        # Prepare random state using 3 random rotation around the 3 axis
        pr.apply(RY(random() * pi), *to_teleport)
        pr.apply(RX(random() * pi), *to_teleport)
        pr.apply(RZ(random() * pi), *to_teleport)

        # Encode
        pr.apply(CNOT, *to_teleport, *epr_pair_a)
        pr.apply(H, *to_teleport)

        # Teleport
        pr.measure(to_teleport, to_teleport_c)
        pr.measure(epr_pair_a, epr_pair_a_c)

        # Decode
        pr.cc_apply(epr_pair_a_c[0], X, epr_pair_b[0])
        pr.cc_apply(to_teleport_c[0], Z, epr_pair_b[0])

        return pr, None
def make_c_control_circuit():
    prog = Program()
    qbits = prog.qalloc(2)
    cbits = prog.calloc(2)
    prog.apply(X, qbits[0])
    prog.measure(qbits[0], cbits[0])
    prog.cc_apply(cbits[0], X, qbits[1])
    prog.measure(qbits[1], cbits[1])
    return prog.to_circ()
def main():
    # _a is for Alice, _b is for Bob, _c is for classical
    pr = Program()
    to_teleport = pr.qalloc()
    epr_pair_a = pr.qalloc()
    epr_pair_a_c = pr.calloc()
    to_teleport_c = pr.calloc()
    epr_pair_b = pr.qalloc()

    # Prepare EPR pair
    pr.apply(H, *epr_pair_a)
    pr.apply(CNOT, *epr_pair_a, *epr_pair_b)
    # Now Alice has her half of the EPR pair (epr_pair_a) and Bob the other one
    # (epr_pair_b qubit)

    # Prepare random state on the qubit(s) to teleport
    pr.apply(RY(random() * pi), *to_teleport)
    pr.apply(RX(random() * pi), *to_teleport)
    pr.apply(RZ(random() * pi), *to_teleport)

    # At this point we make a copy of the original program. The idea is to show
    # the state we would obtain if we would stop at this stage, before the
    # teleportation.
    pr2 = deepcopy(pr)

    # We continue with the teleportation circuit

    # Alice interact her to_teleport_qubit with her half of the EPR pair
    pr.apply(CNOT, *to_teleport, *epr_pair_a)
    pr.apply(H, *to_teleport)
    # ... and then she measures her 2 qubits
    pr.measure(to_teleport, to_teleport_c)
    pr.measure(epr_pair_a, epr_pair_a_c)

    # She then sends her measured qubits to Bob which, depending on their value
    # being 0 or 1, performs the classically controlled X and Z on his own half of the EPR pair
    pr.cc_apply(epr_pair_a_c[0], X, epr_pair_b[0])
    pr.cc_apply(to_teleport_c[0], Z, epr_pair_b[0])

    #
    circ = pr.to_circ()
    circ2 = pr2.to_circ()

    # simulation
    qpu = PyLinalg()
    res = qpu.submit(circ.to_job(qubits=[epr_pair_b]))
    res2 = qpu.submit(circ2.to_job(qubits=[to_teleport]))

    print("Original state, measured on to_teleport qubit")
    for sample in res2:
        # print(f"state {sample.state} with amplitude {sample.amplitude} and probability {sample.probability}")
        print(f"state {sample.state} with amplitude {sample.probability}")
    print("Teleported state, measured on ")
    for sample in res:
        print(f"state {sample.state} with probability {sample.probability}")
예제 #4
0
def generate_boolean():
    prog = Program()
    qbits = prog.qalloc(3)
    cbits = prog.calloc(3)
    prog.apply(X, qbits[1])
    prog.measure(qbits[0], cbits[0])
    prog.measure(qbits[1], cbits[1])
    prog.logic(cbits[2], cbits[1] & ~cbits[0])
    prog.cc_apply(cbits[2], X, qbits[2])
    prog.apply(X, qbits[0])
    return prog.to_circ()
예제 #5
0
def generate_teleportation(split_measures: bool):
    """
    Generates a circuit corresponding to the teleportation
    circuit

    Args:
        split_measures (bool): split measures

    Returns:
        :class:`~qat.core.Circuit`: generated circuit
    """
    # Init program
    prog = Program()
    source = prog.qalloc(1)
    bell_pair = prog.qalloc(2)
    cbits = prog.calloc(2)

    # Init source qubit
    prog.apply(RX(1.23), source)
    prog.apply(RZ(4.56), source)

    # Init Bell pair
    prog.apply(H, bell_pair[0])
    prog.apply(CNOT, bell_pair)

    # Bell pair measurement between source qubit and bell_pair[0]
    prog.apply(CNOT, source, bell_pair[0])
    prog.apply(H, source)

    if split_measures:
        prog.measure(source[0], cbits[0])
        prog.measure(bell_pair[0], cbits[1])

    else:
        prog.measure([source[0], bell_pair[0]], cbits)

    # Classic control
    prog.cc_apply(cbits[1], X, bell_pair[1])
    prog.cc_apply(cbits[0], Z, bell_pair[1])

    # Return circuit
    return prog.to_circ()