Exemplo n.º 1
0
def cnot_rxx_decompose(plus_ry=True, plus_rxx=True):
    """Decomposition of CNOT gate.

    NOTE: this differs to CNOT by a global phase.
    The matrix returned is given by exp(1j * pi/4) * CNOT

    Args:
        plus_ry (bool): positive initial RY rotation
        plus_rxx (bool): positive RXX rotation.

    Returns:
        QuantumCircuit: The decomposed circuit for CNOT gate (up to
        global phase).
    """
    # Convert boolean args to +/- 1 signs
    if plus_ry:
        sgn_ry = 1
    else:
        sgn_ry = -1
    if plus_rxx:
        sgn_rxx = 1
    else:
        sgn_rxx = -1
    circuit = QuantumCircuit(2, global_phase=-sgn_ry * sgn_rxx * np.pi / 4)
    circuit.append(RYGate(sgn_ry * np.pi / 2), [0])
    circuit.append(RXXGate(sgn_rxx * np.pi / 2), [0, 1])
    circuit.append(RXGate(-sgn_rxx * np.pi / 2), [0])
    circuit.append(RXGate(-sgn_rxx * sgn_ry * np.pi / 2), [1])
    circuit.append(RYGate(-sgn_ry * np.pi / 2), [0])
    return circuit
Exemplo n.º 2
0
 def _define(self):
     diag_circuit = self._dec_diag()
     gate = diag_circuit.to_instruction()
     q = QuantumRegister(self.num_qubits)
     diag_circuit = QuantumCircuit(q)
     diag_circuit.append(gate, q[:])
     self.definition = diag_circuit
Exemplo n.º 3
0
    def __call__(self, target, basis_fidelity=None, *, _num_basis_uses=None) -> QuantumCircuit:
        """Decompose a two-qubit unitary over fixed basis + SU(2) using the best approximation given
        that each basis application has a finite fidelity.

        You can force a particular approximation by passing _num_basis_uses.
        """
        basis_fidelity = basis_fidelity or self.basis_fidelity
        target = np.asarray(target, dtype=complex)

        target_decomposed = TwoQubitWeylDecomposition(target)
        traces = self.traces(target_decomposed)
        expected_fidelities = [trace_to_fid(traces[i]) * basis_fidelity ** i for i in range(4)]

        best_nbasis = int(np.argmax(expected_fidelities))
        if _num_basis_uses is not None:
            best_nbasis = _num_basis_uses
        decomposition = self.decomposition_fns[best_nbasis](target_decomposed)
        decomposition_euler = [self._decomposer1q._decompose(x) for x in decomposition]

        q = QuantumRegister(2)
        return_circuit = QuantumCircuit(q)
        return_circuit.global_phase = target_decomposed.global_phase
        return_circuit.global_phase -= best_nbasis * self.basis.global_phase
        if best_nbasis == 2:
            return_circuit.global_phase += np.pi
        for i in range(best_nbasis):
            return_circuit.compose(decomposition_euler[2 * i], [q[0]], inplace=True)
            return_circuit.compose(decomposition_euler[2 * i + 1], [q[1]], inplace=True)
            return_circuit.append(self.gate, [q[0], q[1]])
        return_circuit.compose(decomposition_euler[2 * best_nbasis], [q[0]], inplace=True)
        return_circuit.compose(decomposition_euler[2 * best_nbasis + 1], [q[1]], inplace=True)

        return return_circuit
Exemplo n.º 4
0
    def _convert_to_block(self, layer: Any) -> QuantumCircuit:
        """Try to convert ``layer`` to a QuantumCircuit.

        Args:
            layer: The object to be converted to an NLocal block / Instruction.

        Returns:
            The layer converted to a circuit.

        Raises:
            TypeError: If the input cannot be converted to a circuit.
        """
        if isinstance(layer, QuantumCircuit):
            return layer

        if isinstance(layer, Instruction):
            circuit = QuantumCircuit(layer.num_qubits)
            circuit.append(layer, list(range(layer.num_qubits)))
            return circuit

        try:
            circuit = QuantumCircuit(layer.num_qubits)
            circuit.append(layer.to_instruction(),
                           list(range(layer.num_qubits)))
            return circuit
        except AttributeError:
            pass

        raise TypeError("Adding a {} to an NLocal is not supported.".format(
            type(layer)))
Exemplo n.º 5
0
 def _dec_mcg_up_diag(self):
     """
     Call to create a circuit with gates that implement the MCG up to a diagonal gate.
     Remark: The qubits the gate acts on are ordered in the following way:
         q=[q_target,q_controls,q_ancilla_zero,q_ancilla_dirty]
     """
     diag = np.ones(2**(self.num_controls + 1)).tolist()
     q = QuantumRegister(self.num_qubits)
     circuit = QuantumCircuit(q)
     (q_target, q_controls, q_ancillas_zero,
      q_ancillas_dirty) = self._define_qubit_role(q)
     # ToDo: Keep this threshold updated such that the lowest gate count is achieved:
     # ToDo: we implement the MCG with a UCGate up to diagonal if the number of controls is
     # ToDo: smaller than the threshold.
     threshold = float("inf")
     if self.num_controls < threshold:
         # Implement the MCG as a UCGate (up to diagonal)
         gate_list = [np.eye(2, 2) for i in range(2**self.num_controls)]
         gate_list[-1] = self.params[0]
         ucg = UCGate(gate_list, up_to_diagonal=True)
         circuit.append(ucg, [q_target] + q_controls)
         diag = ucg._get_diagonal()
         # else:
         # ToDo: Use the best decomposition for MCGs up to diagonal gates here
         # ToDo: (with all available ancillas)
     return circuit, diag
Exemplo n.º 6
0
 def _define(self):
     mcg_up_diag_circuit, _ = self._dec_mcg_up_diag()
     gate = mcg_up_diag_circuit.to_instruction()
     q = QuantumRegister(self.num_qubits)
     mcg_up_diag_circuit = QuantumCircuit(q)
     mcg_up_diag_circuit.append(gate, q[:])
     self.definition = mcg_up_diag_circuit
Exemplo n.º 7
0
 def _define(self):
     squ_circuit, _ = self._dec_single_qubit_unitary()
     gate = squ_circuit.to_instruction()
     q = QuantumRegister(self.num_qubits)
     squ_circuit = QuantumCircuit(q)
     squ_circuit.append(gate, q[:])
     self.definition = squ_circuit.data
Exemplo n.º 8
0
 def _define(self):
     # pylint: disable=cyclic-import
     from qiskit.circuit.quantumcircuit import QuantumCircuit
     from .u import UGate
     q = QuantumRegister(1, 'q')
     qc = QuantumCircuit(q, name=self.name)
     qc.append(UGate(0, 0, self.params[0]), [0])
     self.definition = qc
Exemplo n.º 9
0
 def _define(self):
     """The standard definition used the Gray code implementation."""
     # pylint: disable=cyclic-import
     from qiskit.circuit.quantumcircuit import QuantumCircuit
     q = QuantumRegister(self.num_qubits, name='q')
     qc = QuantumCircuit(q)
     qc.append(MCXGrayCode(self.num_ctrl_qubits), qargs=q[:])
     self.definition = qc
Exemplo n.º 10
0
 def _define(self):
     # TODO The inverse().inverse() is because there is code to uncompute (_gates_to_uncompute)
     #  an isometry, but not for generating its decomposition. It would be cheaper to do the
     #  later here instead.
     gate = self.inverse().inverse()
     q = QuantumRegister(self.num_qubits)
     iso_circuit = QuantumCircuit(q)
     iso_circuit.append(gate, q[:])
     self.definition = iso_circuit
Exemplo n.º 11
0
    def __init__(
        self, num_state_qubits: int, kind: str = "fixed", name: str = "DraperQFTAdder"
    ) -> None:
        r"""
        Args:
            num_state_qubits: The number of qubits in either input register for
                state :math:`|a\rangle` or :math:`|b\rangle`. The two input
                registers must have the same number of qubits.
            kind: The kind of adder, can be ``'half'`` for a half adder or
                ``'fixed'`` for a fixed-sized adder. A half adder contains a carry-out to represent
                the most-significant bit, but the fixed-sized adder doesn't and hence performs
                addition modulo ``2 ** num_state_qubits``.
            name: The name of the circuit object.
        Raises:
            ValueError: If ``num_state_qubits`` is lower than 1.
        """
        if kind == "full":
            raise ValueError("The DraperQFTAdder only supports 'half' and 'fixed' as ``kind``.")

        if num_state_qubits < 1:
            raise ValueError("The number of qubits must be at least 1.")

        super().__init__(num_state_qubits, name=name)

        qr_a = QuantumRegister(num_state_qubits, name="a")
        qr_b = QuantumRegister(num_state_qubits, name="b")
        qr_list = [qr_a, qr_b]

        if kind == "half":
            qr_z = QuantumRegister(1, name="cout")
            qr_list.append(qr_z)

        # add registers
        self.add_register(*qr_list)

        # define register containing the sum and number of qubits for QFT circuit
        qr_sum = qr_b[:] if kind == "fixed" else qr_b[:] + qr_z[:]
        num_qubits_qft = num_state_qubits if kind == "fixed" else num_state_qubits + 1

        circuit = QuantumCircuit(*self.qregs, name=name)

        # build QFT adder circuit
        circuit.append(QFT(num_qubits_qft, do_swaps=False).to_gate(), qr_sum[:])

        for j in range(num_state_qubits):
            for k in range(num_state_qubits - j):
                lam = np.pi / (2**k)
                circuit.cp(lam, qr_a[j], qr_b[j + k])

        if kind == "half":
            for j in range(num_state_qubits):
                lam = np.pi / (2 ** (j + 1))
                circuit.cp(lam, qr_a[num_state_qubits - j - 1], qr_z[0])

        circuit.append(QFT(num_qubits_qft, do_swaps=False).inverse().to_gate(), qr_sum[:])

        self.append(circuit.to_gate(), self.qubits)
Exemplo n.º 12
0
 def _circuit_u3(theta,
                 phi,
                 lam,
                 simplify=True,
                 atol=DEFAULT_ATOL):
     # pylint: disable=unused-argument
     circuit = QuantumCircuit(1)
     circuit.append(U3Gate(theta, phi, lam), [0])
     return circuit
Exemplo n.º 13
0
def tweedledum2qiskit(tweedledum_circuit, name=None, qregs=None):
    """ Converts a `Tweedledum <https://github.com/boschmitt/tweedledum>`_
    circuit into a Qiskit circuit. A Tweedledum circuit is a
    dictionary with the following shape:
        {
        "num_qubits": 2,
        "gates": [{
            "gate": "X",
            "qubits": [1],
            "control_qubits": [0],
            "control_state": "1"
        }]
    Args:
        tweedledum_circuit (dict): Tweedledum circuit.
        name (str): Name for the resulting Qiskit circuit.
        qregs (list(QuantumRegister)): Optional. List of QuantumRegisters on which the
           circuit would operate. If not provided, it will create a flat register.

    Returns:
        QuantumCircuit: The Tweedledum circuit converted to a Qiskit circuit.

    Raises:
        ClassicalFunctionCompilerError: If there a gate in the Tweedledum circuit has no Qiskit
        equivalent.
    """
    gates = {
        'z': ZGate,
        't': TGate,
        's': SGate,
        'tdg': TdgGate,
        'sdg': SdgGate,
        'u1': U1Gate,
        'x': XGate,
        'h': HGate,
        'u3': U3Gate
    }
    if qregs:
        circuit = QuantumCircuit(*qregs, name=name)
    else:
        circuit = QuantumCircuit(tweedledum_circuit['num_qubits'], name=name)
    for gate in tweedledum_circuit['gates']:
        basegate = gates.get(gate['gate'].lower())
        if basegate is None:
            raise ClassicalFunctionCompilerError(
                'The Tweedledum gate %s has no Qiskit equivalent' %
                gate['gate'])

        ctrl_qubits = gate.get('control_qubits', [])
        trgt_qubits = gate.get('qubits', [])

        if ctrl_qubits:
            gate = basegate().control(len(ctrl_qubits),
                                      ctrl_state=gate.get('control_state'))
        else:
            gate = basegate()
        circuit.append(gate, ctrl_qubits + trgt_qubits)
    return circuit
Exemplo n.º 14
0
 def _define(self):
     # call to generate the circuit that takes the isometry to the first 2^m columns
     # of the 2^n identity matrix
     iso_circuit = self._gates_to_uncompute()
     # invert the circuit to create the circuit implementing the isometry
     gate = iso_circuit.to_instruction().inverse()
     q = QuantumRegister(self.num_qubits)
     iso_circuit = QuantumCircuit(q)
     iso_circuit.append(gate, q[:])
     self.definition = iso_circuit
Exemplo n.º 15
0
 def _circuit_rr(theta,
                 phi,
                 lam,
                 simplify=True,
                 atol=DEFAULT_ATOL):
     circuit = QuantumCircuit(1)
     if not simplify or not np.isclose(theta, -np.pi, atol=atol):
         circuit.append(RGate(theta + np.pi, np.pi / 2 - lam), [0])
     circuit.append(RGate(-np.pi, 0.5 * (phi - lam + np.pi)), [0])
     return circuit
    def __call__(self, target, basis_fidelity=None):
        """Decompose a two-qubit unitary over fixed basis + SU(2) using the best approximation given
        that each basis application has a finite fidelity.
        """
        basis_fidelity = basis_fidelity or self.basis_fidelity
        if hasattr(target, 'to_operator'):
            # If input is a BaseOperator subclass this attempts to convert
            # the object to an Operator so that we can extract the underlying
            # numpy matrix from `Operator.data`.
            target = target.to_operator().data
        if hasattr(target, 'to_matrix'):
            # If input is Gate subclass or some other class object that has
            # a to_matrix method this will call that method.
            target = target.to_matrix()
        # Convert to numpy array incase not already an array
        target = np.asarray(target, dtype=complex)
        # Check input is a 2-qubit unitary
        if target.shape != (4, 4):
            raise QiskitError(
                "TwoQubitBasisDecomposer: expected 4x4 matrix for target")
        if not is_unitary_matrix(target):
            raise QiskitError(
                "TwoQubitBasisDecomposer: target matrix is not unitary.")

        target_decomposed = TwoQubitWeylDecomposition(target)
        traces = self.traces(target_decomposed)
        expected_fidelities = [
            trace_to_fid(traces[i]) * basis_fidelity**i for i in range(4)
        ]

        best_nbasis = np.argmax(expected_fidelities)
        decomposition = self.decomposition_fns[best_nbasis](target_decomposed)
        decomposition_euler = [
            self._decomposer1q._decompose(x) for x in decomposition
        ]

        q = QuantumRegister(2)
        return_circuit = QuantumCircuit(q)
        return_circuit.global_phase = target_decomposed.global_phase
        return_circuit.global_phase -= best_nbasis * self.basis.global_phase
        if best_nbasis == 2:
            return_circuit.global_phase += np.pi
        for i in range(best_nbasis):
            return_circuit.compose(decomposition_euler[2 * i], [q[0]],
                                   inplace=True)
            return_circuit.compose(decomposition_euler[2 * i + 1], [q[1]],
                                   inplace=True)
            return_circuit.append(self.gate, [q[0], q[1]])
        return_circuit.compose(decomposition_euler[2 * best_nbasis], [q[0]],
                               inplace=True)
        return_circuit.compose(decomposition_euler[2 * best_nbasis + 1],
                               [q[1]],
                               inplace=True)

        return return_circuit
Exemplo n.º 17
0
 def _define(self):
     """Define the MCX gate using the Gray code."""
     # pylint: disable=cyclic-import
     from qiskit.circuit.quantumcircuit import QuantumCircuit
     from .u1 import MCU1Gate
     q = QuantumRegister(self.num_qubits, name='q')
     qc = QuantumCircuit(q, name=self.name)
     qc.h(q[-1])
     qc.append(MCU1Gate(numpy.pi, num_ctrl_qubits=self.num_ctrl_qubits),
               qargs=q[:])
     qc.h(q[-1])
     self.definition = qc
Exemplo n.º 18
0
def apply_reflection(reflection_name, coordinate):
    """
    Given a reflection type and a canonical coordinate, applies the reflection
    and describes a circuit which enacts the reflection + a global phase shift.
    """
    reflection_scalars, reflection_phase_shift, source_reflection_gates = reflection_options[
        reflection_name
    ]
    reflected_coord = [x * y for x, y in zip(reflection_scalars, coordinate)]
    source_reflection = QuantumCircuit(2)
    for gate in source_reflection_gates:
        source_reflection.append(gate(np.pi), [0])

    return reflected_coord, source_reflection, reflection_phase_shift
Exemplo n.º 19
0
def apply_shift(shift_name, coordinate):
    """
    Given a shift type and a canonical coordinate, applies the shift and
    describes a circuit which enacts the shift + a global phase shift.
    """
    shift_scalars, shift_phase_shift, source_shift_gates = shift_options[shift_name]
    shifted_coord = [np.pi / 2 * x + y for x, y in zip(shift_scalars, coordinate)]

    source_shift = QuantumCircuit(2)
    for gate in source_shift_gates:
        source_shift.append(gate(np.pi), [0])
        source_shift.append(gate(np.pi), [1])

    return shifted_coord, source_shift, shift_phase_shift
Exemplo n.º 20
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
Exemplo n.º 21
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(), qargs=q[:])
         self.definition = qc
     elif self.num_qubits == 5:
         qc.append(C4XGate(), qargs=q[:])
         self.definition = qc
     else:
         self.definition = qc
         self.definition.data = self._recurse(q[:-1], q_ancilla=q[-1])
Exemplo n.º 22
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)
Exemplo n.º 23
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)
Exemplo n.º 24
0
 def _circuit_xyx(theta, phi, lam, phase, simplify=True, atol=DEFAULT_ATOL):
     circuit = QuantumCircuit(1, global_phase=phase)
     if simplify and np.isclose(theta, 0.0, atol=atol):
         circuit.append(RXGate(phi + lam), [0])
         return circuit
     if not simplify or not np.isclose(lam, 0.0, atol=atol):
         circuit.append(RXGate(lam), [0])
     if not simplify or not np.isclose(theta, 0.0, atol=atol):
         circuit.append(RYGate(theta), [0])
     if not simplify or not np.isclose(phi, 0.0, atol=atol):
         circuit.append(RXGate(phi), [0])
     return circuit
Exemplo n.º 25
0
 def _circuit_zyz(theta, phi, lam, simplify=True, atol=DEFAULT_ATOL):
     circuit = QuantumCircuit(1)
     if simplify and np.isclose(theta, 0.0, atol=atol):
         circuit.append(RZGate(phi + lam), [0])
         return circuit
     if not simplify or not np.isclose(lam, 0.0, atol=atol):
         circuit.append(RZGate(lam), [0])
     if not simplify or not np.isclose(theta, 0.0, atol=atol):
         circuit.append(RYGate(theta), [0])
     if not simplify or not np.isclose(phi, 0.0, atol=atol):
         circuit.append(RZGate(phi), [0])
     return circuit
Exemplo n.º 26
0
 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
     circuit = QuantumCircuit(1, global_phase=phase)
     if simplify and (np.isclose(theta, 0.0, atol=atol, rtol=rtol)):
         if not np.isclose(
                 phi + lam, [0.0, 2 * np.pi], atol=atol, rtol=rtol).any():
             circuit.append(U1Gate(_mod2pi(phi + lam)), [0])
     elif simplify and np.isclose(theta, np.pi / 2, atol=atol, rtol=rtol):
         circuit.append(U2Gate(phi, lam), [0])
     else:
         circuit.append(U3Gate(theta, phi, lam), [0])
     return circuit
Exemplo n.º 27
0
 def _circuit_u1x(theta, phi, lam, phase, simplify=True, atol=DEFAULT_ATOL):
     # Shift theta and phi so decomposition is
     # U1(phi).X90.U1(theta).X90.U1(lam)
     theta += np.pi
     phi += np.pi
     # Check for decomposition into minimimal number required X90 pulses
     if simplify and np.isclose(abs(theta), np.pi, atol=atol):
         # Zero X90 gate decomposition
         circuit = QuantumCircuit(1, global_phase=phase)
         circuit.append(U1Gate(lam + phi + theta), [0])
         return circuit
     if simplify and np.isclose(abs(theta), np.pi / 2, atol=atol):
         # Single X90 gate decomposition
         circuit = QuantumCircuit(1, global_phase=phase)
         circuit.append(U1Gate(lam + theta), [0])
         circuit.append(RXGate(np.pi / 2), [0])
         circuit.append(U1Gate(phi + theta), [0])
         return circuit
     # General two-X90 gate decomposition
     circuit = QuantumCircuit(1, global_phase=phase)
     circuit.append(U1Gate(lam), [0])
     circuit.append(RXGate(np.pi / 2), [0])
     circuit.append(U1Gate(theta), [0])
     circuit.append(RXGate(np.pi / 2), [0])
     circuit.append(U1Gate(phi), [0])
     return circuit
Exemplo n.º 28
0
 def _circuit_zsx(theta, phi, lam, phase, simplify=True, atol=DEFAULT_ATOL):
     # Shift theta and phi so decomposition is
     # RZ(phi+pi).SX.RZ(theta+pi).SX.RZ(lam)
     theta = _mod2pi(theta + np.pi)
     phi = _mod2pi(phi + np.pi)
     circuit = QuantumCircuit(1, global_phase=phase - np.pi / 2)
     # Check for decomposition into minimimal number required SX gates
     if simplify and np.isclose(abs(theta), np.pi, atol=atol):
         if not np.isclose(_mod2pi(abs(lam + phi + theta)), [0., 2 * np.pi],
                           atol=atol).any():
             circuit.append(RZGate(_mod2pi(lam + phi + theta)), [0])
             circuit.global_phase += 0.5 * _mod2pi(lam + phi + theta)
         circuit.global_phase += np.pi / 2
     elif simplify and np.isclose(abs(theta), [np.pi / 2, 3 * np.pi / 2],
                                  atol=atol).any():
         if not np.isclose(_mod2pi(abs(lam + theta)), [0., 2 * np.pi],
                           atol=atol).any():
             circuit.append(RZGate(_mod2pi(lam + theta)), [0])
             circuit.global_phase += 0.5 * _mod2pi(lam + theta)
         circuit.append(SXGate(), [0])
         if not np.isclose(_mod2pi(abs(phi + theta)), [0., 2 * np.pi],
                           atol=atol).any():
             circuit.append(RZGate(_mod2pi(phi + theta)), [0])
             circuit.global_phase += 0.5 * _mod2pi(phi + theta)
         if np.isclose(theta, [-np.pi / 2, 3 * np.pi / 2], atol=atol).any():
             circuit.global_phase += np.pi / 2
     else:
         if not np.isclose(abs(lam), [0., 2 * np.pi], atol=atol).any():
             circuit.append(RZGate(lam), [0])
             circuit.global_phase += 0.5 * lam
         circuit.append(SXGate(), [0])
         if not np.isclose(abs(theta), [0., 2 * np.pi], atol=atol).any():
             circuit.append(RZGate(theta), [0])
             circuit.global_phase += 0.5 * theta
         circuit.append(SXGate(), [0])
         if not np.isclose(abs(phi), [0., 2 * np.pi], atol=atol).any():
             circuit.append(RZGate(phi), [0])
             circuit.global_phase += 0.5 * phi
     return circuit
Exemplo n.º 29
0
 def _circuit_u(theta, phi, lam, phase, simplify=True, atol=DEFAULT_ATOL):
     # pylint: disable=unused-argument
     circuit = QuantumCircuit(1, global_phase=phase)
     circuit.append(UGate(theta, phi, lam), [0])
     return circuit
Exemplo n.º 30
0
def _experiments_to_circuits(qobj):
    """Return a list of QuantumCircuit object(s) from a qobj.

    Args:
        qobj (Qobj): The Qobj object to convert to QuantumCircuits

    Returns:
        list: A list of QuantumCircuit objects from the qobj
    """
    if not qobj.experiments:
        return None

    circuits = []
    for exp in qobj.experiments:
        quantum_registers = [QuantumRegister(i[1], name=i[0]) for i in exp.header.qreg_sizes]
        classical_registers = [ClassicalRegister(i[1], name=i[0]) for i in exp.header.creg_sizes]
        circuit = QuantumCircuit(*quantum_registers, *classical_registers, name=exp.header.name)
        qreg_dict = collections.OrderedDict()
        creg_dict = collections.OrderedDict()
        for reg in quantum_registers:
            qreg_dict[reg.name] = reg
        for reg in classical_registers:
            creg_dict[reg.name] = reg
        conditional = {}
        for i in exp.instructions:
            name = i.name
            qubits = []
            params = getattr(i, "params", [])
            try:
                for qubit in i.qubits:
                    qubit_label = exp.header.qubit_labels[qubit]
                    qubits.append(qreg_dict[qubit_label[0]][qubit_label[1]])
            except Exception:  # pylint: disable=broad-except
                pass
            clbits = []
            try:
                for clbit in i.memory:
                    clbit_label = exp.header.clbit_labels[clbit]
                    clbits.append(creg_dict[clbit_label[0]][clbit_label[1]])
            except Exception:  # pylint: disable=broad-except
                pass
            if hasattr(circuit, name):
                instr_method = getattr(circuit, name)
                if i.name in ["snapshot"]:
                    _inst = instr_method(
                        i.label, snapshot_type=i.snapshot_type, qubits=qubits, params=params
                    )
                elif i.name == "initialize":
                    _inst = instr_method(params, qubits)
                elif i.name == "isometry":
                    _inst = instr_method(*params, qubits, clbits)
                elif i.name in ["mcx", "mcu1", "mcp"]:
                    _inst = instr_method(*params, qubits[:-1], qubits[-1], *clbits)
                else:
                    _inst = instr_method(*params, *qubits, *clbits)
            elif name == "bfunc":
                conditional["value"] = int(i.val, 16)
                full_bit_size = sum(creg_dict[x].size for x in creg_dict)
                mask_map = {}
                raw_map = {}
                raw = []

                for creg in creg_dict:
                    size = creg_dict[creg].size
                    reg_raw = [1] * size
                    if not raw:
                        raw = reg_raw
                    else:
                        for pos, val in enumerate(raw):
                            if val == 1:
                                raw[pos] = 0
                        raw = reg_raw + raw
                    mask = [0] * (full_bit_size - len(raw)) + raw
                    raw_map[creg] = mask
                    mask_map[int("".join(str(x) for x in mask), 2)] = creg
                creg = mask_map[int(i.mask, 16)]
                conditional["register"] = creg_dict[creg]
                val = int(i.val, 16)
                mask = raw_map[creg]
                for j in reversed(mask):
                    if j == 0:
                        val = val >> 1
                    else:
                        conditional["value"] = val
                        break
            else:
                _inst = temp_opaque_instruction = Instruction(
                    name=name, num_qubits=len(qubits), num_clbits=len(clbits), params=params
                )
                circuit.append(temp_opaque_instruction, qubits, clbits)
            if conditional and name != "bfunc":
                _inst.c_if(conditional["register"], conditional["value"])
                conditional = {}
        pulse_lib = qobj.config.pulse_library if hasattr(qobj.config, "pulse_library") else []
        parametric_pulses = (
            qobj.config.parametric_pulses if hasattr(qobj.config, "parametric_pulses") else []
        )
        # The dict update method did not work here; could investigate in the future
        if hasattr(qobj.config, "calibrations"):
            circuit.calibrations = dict(
                **circuit.calibrations, **_qobj_to_circuit_cals(qobj, pulse_lib, parametric_pulses)
            )
        if hasattr(exp.config, "calibrations"):
            circuit.calibrations = dict(
                **circuit.calibrations, **_qobj_to_circuit_cals(exp, pulse_lib, parametric_pulses)
            )
        circuits.append(circuit)
    return circuits