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}")
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()
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()