Source code for qrisp.misc.stim_tools.stim_noise_gate_application_functions

"""
********************************************************************************
* Copyright (c) 2026 the Qrisp authors
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is
* available at https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************
"""

import stim
from qrisp.core import append_operation
from qrisp.jasp import check_for_tracing_mode
from qrisp.misc.stim_tools.error_class import StimNoiseGate
from sympy import symbols

greek_letters = symbols(
    "alpha beta gamma delta epsilon zeta eta theta iota kappa lambda mu nu xi omicron pi rho sigma tau upsilon phi chi psi omega"
)


[docs] def stim_noise(stim_name, *parameters_and_qubits, pauli_string=None): """ Applies a ``StimNoiseGate`` to the given qubits. For a list of supported error instructions, please check `Stims gate reference <https://github.com/quantumlib/Stim/blob/main/doc/gates.md#noise-channels>`_. Some of the most common errors are listed below: .. list-table:: :widths: 25 75 :header-rows: 1 * - Name - Description * - ``DEPOLARIZE1`` - Single qubit depolarizing noise. This channel applies one of the Pauli errors X, Y, Z with probability $p/3$. * - ``DEPOLARIZE2`` - Two qubit depolarizing noise. This channel applies one of the 15 non-identity two-qubit Pauli errors (IX, IY, ..., ZZ) with probability $p/15$. * - ``X_ERROR`` - Single qubit Pauli-X error (Bit flip). Applies X with probability $p$. * - ``Y_ERROR`` - Single qubit Pauli-Y error. Applies Y with probability $p$. * - ``Z_ERROR`` - Single qubit Pauli-Z error (Phase flip). Applies Z with probability $p$. * - ``PAULI_CHANNEL_1`` - Custom single qubit Pauli channel. Takes 3 arguments (px, py, pz) specifying the probabilities of applying X, Y, and Z errors respectively. * - ``PAULI_CHANNEL_2`` - Custom two qubit Pauli channel. Takes 15 arguments specifying the probabilities of applying each of the 15 non-identity two-qubit Pauli errors. * - ``E`` (or ``CORRELATED_ERROR``) - Correlated Pauli error on multiple qubits (requires ``pauli_string`` argument). Applies the specified Pauli string with probability $p$. * - ``ELSE_CORRELATED_ERROR`` - Similar to ``CORRELATED_ERROR`` but only applies if the *previous* error instruction did NOT apply an error. This allows constructing more complex conditional error models. .. warning:: Every noisy operation described here behaves as a purely unitary identity gate, unless the compilation target is indeed Stim (see :meth:`~qrisp.QuantumCircuit.to_stim`). This means for instance that :meth:`~qrisp.QuantumCircuit.to_qiskit` converts the noisy operations to trivial identity gates. The same applies to the behavior of the Qrisp simulator. In other words - the noisy operations will only behave noisy if pushed through the Stim compiler. Parameters ---------- stim_name : str The name of the Stim error gate (e.g. ``DEPOLARIZE1``, ``X_ERROR``, ``CORRELATED_ERROR``). *parameters : float The parameters of the error channel (e.g. error probability). Further details about the semantics of the parameters can be found in the `Stims gate reference <https://github.com/quantumlib/Stim/blob/main/doc/gates.md#noise-channels>`_. *qubits : Qubit The qubits to apply the error channel to. pauli_string : str, optional A string of Pauli operators (e.g. ``XX``, ``IZ``, ``Y``) characterizing the error. This is required for correlated errors (e.g. ``E``, ``CORRELATED_ERROR``). Examples -------- We construct a noisy Bell-pair using the :func:`~qrisp.jasp.extract_stim` decorator. :: from qrisp import * from qrisp.misc.stim_tools import stim_noise @extract_stim def generate_noisy_bell_pair(): qv = QuantumVariable(2) h(qv[0]) cx(qv[0], qv[1]) # Add single qubit noise stim_noise("X_ERROR", 0.1, qv[0]) stim_noise("X_ERROR", 0.1, qv[1]) # Add correlated multi-qubit noise stim_noise("E", 0.1, qv[0], qv[1], pauli_string = "XX") return measure(qv) # Generate result indices and stim circuit res_indices, stim_circuit = generate_noisy_bell_pair() # Compile sampler and sample sampler = stim_circuit.compile_sampler() all_samples = sampler.sample(1000) # Extract results through slicing samples = all_samples[:, res_indices] print(samples) # Yields: # array([[False, True], # [False, True], # [ True, True], # ..., # [ True, True], # [ True, True], # [False, False]], shape=(1000, 2)) """ error_data = stim.gate_data(stim_name) if pauli_string is not None: # Check for compatibility if not (stim_name in ["E", "CORRELATED_ERROR", "ELSE_CORRELATED_ERROR"]): raise Exception( f"Stim error {stim_name} does not support Pauli strings. Supported gates are E, CORRELATED_ERROR, ELSE_CORRELATED_ERROR" ) num_qubits = len(pauli_string) elif error_data.is_single_qubit_gate: num_qubits = 1 elif error_data.is_two_qubit_gate: num_qubits = 2 else: raise Exception( f"Could not determine qubit amount for Stim error {stim_name}. Please check if the error is supported." ) params = parameters_and_qubits[:-num_qubits] qubits = parameters_and_qubits[-num_qubits:] if check_for_tracing_mode(): error_op = StimNoiseGate( stim_name, *greek_letters[: len(params)], pauli_string=pauli_string ) append_operation(error_op, qubits=qubits, param_tracers=list(params)) else: error_op = StimNoiseGate(stim_name, *params, pauli_string=pauli_string) append_operation(error_op, qubits=qubits)