def test_mixed_circuit() -> None:
    c = Circuit()
    qr = c.add_q_register("q", 2)
    ar = c.add_c_register("a", 1)
    br = c.add_c_register("b", 1)
    c.H(qr[0])
    c.Measure(qr[0], ar[0])
    c.X(qr[1], condition=reg_eq(ar, 0))
    c.Measure(qr[1], br[0])
    backend = AerBackend()
    backend.compile_circuit(c)
    counts = backend.get_counts(c, 1024)
    for key in counts.keys():
        assert key in {(0, 1), (1, 0)}
Example #2
0
def test_nondefault_registers() -> None:
    c = Circuit()

    qreg = c.add_q_register("g", 3)
    creg1 = c.add_c_register("a", 3)
    creg2 = c.add_c_register("b", 3)

    c.X(qreg[1])
    c.X(qreg[0])
    c.Measure(qreg[1], creg1[1])
    c.Measure(qreg[0], creg2[0])

    b = QsharpSimulatorBackend()
    b.compile_circuit(c)
    counts = b.get_result(b.process_circuit(c, 10)).get_counts()

    assert counts == {(0, 1, 0, 1, 0, 0): 10}
Example #3
0
#
# We can give these units arbitrary names and indices of arbitrary dimension:

from pytket.circuit import Qubit

new_q1 = Qubit("alpha", 0)
new_q2 = Qubit("beta", 2, 1)
new_q3 = Qubit("gamma", (0, 0, 0))
c.add_qubit(new_q1)
c.add_qubit(new_q2)
c.add_qubit(new_q3)
print(c.qubits)

# We can also add a new register of qubits in one go:

c.add_q_register("delta", 4)
print(c.qubits)

# Similar commands are available for classical bits.
#
# We can add gates to the circuit as follows:

c.CX(0, 1)

# This command appends a CX gate with control `q[0]` and target `q[1]`. Note that the integer arguments are automatically converted to the default unit IDs. For simple circuits it is often easiest to stick to the default register and refer to the qubits by integers. To add gates to our own named units, we simply pass the `Qubit` (or classical `Bit`) as an argument. (We can't mix the two conventions in one command, however.)

c.H(new_q1)
c.CX(Qubit("q", 1), new_q2)
c.Rz(0.5, new_q2)
print(c.get_commands())
Example #4
0
class CircuitBuilder:
    def __init__(
        self,
        qregs: List[QuantumRegister],
        cregs: Optional[List[ClassicalRegister]] = None,
        name: Optional[str] = None,
        phase: Optional[float] = 0.0,
    ):
        self.qregs = qregs
        self.cregs = [] if cregs is None else cregs
        self.tkc = Circuit(name=name)
        self.tkc.add_phase(phase)
        self.qregmap = {}
        for reg in qregs:
            tk_reg = self.tkc.add_q_register(reg.name, len(reg))
            self.qregmap.update({reg: tk_reg})
        self.cregmap = {}
        for reg in self.cregs:
            tk_reg = self.tkc.add_c_register(reg.name, len(reg))
            self.cregmap.update({reg: tk_reg})

    def circuit(self) -> Circuit:
        return self.tkc

    def add_qiskit_data(self, data: "QuantumCircuitData") -> None:
        for i, qargs, cargs in data:
            condition_kwargs = {}
            if i.condition is not None:
                cond_reg = self.cregmap[i.condition[0]]
                condition_kwargs = {
                    "condition_bits":
                    [cond_reg[k] for k in range(len(cond_reg))],
                    "condition_value": i.condition[1],
                }
            if type(i) == ControlledGate:
                if type(i.base_gate) == qiskit_gates.RYGate:
                    optype = OpType.CnRy
                else:
                    # Maybe handle multicontrolled gates in a more general way,
                    # but for now just do CnRy
                    raise NotImplementedError(
                        "qiskit ControlledGate with " +
                        "base gate {} not implemented".format(i.base_gate))
            else:
                optype = _known_qiskit_gate[type(i)]

            qubits = [
                self.qregmap[qbit.register][qbit.index] for qbit in qargs
            ]
            bits = [self.cregmap[bit.register][bit.index] for bit in cargs]

            if optype == OpType.Unitary2qBox:
                u = i.to_matrix()
                ubox = Unitary2qBox(u)
                self.tkc.add_unitary2qbox(ubox, qubits[0], qubits[1],
                                          **condition_kwargs)
            elif optype == OpType.Barrier:
                self.tkc.add_barrier(qubits)
            elif optype in (OpType.CircBox, OpType.Custom):
                qregs = [QuantumRegister(i.num_qubits, "q")
                         ] if i.num_qubits > 0 else []
                cregs = ([ClassicalRegister(i.num_clbits, "c")]
                         if i.num_clbits > 0 else [])
                builder = CircuitBuilder(qregs, cregs)
                builder.add_qiskit_data(i.definition)
                subc = builder.circuit()
                if optype == OpType.CircBox:
                    cbox = CircBox(subc)
                    self.tkc.add_circbox(cbox, qubits + bits,
                                         **condition_kwargs)
                else:
                    # warning, this will catch all `Gate` instances
                    # that were not picked up as a subclass in _known_qiskit_gate
                    params = [param_to_tk(p) for p in i.params]
                    gate_def = CustomGateDef.define(i.name, subc,
                                                    list(subc.free_symbols()))
                    self.tkc.add_custom_gate(gate_def, params, qubits + bits)
            else:
                params = [param_to_tk(p) for p in i.params]
                self.tkc.add_gate(optype, params, qubits + bits,
                                  **condition_kwargs)