Beispiel #1
0
def _gate_to_circuit(operation):
    from qiskit.circuit.quantumcircuit import QuantumCircuit
    from qiskit.circuit.quantumregister import QuantumRegister
    qr = QuantumRegister(operation.num_qubits)
    qc = QuantumCircuit(qr, name=operation.name)
    if hasattr(operation, 'definition') and operation.definition:
        for rule in operation.definition:
            if rule[0].name in {'id', 'barrier', 'measure', 'snapshot'}:
                raise QiskitError(
                    'Cannot make controlled gate with {} instruction'.format(
                        rule[0].name))
            qc.append(rule[0],
                      qargs=[qr[bit.index] for bit in rule[1]],
                      cargs=[])
    else:
        qc.append(operation, qargs=qr, cargs=[])
    return qc
Beispiel #2
0
def evolve_pauli(
    pauli: Pauli,
    time: Union[float, ParameterExpression] = 1.0,
    cx_structure: str = "chain",
    label: Optional[str] = None,
) -> QuantumCircuit:
    r"""Construct a circuit implementing the time evolution of a single Pauli string.

    For a Pauli string :math:`P = \{I, X, Y, Z\}^{\otimes n}` on :math:`n` qubits and an
    evolution time :math:`t`, the returned circuit implements the unitary operation

    .. math::

        U(t) = e^{-itP}.

    Since only a single Pauli string is evolved the circuit decomposition is exact.

    Args:
        pauli: The Pauli to evolve.
        time: The evolution time.
        cx_structure: Determine the structure of CX gates, can be either "chain" for
            next-neighbor connections or "fountain" to connect directly to the top qubit.
        label: A label for the gate.

    Returns:
        A quantum circuit implementing the time evolution of the Pauli.
    """
    num_non_identity = len([label for label in pauli.to_label() if label != "I"])

    # first check, if the Pauli is only the identity, in which case the evolution only
    # adds a global phase
    if num_non_identity == 0:
        definition = QuantumCircuit(pauli.num_qubits, global_phase=-time)
    # if we evolve on a single qubit, if yes use the corresponding qubit rotation
    elif num_non_identity == 1:
        definition = _single_qubit_evolution(pauli, time)
    # same for two qubits, use Qiskit's native rotations
    elif num_non_identity == 2:
        definition = _two_qubit_evolution(pauli, time, cx_structure)
    # otherwise do basis transformation and CX chains
    else:
        definition = _multi_qubit_evolution(pauli, time, cx_structure)

    definition.name = f"exp(it {pauli.to_label()})"

    return definition
Beispiel #3
0
 def _dec_ucg(self):
     """
     Call to create a circuit that implements the uniformly controlled gate. If
     up_to_diagonal=True, the circuit implements the gate up to a diagonal gate and
     the diagonal gate is also returned.
     """
     diag = np.ones(2**self.num_qubits).tolist()
     q = QuantumRegister(self.num_qubits)
     q_controls = q[1:]
     q_target = q[0]
     circuit = QuantumCircuit(q)
     # If there is no control, we use the ZYZ decomposition
     if not q_controls:
         theta, phi, lamb = euler_angles_1q(self.params[0])
         circuit.u3(theta, phi, lamb, q)
         return circuit, diag
     # If there is at least one control, first,
     # we find the single qubit gates of the decomposition.
     (single_qubit_gates, diag) = self._dec_ucg_help()
     # Now, it is easy to place the C-NOT gates and some Hadamards and Rz(pi/2) gates
     # (which are absorbed into the single-qubit unitaries) to get back the full decomposition.
     for i, gate in enumerate(single_qubit_gates):
         # Absorb Hadamards and Rz(pi/2) gates
         if i == 0:
             squ = HGate().to_matrix().dot(gate)
         elif i == len(single_qubit_gates) - 1:
             squ = gate.dot(UCG._rz(np.pi / 2)).dot(HGate().to_matrix())
         else:
             squ = HGate().to_matrix().dot(gate.dot(UCG._rz(
                 np.pi / 2))).dot(HGate().to_matrix())
         # Add single-qubit gate
         circuit.squ(squ, q_target)
         # The number of the control qubit is given by the number of zeros at the end
         # of the binary representation of (i+1)
         binary_rep = np.binary_repr(i + 1)
         num_trailing_zeros = len(binary_rep) - len(binary_rep.rstrip('0'))
         q_contr_index = num_trailing_zeros
         # Add C-NOT gate
         if not i == len(single_qubit_gates) - 1:
             circuit.cx(q_controls[q_contr_index], q_target)
     if not self.up_to_diagonal:
         # Important: the diagonal gate is given in the computational basis of the qubits
         # q[k-1],...,q[0],q_target (ordered with decreasing significance),
         # where q[i] are the control qubits and t denotes the target qubit.
         circuit.diag_gate(diag.tolist(), q)
     return circuit, diag
Beispiel #4
0
    def _define(self):
        """Define the MCX gate using recursion."""
        # pylint: disable=cyclic-import
        from qiskit.circuit.quantumcircuit import QuantumCircuit

        q = QuantumRegister(self.num_qubits, name="q")
        qc = QuantumCircuit(q, name=self.name)
        if self.num_qubits == 4:
            qc._append(C3XGate(), q[:], [])
            self.definition = qc
        elif self.num_qubits == 5:
            qc._append(C4XGate(), q[:], [])
            self.definition = qc
        else:
            for instr, qargs, cargs in self._recurse(q[:-1], q_ancilla=q[-1]):
                qc._append(instr, qargs, cargs)
            self.definition = qc
Beispiel #5
0
def diagonalizing_clifford(pauli: Pauli) -> QuantumCircuit:
    """Get the clifford circuit to diagonalize the Pauli operator.

    Args:
        pauli: The Pauli to diagonalize.

    Returns:
        A circuit to diagonalize.
    """
    cliff = QuantumCircuit(pauli.num_qubits)
    for i, pauli_i in enumerate(reversed(pauli.to_label())):
        if pauli_i == "Y":
            cliff.sdg(i)
        if pauli_i in ["X", "Y"]:
            cliff.h(i)

    return cliff
Beispiel #6
0
 def _define(self):
     """
     gate rzx(theta) a, b { h b; cx a, b; u1(theta) b; cx a, b; h b;}
     """
     # pylint: disable=cyclic-import
     from qiskit.circuit.quantumcircuit import QuantumCircuit
     from .h import HGate
     from .x import CXGate
     from .rz import RZGate
     theta = self.params[0]
     q = QuantumRegister(2, 'q')
     qc = QuantumCircuit(q, name=self.name)
     rules = [(HGate(), [q[1]], []), (CXGate(), [q[0], q[1]], []),
              (RZGate(theta), [q[1]], []), (CXGate(), [q[0], q[1]], []),
              (HGate(), [q[1]], [])]
     qc._data = rules
     self.definition = qc
Beispiel #7
0
 def _define(self):
     """
     gate sx a { rz(-pi/2) a; h a; rz(-pi/2); }
     """
     # pylint: disable=cyclic-import
     from qiskit.circuit.quantumcircuit import QuantumCircuit
     from .s import SdgGate
     from .h import HGate
     q = QuantumRegister(1, 'q')
     qc = QuantumCircuit(q, name=self.name, global_phase=pi / 4)
     rules = [
         (SdgGate(), [q[0]], []),
         (HGate(), [q[0]], []),
         (SdgGate(), [q[0]], [])
     ]
     qc.data = rules
     self.definition = qc
Beispiel #8
0
    def _define(self):
        """
        gate cz a,b { h b; cx a,b; h b; }
        """
        # pylint: disable=cyclic-import
        from qiskit.circuit.quantumcircuit import QuantumCircuit
        from .h import HGate
        from .x import CXGate

        q = QuantumRegister(2, "q")
        qc = QuantumCircuit(q, name=self.name)
        rules = [(HGate(), [q[1]], []), (CXGate(), [q[0], q[1]], []),
                 (HGate(), [q[1]], [])]
        for instr, qargs, cargs in rules:
            qc._append(instr, qargs, cargs)

        self.definition = qc
Beispiel #9
0
 def _define(self):
     """
     gate csx a,b { h b; cu1(pi/2) a,b; h b; }
     """
     # pylint: disable=cyclic-import
     from qiskit.circuit.quantumcircuit import QuantumCircuit
     from .h import HGate
     from .u1 import CU1Gate
     q = QuantumRegister(2, 'q')
     qc = QuantumCircuit(q, name=self.name)
     rules = [
         (HGate(), [q[1]], []),
         (CU1Gate(pi/2), [q[0], q[1]], []),
         (HGate(), [q[1]], [])
     ]
     qc.data = rules
     self.definition = qc
Beispiel #10
0
    def _define(self):
        # pylint: disable=cyclic-import
        from qiskit.circuit.quantumcircuit import QuantumCircuit
        q = QuantumRegister(self.num_qubits, 'q')
        qc = QuantumCircuit(q, name=self.name)

        if self.num_ctrl_qubits == 0:
            qc.p(self.params[0], 0)
        if self.num_ctrl_qubits == 1:
            qc.cp(self.params[0], 0, 1)
        else:
            from .u3 import _gray_code_chain
            scaled_lam = self.params[0] / (2 ** (self.num_ctrl_qubits - 1))
            bottom_gate = CPhaseGate(scaled_lam)
            definition = _gray_code_chain(q, self.num_ctrl_qubits, bottom_gate)
            qc.data = definition
        self.definition = qc
Beispiel #11
0
    def __init__(self, num_qubits: int, theta: Union[List[List[float]], np.ndarray]) -> None:
        """Create a new Global Mølmer–Sørensen (GMS) gate.

        Args:
            num_qubits: width of gate.
            theta: a num_qubits x num_qubits symmetric matrix of
                interaction angles for each qubit pair. The upper
                triangle is considered.
        """
        super().__init__(num_qubits, name="gms")
        if not isinstance(theta, list):
            theta = [theta] * int((num_qubits ** 2 - 1) / 2)
        gms = QuantumCircuit(num_qubits, name="gms")
        for i in range(self.num_qubits):
            for j in range(i + 1, self.num_qubits):
                gms.append(RXXGate(theta[i][j]), [i, j])
        self.append(gms.to_gate(), self.qubits)
Beispiel #12
0
    def _define(self):
        """
        gate pauli (p1 a1,...,pn an) { p1 a1; ... ; pn an; }
        """
        # pylint: disable=cyclic-import
        from qiskit.circuit.quantumcircuit import QuantumCircuit

        gates = {"X": XGate, "Y": YGate, "Z": ZGate}
        q = QuantumRegister(len(self.params[0]), "q")
        qc = QuantumCircuit(q, name=f"{self.name}({self.params[0]})")

        paulis = self.params[0]
        for i, p in enumerate(reversed(paulis)):
            if p == "I":
                continue
            qc._append(CircuitInstruction(gates[p](), (q[i], ), ()))
        self.definition = qc
Beispiel #13
0
    def test_pauli_gate(self, method, device, pauli):
        """Test multi-qubit Pauli gate."""
        pauli = qi.Pauli(pauli)
        circuit = QuantumCircuit(pauli.num_qubits)
        circuit.append(pauli, range(pauli.num_qubits))

        backend = self.backend(method=method, device=device)
        label = 'final'
        if method == 'density_matrix':
            target = qi.DensityMatrix(circuit)
            circuit.save_density_matrix(label=label)
            state_fn = qi.DensityMatrix
            fidelity_fn = qi.state_fidelity
        elif method == 'stabilizer':
            target = qi.Clifford(circuit)
            circuit.save_stabilizer(label=label)
            state_fn = qi.Clifford.from_dict
            fidelity_fn = qi.process_fidelity
        elif method == 'unitary':
            target = qi.Operator(circuit)
            circuit.save_unitary(label=label)
            state_fn = qi.Operator
            fidelity_fn = qi.process_fidelity
        elif method == 'superop':
            target = qi.SuperOp(circuit)
            circuit.save_superop(label=label)
            state_fn = qi.SuperOp
            fidelity_fn = qi.process_fidelity
        else:
            target = qi.Statevector(circuit)
            circuit.save_statevector(label=label)
            state_fn = qi.Statevector
            fidelity_fn = qi.state_fidelity

        result = backend.run(transpile(circuit, backend, optimization_level=0),
                             shots=1).result()

        # Check results
        success = getattr(result, 'success', False)
        self.assertTrue(success)
        data = result.data(0)
        self.assertIn(label, data)
        value = state_fn(data[label])
        fidelity = fidelity_fn(target, value)
        self.assertGreater(fidelity, 0.9999)
Beispiel #14
0
 def _define(self):
     """
     gate c3sqrtx a,b,c,d
     {
         h d; cu1(-pi/8) a,d; h d;
         cx a,b;
         h d; cu1(pi/8) b,d; h d;
         cx a,b;
         h d; cu1(-pi/8) b,d; h d;
         cx b,c;
         h d; cu1(pi/8) c,d; h d;
         cx a,c;
         h d; cu1(-pi/8) c,d; h d;
         cx b,c;
         h d; cu1(pi/8) c,d; h d;
         cx a,c;
         h d; cu1(-pi/8) c,d; h d;
     }
     gate c4x a,b,c,d,e
     {
         h e; cu1(-pi/2) d,e; h e;
         c3x a,b,c,d;
         h d; cu1(pi/4) d,e; h d;
         c3x a,b,c,d;
         c3sqrtx a,b,c,e;
     }
     """
     # pylint: disable=cyclic-import
     from qiskit.circuit.quantumcircuit import QuantumCircuit
     from .u1 import CU1Gate
     q = QuantumRegister(5, name='q')
     qc = QuantumCircuit(q, name=self.name)
     rules = [
         (HGate(), [q[4]], []),
         (CU1Gate(-numpy.pi / 2), [q[3], q[4]], []),
         (HGate(), [q[4]], []),
         (C3XGate(), [q[0], q[1], q[2], q[3]], []),
         (HGate(), [q[4]], []),
         (CU1Gate(numpy.pi / 2), [q[3], q[4]], []),
         (HGate(), [q[4]], []),
         (C3XGate(), [q[0], q[1], q[2], q[3]], []),
         (C3XGate(numpy.pi / 8), [q[0], q[1], q[2], q[4]], []),
     ]
     qc._data = rules
     self.definition = qc
Beispiel #15
0
    def _define(self):
        """
        gate ecr a, b { rzx(pi/4) a, b; x a; rzx(-pi/4) a, b;}
        """
        # pylint: disable=cyclic-import
        from qiskit.circuit.quantumcircuit import QuantumCircuit

        q = QuantumRegister(2, "q")
        qc = QuantumCircuit(q, name=self.name)
        rules = [
            (RZXGate(np.pi / 4), [q[0], q[1]], []),
            (XGate(), [q[0]], []),
            (RZXGate(-np.pi / 4), [q[0], q[1]], []),
        ]
        for instr, qargs, cargs in rules:
            qc._append(instr, qargs, cargs)

        self.definition = qc
Beispiel #16
0
 def _define(self):
     """
     gate cphase(lambda) a,b
     { phase(lambda/2) a; cx a,b;
       phase(-lambda/2) b; cx a,b;
       phase(lambda/2) b;
     }
     """
     # pylint: disable=cyclic-import
     from qiskit.circuit.quantumcircuit import QuantumCircuit
     q = QuantumRegister(2, 'q')
     qc = QuantumCircuit(q, name=self.name)
     qc.p(self.params[0] / 2, 0)
     qc.cx(0, 1)
     qc.p(-self.params[0] / 2, 1)
     qc.cx(0, 1)
     qc.p(self.params[0] / 2, 1)
     self.definition = qc
    def synthesize(self, evolution):
        # get operators and time to evolve
        operators = evolution.operator
        time = evolution.time

        # construct the evolution circuit
        evolution_circuit = QuantumCircuit(operators[0].num_qubits)

        if not isinstance(operators, list):
            matrix = operators.to_matrix()
        else:
            matrix = sum(op.to_matrix() for op in operators)

        exp = expm(-1j * time * matrix)

        evolution_circuit.unitary(exp, evolution_circuit.qubits)

        return evolution_circuit
Beispiel #18
0
    def _define(self):
        # pylint: disable=cyclic-import
        from qiskit.circuit.quantumcircuit import QuantumCircuit
        q = QuantumRegister(self.num_qubits, 'q')
        qc = QuantumCircuit(q, name=self.name)

        if self.num_ctrl_qubits == 0:
            definition = U1Gate(self.params[0]).definition
        if self.num_ctrl_qubits == 1:
            definition = CU1Gate(self.params[0]).definition
        else:
            from .u3 import _gray_code_chain
            scaled_lam = self.params[0] / (2 ** (self.num_ctrl_qubits - 1))
            bottom_gate = CU1Gate(scaled_lam)
            definition = _gray_code_chain(q, self.num_ctrl_qubits, bottom_gate)
        for instr, qargs, cargs in definition:
            qc._append(instr, qargs, cargs)
        self.definition = qc
 def _circuit_xyx(theta,
                  phi,
                  lam,
                  phase,
                  simplify=True,
                  atol=DEFAULT_ATOL):
     qr = QuantumRegister(1, 'qr')
     circuit = QuantumCircuit(qr, global_phase=phase)
     if simplify and math.isclose(theta, 0.0, abs_tol=atol):
         circuit._append(RXGate(phi + lam), [qr[0]], [])
         return circuit
     if not simplify or not math.isclose(lam, 0.0, abs_tol=atol):
         circuit._append(RXGate(lam), [qr[0]], [])
     if not simplify or not math.isclose(theta, 0.0, abs_tol=atol):
         circuit._append(RYGate(theta), [qr[0]], [])
     if not simplify or not math.isclose(phi, 0.0, abs_tol=atol):
         circuit._append(RXGate(phi), [qr[0]], [])
     return circuit
Beispiel #20
0
 def _define(self):
     """
     gate cswap a,b,c
     { cx c,b;
       ccx a,b,c;
       cx c,b;
     }
     """
     # pylint: disable=cyclic-import
     from qiskit.circuit.quantumcircuit import QuantumCircuit
     from .x import CXGate, CCXGate
     q = QuantumRegister(3, 'q')
     qc = QuantumCircuit(q, name=self.name)
     rules = [(CXGate(), [q[2], q[1]], []),
              (CCXGate(), [q[0], q[1], q[2]], []),
              (CXGate(), [q[2], q[1]], [])]
     qc._data = rules
     self.definition = qc
Beispiel #21
0
    def _build_additional_layers(self, circuit, which):
        if which == "appended":
            blocks = self._appended_blocks
            entanglements = self._appended_entanglement
        elif which == "prepended":
            blocks = reversed(self._prepended_blocks)
            entanglements = reversed(self._prepended_entanglement)
        else:
            raise ValueError("`which` must be either `appended` or `prepended`.")

        for block, ent in zip(blocks, entanglements):
            layer = QuantumCircuit(*self.qregs)
            if isinstance(ent, str):
                ent = get_entangler_map(block.num_qubits, self.num_qubits, ent)
            for indices in ent:
                layer.compose(block, indices, inplace=True)

            circuit.compose(layer, inplace=True)
Beispiel #22
0
    def inverse(self):
        """Return the inverse.

        This does not re-compute the decomposition for the multiplexer with the inverse of the
        gates but simply inverts the existing decomposition.
        """
        inverse_gate = Gate(
            name=self.name + "_dg", num_qubits=self.num_qubits,
            params=[])  # removing the params because arrays are deprecated

        definition = QuantumCircuit(*self.definition.qregs)
        for inst in reversed(self._definition):
            definition._append(
                inst.replace(operation=inst.operation.inverse()))

        definition.global_phase = -self.definition.global_phase

        inverse_gate.definition = definition
        return inverse_gate
Beispiel #23
0
 def _define(self):
     """
     gate crz(lambda) a,b
     { u1(lambda/2) b; cx a,b;
       u1(-lambda/2) b; cx a,b;
     }
     """
     # pylint: disable=cyclic-import
     from qiskit.circuit.quantumcircuit import QuantumCircuit
     from .u1 import U1Gate
     from .x import CXGate
     q = QuantumRegister(2, 'q')
     qc = QuantumCircuit(q, name=self.name)
     rules = [(U1Gate(self.params[0] / 2), [q[1]], []),
              (CXGate(), [q[0], q[1]], []),
              (U1Gate(-self.params[0] / 2), [q[1]], []),
              (CXGate(), [q[0], q[1]], [])]
     qc._data = rules
     self.definition = qc
Beispiel #24
0
    def _build_additional_layers(self, which):
        if which == 'appended':
            blocks = self._appended_blocks
            entanglements = self._appended_entanglement
        elif which == 'prepended':
            blocks = reversed(self._prepended_blocks)
            entanglements = reversed(self._prepended_entanglement)
        else:
            raise ValueError(
                '`which` must be either `appended` or `prepended`.')

        for i, (block, ent) in enumerate(zip(blocks, entanglements)):
            layer = QuantumCircuit(*self.qregs)
            if isinstance(ent, str):
                ent = get_entangler_map(block.num_qubits, self.num_qubits, ent)
            for indices in ent:
                layer.compose(block, indices, inplace=True)

            self += layer
    def _define(self):
        """
        gate xx_minus_yy(theta, beta) a, b {
            rz(-beta) b;
            rz(-pi/2) a;
            sx a;
            rz(pi/2) a;
            s b;
            cx a, b;
            ry(theta/2) a;
            ry(-theta/2) b;
            cx a, b;
            sdg b;
            rz(-pi/2) a;
            sxdg a;
            rz(pi/2) a;
            rz(beta) b;
        }
        """
        theta, beta = self.params
        register = QuantumRegister(2, "q")
        circuit = QuantumCircuit(register, name=self.name)
        a, b = register
        rules = [
            (RZGate(-beta), [b], []),
            (RZGate(-pi / 2), [a], []),
            (SXGate(), [a], []),
            (RZGate(pi / 2), [a], []),
            (SGate(), [b], []),
            (CXGate(), [a, b], []),
            (RYGate(theta / 2), [a], []),
            (RYGate(-theta / 2), [b], []),
            (CXGate(), [a, b], []),
            (SdgGate(), [b], []),
            (RZGate(-pi / 2), [a], []),
            (SXdgGate(), [a], []),
            (RZGate(pi / 2), [a], []),
            (RZGate(beta), [b], []),
        ]
        for instr, qargs, cargs in rules:
            circuit._append(instr, qargs, cargs)

        self.definition = circuit
 def _circuit_u321(theta,
                   phi,
                   lam,
                   phase,
                   simplify=True,
                   atol=DEFAULT_ATOL):
     rtol = 1e-9  # default is 1e-5, too far from atol=1e-12
     qr = QuantumRegister(1, 'qr')
     circuit = QuantumCircuit(qr, global_phase=phase)
     if simplify and (math.isclose(theta, 0.0, abs_tol=atol, rel_tol=rtol)):
         phi_lam = phi + lam
         if not (math.isclose(phi_lam, 0.0, abs_tol=atol, rel_tol=rtol) or
                 math.isclose(phi_lam, 2*np.pi, abs_tol=atol, rel_tol=rtol)):
             circuit._append(U1Gate(_mod2pi(phi+lam)), [qr[0]], [])
     elif simplify and math.isclose(theta, np.pi/2, abs_tol=atol, rel_tol=rtol):
         circuit._append(U2Gate(phi, lam), [qr[0]], [])
     else:
         circuit._append(U3Gate(theta, phi, lam), [qr[0]], [])
     return circuit
Beispiel #27
0
def cnot_chain(pauli: Pauli) -> QuantumCircuit:
    """CX chain.

    For example, for the Pauli with the label 'XYZIX'.

    .. parsed-literal::

                       ┌───┐
        q_0: ──────────┤ X ├
                       └─┬─┘
        q_1: ────────────┼──
                  ┌───┐  │
        q_2: ─────┤ X ├──■──
             ┌───┐└─┬─┘
        q_3: ┤ X ├──■───────
             └─┬─┘
        q_4: ──■────────────

    Args:
        pauli: The Pauli for which to construct the CX chain.

    Returns:
        A circuit implementing the CX chain.
    """

    chain = QuantumCircuit(pauli.num_qubits)
    control, target = None, None

    # iterate over the Pauli's and add CNOTs
    for i, pauli_i in enumerate(pauli.to_label()):
        i = pauli.num_qubits - i - 1
        if pauli_i != "I":
            if control is None:
                control = i
            else:
                target = i

        if control is not None and target is not None:
            chain.cx(control, target)
            control = i
            target = None

    return chain
Beispiel #28
0
def integrate_circuit(
    qc: QuantumCircuit,
    target_qubits: List[int],
    target_classical_bits: Optional[List[int]] = None,
    number_of_qubits: int = 5,
    add_measurements: bool = True,
) -> QuantumCircuit:
    """ Integrate circuit at specified qubits in a larger qubit system

    This can be used for example to integrate a single-qubit experiment in
    a 5-qubit circuit to be executed on a 5-qubit device.

    Args:
        qc: QuantumCircuit to be integrated
        target_qubits: List of qubits to map the circuit on
        target_classical_bits: If None, then use the registers allocated to the target qubits
        number_of_qubits: Number of qubits in the target system
        add_measurements: If True, then add a measure statement for all the new qubits

    Returns:
        Integrated circuit
    """
    if qc.num_qubits > number_of_qubits:
        raise CircuitError(
            f'number of qubits {qc.num_qubits} in the specified circuit cannot exceed specified number of qubits {number_of_qubits} in the target system'
        )

    output_qc = QuantumCircuit(number_of_qubits, number_of_qubits)

    qbits = [output_qc.qregs[0][i] for i in target_qubits]
    if target_classical_bits is None:
        cbits = [output_qc.cregs[0][i] for i in target_qubits]
    else:
        cbits = [output_qc.cregs[0][i] for i in target_classical_bits]

    output_qc = output_qc.compose(qc, qubits=qbits, clbits=cbits)

    if add_measurements:
        for qubit_index in range(number_of_qubits):
            if qubit_index not in target_qubits:
                output_qc.measure(qubit_index, qubit_index)
    return output_qc
Beispiel #29
0
    def _define(self):
        """
        gate ccx a,b,c
        {
        h c; cx b,c; tdg c; cx a,c;
        t c; cx b,c; tdg c; cx a,c;
        t b; t c; h c; cx a,b;
        t a; tdg b; cx a,b;}
        """
        # pylint: disable=cyclic-import
        from qiskit.circuit.quantumcircuit import QuantumCircuit

        #                                                        ┌───┐
        # q_0: ───────────────────■─────────────────────■────■───┤ T ├───■──
        #                         │             ┌───┐   │  ┌─┴─┐┌┴───┴┐┌─┴─┐
        # q_1: ───────■───────────┼─────────■───┤ T ├───┼──┤ X ├┤ Tdg ├┤ X ├
        #      ┌───┐┌─┴─┐┌─────┐┌─┴─┐┌───┐┌─┴─┐┌┴───┴┐┌─┴─┐├───┤└┬───┬┘└───┘
        # q_2: ┤ H ├┤ X ├┤ Tdg ├┤ X ├┤ T ├┤ X ├┤ Tdg ├┤ X ├┤ T ├─┤ H ├──────
        #      └───┘└───┘└─────┘└───┘└───┘└───┘└─────┘└───┘└───┘ └───┘
        q = QuantumRegister(3, "q")
        qc = QuantumCircuit(q, name=self.name)
        rules = [
            (HGate(), [q[2]], []),
            (CXGate(), [q[1], q[2]], []),
            (TdgGate(), [q[2]], []),
            (CXGate(), [q[0], q[2]], []),
            (TGate(), [q[2]], []),
            (CXGate(), [q[1], q[2]], []),
            (TdgGate(), [q[2]], []),
            (CXGate(), [q[0], q[2]], []),
            (TGate(), [q[1]], []),
            (TGate(), [q[2]], []),
            (HGate(), [q[2]], []),
            (CXGate(), [q[0], q[1]], []),
            (TGate(), [q[0]], []),
            (TdgGate(), [q[1]], []),
            (CXGate(), [q[0], q[1]], []),
        ]
        for instr, qargs, cargs in rules:
            qc._append(instr, qargs, cargs)

        self.definition = qc
Beispiel #30
0
    def circuit(
        self, *, euler_basis: Optional[str] = None, simplify=False, atol=DEFAULT_ATOL
    ) -> QuantumCircuit:
        """Returns Weyl decomposition in circuit form.

        simplify, atol arguments are passed to OneQubitEulerDecomposer"""
        if euler_basis is None:
            euler_basis = self._default_1q_basis
        oneq_decompose = OneQubitEulerDecomposer(euler_basis)
        c1l, c1r, c2l, c2r = (
            oneq_decompose(k, simplify=simplify, atol=atol)
            for k in (self.K1l, self.K1r, self.K2l, self.K2r)
        )
        circ = QuantumCircuit(2, global_phase=self.global_phase)
        circ.compose(c2r, [0], inplace=True)
        circ.compose(c2l, [1], inplace=True)
        self._weyl_gate(simplify, circ, atol)
        circ.compose(c1r, [0], inplace=True)
        circ.compose(c1l, [1], inplace=True)
        return circ