def _add_single_qubit_op_to_circuit(cmd: ProjectQCommand, circ: Circuit) -> bool: assert len(cmd.qubits) == 1 assert len(cmd.qubits[0]) == 1 qubit_no = cmd.qubits[0][0].id new_qubit = False if get_control_count(cmd) > 0: raise Exception("singleq gate " + str(cmd.gate) + " has " + str(get_control_count(cmd)) + " control qubits") else: if qubit_no >= circ.n_qubits: circ.add_blank_wires(1 + qubit_no - circ.n_qubits) new_qubit = True if type(cmd.gate) == pqo.MeasureGate: bit = Bit("c", qubit_no) if bit not in circ.bits: circ.add_bit(bit) circ.Measure(qubit_no, qubit_no) return new_qubit elif type(cmd.gate) in (pqo.Rx, pqo.Ry, pqo.Rz): op = Op.create(_pq_to_tk_singleqs[type(cmd.gate)], cmd.gate.angle / np.pi) else: op = Op.create(_pq_to_tk_singleqs[type(cmd.gate)]) circ.add_gate(Op=op, args=[qubit_no]) return new_qubit
def pyzx_to_tk(pyzx_circ: pyzxCircuit) -> Circuit: """ Convert a :py:class:`pyzx.Circuit` to a tket :py:class:`Circuit` . All PyZX basic gate operations are currently supported by pytket. Run `pyzx_circuit_name.to_basic_gates()` before conversion. :param pyzx_circ: A circuit to be converted :return: The converted circuit """ c = Circuit(pyzx_circ.qubits, name=pyzx_circ.name) for g in pyzx_circ.gates: if not type(g) in _pyzx_to_tk_gates: raise Exception("Cannot parse PyZX gate of type " + g.name + "into tket Circuit") op_type = _pyzx_to_tk_gates[type(g)] if hasattr(g, "control"): qbs = [getattr(g, "control"), getattr(g, "target")] else: qbs = [getattr(g, "target")] if op_type == OpType.Sdg and not getattr(g, "adjoint"): op_type = OpType.S elif op_type == OpType.Tdg and not getattr(g, "adjoint"): op_type = OpType.T if hasattr(g, "printphase") and op_type in _parameterised_gates: op = Op.create(op_type, g.phase) else: op = Op.create(op_type) c.add_gate(Op=op, args=qbs) return c
def cmd_body(op: Op, qbs: List[int]) -> str: optype = op.type if optype == OpType.CCX: return "CCNOT(q[{}], q[{}], q[{}])".format(*qbs) elif optype == OpType.CX: return "CNOT(q[{}], q[{}])".format(*qbs) elif optype == OpType.PauliExpBox: paulis = op.get_paulis() theta = (-2 / pi) * op.get_phase() return "Exp([{}], {}, [{}])".format( ", ".join([qs_pauli[p] for p in paulis]), theta, ", ".join(["q[{}]".format(i) for i in qbs]), ) elif optype == OpType.H: return "H(q[{}])".format(*qbs) elif optype == OpType.noop: pass elif optype == OpType.Rx: return "Rx({}, q[{}])".format(pi * op.params[0], qbs[0]) elif optype == OpType.Ry: return "Ry({}, q[{}])".format(pi * op.params[0], qbs[0]) elif optype == OpType.Rz: return "Rz({}, q[{}])".format(pi * op.params[0], qbs[0]) elif optype == OpType.S: return "S(q[{}])".format(*qbs) elif optype == OpType.SWAP: return "SWAP(q[{}], q[{}])".format(*qbs) elif optype == OpType.T: return "T(q[{}])".format(*qbs) elif optype == OpType.X: return "X(q[{}])".format(*qbs) elif optype == OpType.Y: return "Y(q[{}])".format(*qbs) elif optype == OpType.Z: return "Z(q[{}])".format(*qbs) elif optype == OpType.CnX: return ( "ApplyMultiControlledC(" + ", ".join( [ "ApplyToFirstTwoQubitsCA(CNOT, _)", "CCNOTop(CCNOT)", "[{}]".format(", ".join(["q[{}]".format(i) for i in qbs[:-1]])), "[{}]".format("q[{}]".format(qbs[-1])), ] ) + ")" ) else: raise RuntimeError("Unsupported operation {}".format(optype))
def _add_daggered_op_to_circuit(cmd: ProjectQCommand, circ: Circuit) -> bool: undaggered_gate = cmd.gate.get_inverse() if type(undaggered_gate) == pqo.TGate: op = Op.create(OpType.Tdg) elif type(undaggered_gate) == pqo.SGate: op = Op.create(OpType.Sdg) else: raise Exception("cannot recognise daggered op of type " + str(cmd.gate)) qubit_no = cmd.qubits[0][0].id assert len(cmd.qubits) == 1 assert len(cmd.qubits[0]) == 1 new_qubit = False if qubit_no >= circ.n_qubits: circ.add_blank_wires(1 + qubit_no - circ.n_qubits) new_qubit = True circ.add_gate(Op=op, args=[qubit_no]) return new_qubit
def _add_multi_qubit_op_to_circuit(cmd: ProjectQCommand, circ: Circuit) -> list: assert len(cmd.qubits) > 0 qubs = [qb for qr in cmd.all_qubits for qb in qr] if get_control_count(cmd) < 1: raise Exception("multiq gate " + str(cmd.gate) + " has no controls") else: new_qubits = [] for q in qubs: qubit_no = q.id if qubit_no >= circ.n_qubits: circ.add_blank_wires(1 + qubit_no - circ.n_qubits) new_qubits.append(q) if type(cmd.gate) == pqo.CRz: op = Op.create(_pq_to_tk_multiqs[type(cmd.gate)], cmd.gate.angle / np.pi) else: op = Op.create(_pq_to_tk_multiqs[type(cmd.gate)]) qubit_nos = [qb.id for qr in cmd.all_qubits for qb in qr] circ.add_gate(Op=op, args=qubit_nos) return new_qubits