Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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