def pyzx_to_tk(pyzx_circ: pyzxCircuit) -> Circuit: """ Convert a :py:class:`pyzx.Circuit` to a :math:`\\mathrm{t|ket}\\rangle` :py:class:`Circuit` . All PyZX basic gate operations are currently supported by pytket. Run `pyzx_circuit_name.to_basic_gates()` before conversion. :param prog: A circuit to be converted :return: The converted circuit """ c = Circuit(pyzx_circ.qubits) for g in pyzx_circ.gates: if not g.name in _pyzx_to_tk_gates: raise Exception("Cannot parse PyZX gate of type " + g.name + "into tket Circuit") op_type = _pyzx_to_tk_gates[g.name] if (hasattr(g, 'control')): qbs = [getattr(g, 'control'), getattr(g, 'target')] else: qbs = [getattr(g, 'target')] if (hasattr(g, "printphase") and op_type in _parameterised_gates): op = c._get_op(OpType=op_type, param=float(g.phase)) else: op = c._get_op(OpType=op_type, parameters=[]) c._add_operation(Op=op, qubits=qbs) return c
def cirq_to_tk(circuit: cirq.Circuit) -> Circuit: """Converts a Cirq :py:class:`Circuit` to a :math:`\\mathrm{t|ket}\\rangle` :py:class:`Circuit` object. :param circuit: The input Cirq :py:class:`Circuit` :raises NotImplementedError: If the input contains a Cirq :py:class:`Circuit` operation which is not yet supported by pytket :return: The :math:`\\mathrm{t|ket}\\rangle` :py:class:`Circuit` corresponding to the input circuit """ qubit_list = _indexed_qubits_from_circuit(circuit) qid_to_num = {q: i for i, q in enumerate(qubit_list)} n_qubits = len(circuit.all_qubits()) tkcirc = Circuit(n_qubits) for moment in circuit: for op in moment.operations: gate = op.gate gatetype = type(gate) qb_lst = [qid_to_num[q] for q in op.qubits] n_qubits = len(op.qubits) if gatetype == cirq_common.HPowGate and gate.exponent == 1: gate = cirq_common.H elif gatetype == cirq_common.CNotPowGate and gate.exponent == 1: gate = cirq_common.CNOT elif gatetype == cirq_pauli._PauliX and gate.exponent == 1: gate = cirq_pauli.X elif gatetype == cirq_pauli._PauliY and gate.exponent == 1: gate = cirq_pauli.Y elif gatetype == cirq_pauli._PauliZ and gate.exponent == 1: gate = cirq_pauli.Z if gate in _constant_gates: try: optype = _cirq2ops_mapping[gate] except KeyError as error: raise NotImplementedError( "Operation not supported by tket: " + str(op.gate)) from error o = tkcirc._get_op(optype) elif isinstance(gate, cirq_common.MeasurementGate): o = tkcirc._get_op(OpType.Measure, n_qubits, n_qubits, gate.key) elif isinstance(gate, cirq.PhasedXPowGate): pe = gate.phase_exponent e = gate.exponent o = tkcirc._get_op(OpType.PhasedX, 1, 1, [e, pe]) else: try: optype = _cirq2ops_mapping[gatetype] except KeyError as error: raise NotImplementedError( "Operation not supported by tket: " + str(op.gate)) from error o = tkcirc._get_op(optype, n_qubits, n_qubits, gate.exponent) tkcirc._add_operation(o, qb_lst) return tkcirc
def pyquil_to_tk(prog: Program) -> Circuit: """ Convert a :py:class:`pyquil.Program` to a :math:`\\mathrm{t|ket}\\rangle` :py:class:`Circuit` . Note that not all pyQuil operations are currently supported by pytket. :param prog: A circuit to be converted :return: The converted circuit """ reg_name = None qubits = prog.get_qubits() n_qubits = max(qubits) + 1 tkc = Circuit(n_qubits) for i in prog.instructions: if isinstance(i, Gate): name = i.name try: optype = _known_quil_gate[name] except KeyError as error: raise NotImplementedError("Operation not supported by tket: " + str(i)) from error if len(i.params) == 0: tkc.add_operation(optype, [q.index for q in i.qubits]) else: params = [p / PI for p in i.params] op = tkc._get_op(optype, params) tkc._add_operation(op, [q.index for q in i.qubits]) elif isinstance(i, Measurement): if not i.classical_reg: raise NotImplementedError( "Program has no defined classical register for measurement on qubit: ", i.qubits[0]) reg = i.classical_reg if reg_name and reg_name != reg.name: raise NotImplementedError( "Program has multiple classical registers: ", reg_name, reg.name) reg_name = reg.name op = tkc._get_op(OpType.Measure, str(reg.offset)) tkc._add_operation(op, [i.qubit.index]) elif isinstance(i, Declare): continue elif isinstance(i, Pragma): continue elif isinstance(i, Halt): return tkc else: raise NotImplementedError("Pyquil instruction is not a gate: " + str(i)) return tkc
def _add_single_qubit_op_to_circuit(cmd:ProjectQCommand,circ:Circuit): 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 type(cmd.gate) in (pqo.Rx,pqo.Ry,pqo.Rz): op = circ._get_op(OpType=_pq_to_tk_singleqs[type(cmd.gate)],param=cmd.gate.angle/np.pi) else: op = circ._get_op(OpType=_pq_to_tk_singleqs[type(cmd.gate)]) if (qubit_no >= circ.n_qubits): circ.add_blank_wires(1+qubit_no-circ.n_qubits) new_qubit = True circ._add_operation(Op=op,qubits=[qubit_no]) return new_qubit
def _add_daggered_op_to_circuit(cmd:ProjectQCommand, circ:Circuit): undaggered_gate = cmd.gate.get_inverse() if (type(undaggered_gate) == pqo.TGate): op = circ._get_op(OpType=OpType.Tdg) elif (type(undaggered_gate) == pqo.SGate): op = circ._get_op(OpType=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_operation(Op=op,qubits=[qubit_no]) return new_qubit
def _add_multi_qubit_op_to_circuit(cmd:ProjectQCommand,circ:Circuit): 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 = circ._get_op(OpType=_pq_to_tk_multiqs[type(cmd.gate)],param=cmd.gate.angle/np.pi) else: op = circ._get_op(OpType=_pq_to_tk_multiqs[type(cmd.gate)]) qubit_nos = [qb.id for qr in cmd.all_qubits for qb in qr] circ._add_operation(Op = op, qubits=qubit_nos) return new_qubits