def build_correction(self):
     # Build Correction Circuit
     circ = QuantumCircuit(self.code, self.syndrm)
     circ.append(XGate().control(4, ctrl_state='0010'),
                 [self.syndrm[i] for i in range(4)] + [self.code[0]])
     circ.append(YGate().control(4, ctrl_state='1110'),
                 [self.syndrm[i] for i in range(4)] + [self.code[0]])
     circ.append(ZGate().control(4, ctrl_state='1100'),
                 [self.syndrm[i] for i in range(4)] + [self.code[0]])
     circ.append(XGate().control(4, ctrl_state='0101'),
                 [self.syndrm[i] for i in range(4)] + [self.code[1]])
     circ.append(YGate().control(4, ctrl_state='1101'),
                 [self.syndrm[i] for i in range(4)] + [self.code[1]])
     circ.append(ZGate().control(4, ctrl_state='1000'),
                 [self.syndrm[i] for i in range(4)] + [self.code[1]])
     circ.append(XGate().control(4, ctrl_state='1010'),
                 [self.syndrm[i] for i in range(4)] + [self.code[2]])
     circ.append(YGate().control(4, ctrl_state='1011'),
                 [self.syndrm[i] for i in range(4)] + [self.code[2]])
     circ.append(ZGate().control(4, ctrl_state='0001'),
                 [self.syndrm[i] for i in range(4)] + [self.code[2]])
     circ.append(XGate().control(4, ctrl_state='0100'),
                 [self.syndrm[i] for i in range(4)] + [self.code[3]])
     circ.append(YGate().control(4, ctrl_state='0111'),
                 [self.syndrm[i] for i in range(4)] + [self.code[3]])
     circ.append(ZGate().control(4, ctrl_state='0011'),
                 [self.syndrm[i] for i in range(4)] + [self.code[3]])
     circ.append(XGate().control(4, ctrl_state='1001'),
                 [self.syndrm[i] for i in range(4)] + [self.code[4]])
     circ.append(YGate().control(4, ctrl_state='1111'),
                 [self.syndrm[i] for i in range(4)] + [self.code[4]])
     circ.append(ZGate().control(4, ctrl_state='0110'),
                 [self.syndrm[i] for i in range(4)] + [self.code[4]])
     return circ
Example #2
0
    def to_instruction(self):
        """Convert to Pauli circuit instruction."""
        from math import pi

        pauli, phase = self._to_label(self.z,
                                      self.x,
                                      self._phase[0],
                                      full_group=False,
                                      return_phase=True)
        if len(pauli) == 1:
            gate = {
                "I": IGate(),
                "X": XGate(),
                "Y": YGate(),
                "Z": ZGate()
            }[pauli]
        else:
            gate = PauliGate(pauli)
        if not phase:
            return gate
        # Add global phase
        circuit = QuantumCircuit(self.num_qubits, name=str(self))
        circuit.global_phase = -phase * pi / 2
        circuit.append(gate, range(self.num_qubits))
        return circuit.to_instruction()
Example #3
0
 def setUp(self):
     super().setUp()
     self.ops = {
         'X': XGate(),
         'Y': YGate(),
         'Z': ZGate(),
         'H': HGate(),
         'S': SGate()
     }
Example #4
0
    def from_label(cls, label):
        """Return a tensor product of single-qubit operators.

        Args:
            label (string): single-qubit operator string.

        Returns:
            Operator: The N-qubit operator.

        Raises:
            QiskitError: if the label contains invalid characters, or the
                         length of the label is larger than an explicitly
                         specified num_qubits.

        Additional Information:
            The labels correspond to the single-qubit matrices:
            'I': [[1, 0], [0, 1]]
            'X': [[0, 1], [1, 0]]
            'Y': [[0, -1j], [1j, 0]]
            'Z': [[1, 0], [0, -1]]
            'H': [[1, 1], [1, -1]] / sqrt(2)
            'S': [[1, 0], [0 , 1j]]
            'T': [[1, 0], [0, (1+1j) / sqrt(2)]]
            '0': [[1, 0], [0, 0]]
            '1': [[0, 0], [0, 1]]
            '+': [[0.5, 0.5], [0.5 , 0.5]]
            '-': [[0.5, -0.5], [-0.5 , 0.5]]
            'r': [[0.5, -0.5j], [0.5j , 0.5]]
            'l': [[0.5, 0.5j], [-0.5j , 0.5]]
        """
        # Check label is valid
        label_mats = {
            'I': IGate().to_matrix(),
            'X': XGate().to_matrix(),
            'Y': YGate().to_matrix(),
            'Z': ZGate().to_matrix(),
            'H': HGate().to_matrix(),
            'S': SGate().to_matrix(),
            'T': TGate().to_matrix(),
            '0': np.array([[1, 0], [0, 0]], dtype=complex),
            '1': np.array([[0, 0], [0, 1]], dtype=complex),
            '+': np.array([[0.5, 0.5], [0.5, 0.5]], dtype=complex),
            '-': np.array([[0.5, -0.5], [-0.5, 0.5]], dtype=complex),
            'r': np.array([[0.5, -0.5j], [0.5j, 0.5]], dtype=complex),
            'l': np.array([[0.5, 0.5j], [-0.5j, 0.5]], dtype=complex),
        }
        if re.match(r'^[IXYZHST01rl\-+]+$', label) is None:
            raise QiskitError('Label contains invalid characters.')
        # Initialize an identity matrix and apply each gate
        num_qubits = len(label)
        op = Operator(np.eye(2 ** num_qubits, dtype=complex))
        for qubit, char in enumerate(reversed(label)):
            if char != 'I':
                op = op.compose(label_mats[char], qargs=[qubit])
        return op
Example #5
0
    def from_label(label):
        """Return a tensor product of single-qubit Clifford gates.

        Args:
            label (string): single-qubit operator string.

        Returns:
            Clifford: The N-qubit Clifford operator.

        Raises:
            QiskitError: if the label contains invalid characters.

        Additional Information:
            The labels correspond to the single-qubit Cliffords are

            * - Label
              - Stabilizer
              - Destabilizer
            * - ``"I"``
              - +Z
              - +X
            * - ``"X"``
              - -Z
              - +X
            * - ``"Y"``
              - -Z
              - -X
            * - ``"Z"``
              - +Z
              - -X
            * - ``"H"``
              - +X
              - +Z
            * - ``"S"``
              - +Z
              - +Y
        """
        # Check label is valid
        label_gates = {
            'I': IGate(),
            'X': XGate(),
            'Y': YGate(),
            'Z': ZGate(),
            'H': HGate(),
            'S': SGate()
        }
        if re.match(r'^[IXYZHS\-+]+$', label) is None:
            raise QiskitError('Label contains invalid characters.')
        # Initialize an identity matrix and apply each gate
        num_qubits = len(label)
        op = Clifford(np.eye(2 * num_qubits, dtype=np.bool))
        for qubit, char in enumerate(reversed(label)):
            _append_circuit(op, label_gates[char], qargs=[qubit])
        return op
Example #6
0
 def to_instruction(self):
     """Convert to Pauli circuit instruction."""
     from qiskit.circuit import QuantumCircuit, QuantumRegister
     from qiskit.circuit.library.standard_gates import IGate, XGate, YGate, ZGate
     gates = {'I': IGate(), 'X': XGate(), 'Y': YGate(), 'Z': ZGate()}
     label = self.to_label()
     num_qubits = self.num_qubits
     qreg = QuantumRegister(num_qubits)
     circuit = QuantumCircuit(qreg, name='Pauli:{}'.format(label))
     for i, pauli in enumerate(reversed(label)):
         circuit.append(gates[pauli], [qreg[i]])
     return circuit.to_instruction()
Example #7
0
    def test_pauli_error_1q_gate_from_string(self):
        """Test single-qubit pauli error as gate qobj from string label"""
        paulis = ['I', 'X', 'Y', 'Z']
        probs = [0.4, 0.3, 0.2, 0.1]
        actual = pauli_error(zip(paulis, probs))

        expected = QuantumError([(IGate(), 0.4), (XGate(), 0.3), (YGate(), 0.2), (ZGate(), 0.1)])
        for i in range(actual.size):
            circ, prob = actual.error_term(i)
            expected_circ, expected_prob = expected.error_term(i)
            self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit")
            self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
Example #8
0
    def test_depolarizing_error_1q_gate(self):
        """Test 1-qubit depolarizing error as gate qobj"""
        p_depol = 0.3
        actual = depolarizing_error(p_depol, 1)

        expected = QuantumError([
            (IGate(), 1 - p_depol*3/4),
            (XGate(), p_depol/4),
            (YGate(), p_depol/4),
            (ZGate(), p_depol/4)
        ])
        for i in range(actual.size):
            circ, prob = actual.error_term(i)
            expected_circ, expected_prob = expected.error_term(i)
            self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit")
            self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
Example #9
0
        if a ``dict`` is given, ``list`` is overwritten.
        The ``string`` supports only 1- or 2-qubit errors and
        its possible values are ``'pauli'``, ``'reset'``, ``'clifford'``.
        The ``'clifford'`` does not support 2-qubit errors.
    """
    def approximate(noise):
        return approximate_quantum_error(noise,
                                         operator_string=operator_string,
                                         operator_dict=operator_dict,
                                         operator_list=operator_list)

    return transform_noise_model(model, approximate)


# pauli operators
_PAULIS_Q0 = [[(IGate(), [0])], [(XGate(), [0])], [(YGate(), [0])],
              [(ZGate(), [0])]]
_PAULIS_Q1 = [[(IGate(), [1])], [(XGate(), [1])], [(YGate(), [1])],
              [(ZGate(), [1])]]
_PAULIS_Q0Q1 = [op_q0 + op_q1 for op_q0 in _PAULIS_Q0 for op_q1 in _PAULIS_Q1]
# reset operators
_RESET_Q0_TO_0 = [(Reset(), [0])]
_RESET_Q0_TO_1 = [(Reset(), [0]), (XGate(), [0])]
_RESET_Q0 = [[(IGate(), [0])], _RESET_Q0_TO_0, _RESET_Q0_TO_1]
_RESET_Q1_TO_0 = [(Reset(), [1])]
_RESET_Q1_TO_1 = [(Reset(), [1]), (XGate(), [1])]
_RESET_Q1 = [[(IGate(), [1])], _RESET_Q1_TO_0, _RESET_Q1_TO_1]
_RESET_Q0Q1 = [op_q0 + op_q1 for op_q0 in _RESET_Q0 for op_q1 in _RESET_Q1]
# preset operator table
_PRESET_OPERATOR_TABLE = {
    "pauli": {
Example #10
0
def _standard_gate_instruction(instruction, ignore_phase=True):
    """Temporary function to create Instruction objects from a json string,
    which is necessary for creating a new QuantumError object from deprecated
    json-based input. Note that the type of returned object is different from
    the deprecated standard_gate_instruction.
    TODO: to be removed after deprecation period.

    Args:
        instruction (dict): A qobj instruction.
        ignore_phase (bool): Ignore global phase on unitary matrix in
                             comparison to canonical unitary.

    Returns:
        list: a list of (instructions, qubits) equivalent to in input instruction.
    """
    gate = {
        "id": IGate(),
        "x": XGate(),
        "y": YGate(),
        "z": ZGate(),
        "h": HGate(),
        "s": SGate(),
        "sdg": SdgGate(),
        "t": TGate(),
        "tdg": TdgGate(),
        "cx": CXGate(),
        "cz": CZGate(),
        "swap": SwapGate()
    }

    name = instruction.get("name", None)
    qubits = instruction["qubits"]
    if name in gate:
        return [(gate[name], qubits)]

    if name not in ["mat", "unitary", "kraus"]:
        return [instruction]

    params = instruction["params"]
    with warnings.catch_warnings():
        warnings.filterwarnings("ignore",
                                category=DeprecationWarning,
                                module="qiskit.providers.aer.noise.errors.errorutils")

        # Check for single-qubit reset Kraus
        if name == "kraus":
            if len(qubits) == 1:
                superop = SuperOp(Kraus(params))
                # Check if reset to |0>
                reset0 = reset_superop(1)
                if superop == reset0:
                    return [(Reset(), [0])]
                # Check if reset to |1>
                reset1 = reset0.compose(Operator(standard_gate_unitary('x')))
                if superop == reset1:
                    return [(Reset(), [0]), (XGate(), [0])]
            return [instruction]

        # Check single qubit gates
        mat = params[0]
        if len(qubits) == 1:
            # Check clifford gates
            for j in range(24):
                if matrix_equal(
                        mat,
                        single_qubit_clifford_matrix(j),
                        ignore_phase=ignore_phase):
                    return [(gate, [0]) for gate in _CLIFFORD_GATES[j]]
            # Check t gates
            for name in ["t", "tdg"]:
                if matrix_equal(
                        mat,
                        standard_gate_unitary(name),
                        ignore_phase=ignore_phase):
                    return [(gate[name], qubits)]
            # TODO: u1,u2,u3 decomposition
        # Check two qubit gates
        if len(qubits) == 2:
            for name in ["cx", "cz", "swap"]:
                if matrix_equal(
                        mat,
                        standard_gate_unitary(name),
                        ignore_phase=ignore_phase):
                    return [(gate[name], qubits)]
            # Check reversed CX
            if matrix_equal(
                    mat,
                    standard_gate_unitary("cx_10"),
                    ignore_phase=ignore_phase):
                return [(CXGate(), [qubits[1], qubits[0]])]
            # Check 2-qubit Pauli's
            paulis = ["id", "x", "y", "z"]
            for pauli0 in paulis:
                for pauli1 in paulis:
                    pmat = np.kron(
                        standard_gate_unitary(pauli1),
                        standard_gate_unitary(pauli0))
                    if matrix_equal(mat, pmat, ignore_phase=ignore_phase):
                        if pauli0 == "id":
                            return [(gate[pauli1], [qubits[1]])]
                        elif pauli1 == "id":
                            return [(gate[pauli0], [qubits[0]])]
                        else:
                            return [(gate[pauli0], [qubits[0]]), (gate[pauli1], [qubits[1]])]
        # Check three qubit toffoli
        if len(qubits) == 3:
            if matrix_equal(
                    mat,
                    standard_gate_unitary("ccx_012"),
                    ignore_phase=ignore_phase):
                return [(CCXGate(), qubits)]
            if matrix_equal(
                    mat,
                    standard_gate_unitary("ccx_021"),
                    ignore_phase=ignore_phase):
                return [(CCXGate(), [qubits[0], qubits[2], qubits[1]])]
            if matrix_equal(
                    mat,
                    standard_gate_unitary("ccx_120"),
                    ignore_phase=ignore_phase):
                return [(CCXGate(), [qubits[1], qubits[2], qubits[0]])]

    # Else return input in
    return [instruction]
Example #11
0
    (HGate(), SGate()),
    (SGate(), HGate()),
    (HGate(), SdgGate()),
    (SdgGate(), HGate()),
    (SGate(), HGate(), SGate()),
    (SdgGate(), HGate(), SGate()),
    (ZGate(), HGate(), SGate()),
    (SGate(), HGate(), SdgGate()),
    (SdgGate(), HGate(), SdgGate()),
    (ZGate(), HGate(), SdgGate()),
    (SGate(), HGate(), ZGate()),
    (SdgGate(), HGate(), ZGate()),
    (ZGate(), HGate(), ZGate()),
    # u3 gates
    (XGate(), ),
    (YGate(), ),
    (SGate(), XGate()),
    (SdgGate(), XGate())
]


def single_qubit_clifford_matrix(j):
    """Return Numpy array for a single qubit Clifford.
    Args:
        j (int): Clifford index 0, ..., 23.
    Returns:
        np.array: The matrix for the indexed clifford.
    Raises:
        NoiseError: If index is out of range [0, 23].
    """
    warnings.warn(
Example #12
0
def depolarizing_error(param, num_qubits, standard_gates=None):
    r"""
    Return a depolarizing quantum error channel.

    The depolarizing channel is defined as:

    .. math::

        E(ρ) = (1 - λ) ρ + λ \text{Tr}[ρ] \frac{I}{2^n}

    with :math:`0 \le λ \le 4^n / (4^n - 1)`

    where :math:`λ` is the depolarizing error param and :math`n` is the
    number of qubits.

    * If :math:`λ = 0` this is the identity channel :math:`E(ρ) = ρ`
    * If :math:`λ = 1` this is a completely depolarizing channel
      :math:`E(ρ) = I / 2^n`
    * If :math:`λ = 4^n / (4^n - 1)` this is a uniform Pauli
      error channel: :math:`E(ρ) = \sum_j P_j ρ P_j / (4^n - 1)` for
      all :math:`P_j != I`.

    Args:
        param (double): depolarizing error parameter.
        num_qubits (int): the number of qubits for the error channel.
        standard_gates (bool): DEPRECATED, if True return the operators as
                               Pauli gates. If false return as unitary gates.
                               (Default: None)

    Returns:
        QuantumError: The quantum error object.

    Raises:
        NoiseError: If noise parameters are invalid.
    """
    if not isinstance(num_qubits, int) or num_qubits < 1:
        raise NoiseError("num_qubits must be a positive integer.")
    # Check that the depolarizing parameter gives a valid CPTP
    num_terms = 4**num_qubits
    max_param = num_terms / (num_terms - 1)
    if param < 0 or param > max_param:
        raise NoiseError("Depolarizing parameter must be in between 0 "
                         "and {}.".format(max_param))

    # Rescale completely depolarizing channel error probs
    # with the identity component removed
    prob_iden = 1 - param / max_param
    prob_pauli = param / num_terms
    probs = [prob_iden] + (num_terms - 1) * [prob_pauli]

    if standard_gates is not None:
        warnings.warn(
            '"standard_gates" option has been deprecated as of qiskit-aer 0.10.0'
            ' and will be removed no earlier than 3 months from that release date.',
            DeprecationWarning,
            stacklevel=2)
        circs = []
        for pauli_list in it.product(
            [IGate(), XGate(), YGate(), ZGate()], repeat=num_qubits):
            qc = QuantumCircuit(num_qubits)
            for q, pauli in enumerate(pauli_list):
                if not standard_gates:
                    pauli = UnitaryGate(pauli.to_matrix())
                qc.append(pauli, qargs=[q])
            circs.append(qc)
        return QuantumError(zip(circs, probs))

    # Generate pauli strings. The order doesn't matter as long
    # as the all identity string is first.
    paulis = [
        Pauli("".join(tup))
        for tup in it.product(['I', 'X', 'Y', 'Z'], repeat=num_qubits)
    ]
    return QuantumError(zip(paulis, probs))