Esempio n. 1
0
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))
Esempio n. 4
0
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
Esempio n. 5
0
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