qrisp.parity#

parity(*measurements, expectation=0, observable=False)[source]#

Computes the parity on a set of measurement results. This is equivalent to performing a multi-input XOR gate.

In mathematical terms, if given the inputs \(\{x_i \in \mathbb{F}_2\| 0 \leq i < n \}\) the output of this function is therefore

\[p = \bigoplus_{i=0}^{n-1} x_i\]

A common usecase for this quanity are certain checks within quantum error correction circuits. In this scenario, the programmer ensures that a certain set of measurements has a deterministic parity. If this is not satisfied during the execution, it indicates the presence of an error.

This type of parity check is also called a “detector”. The set of detector values together with the “detector error model” is then consumed by the decoder, providing an educated guess, which error caused the parity check to fail.

Within Qrisp, the parity function can receive the expectation keyword argument with values 0 or 1, and the observable keyword argument (boolean). The default is expectation=0, observable=False.

The parity function returns:

\[p = x_{\text{exp}} \oplus \left( \bigoplus_{i=0}^{n-1} x_i \right)\]

This implies that the parity function returns True if the expectation is NOT met.

Array Support: If the measurement inputs are arrays, all arrays must have exactly the same shape (no broadcasting). The function applies the parity computation element-wise, returning an array of the same shape. Mixing scalar and array inputs is not allowed.

Note

When used within a function decorated with extract_stim(), this function is translated into Stim’s DETECTOR or OBSERVABLE_INCLUDE instructions in the generated circuit.

  • If observable=False (default), a DETECTOR instruction is created.

  • If observable=True, an OBSERVABLE_INCLUDE instruction is created.

If executed without extract_stim (i.e., in regular Qrisp simulation via jaspify(), for instance), and observable=False, the function verifies that the measured parity matches the expectation provided. Deviations from the parity expectation should solely stem from hardware noise, i.e. a deviation in a noiseless simulation is an error in the program. Because of this, an Exception is raised when the verification fails. However, when extracted to Stim, this verification is NOT performed during the extraction or simulation process (Stim detectors record differences but do not stop execution).

Warning

This function only works in tracing mode (i.e., inside a jaspify() or extract_stim() decorated function). It cannot be called in static mode. To annotate parity operations on a QuantumCircuit directly, use the parity() method instead.

Parameters:
*measurementslist[Tracer[boolean] | array[boolean]]

Variable length argument list of measurement results (typically outcomes of measure or similar operations). Can be scalars or arrays. All array inputs must have exactly the same shape. Mixing scalar and array inputs is not allowed.

expectationint, optional

The expected value of the parity of the measurement results. Must be 0 or 1. The return value indicates if the actual parity differs from this expectation. Default is 0.

observablebool, optional

If True, this parity is treated as a Stim OBSERVABLE_INCLUDE instruction rather than a DETECTOR. Default is False.

Returns:
Tracer[boolean] | array[boolean]

A boolean value representing the parity. Returns scalar if all inputs are scalars, otherwise returns an array with the broadcasted shape of the inputs.

Examples

We measure the parity of the 4 qubit GHZ state:

\[\ket{\text{GHZ}} = \frac{\ket{0000} + \ket{1111}}{\sqrt{2}}\]
from qrisp import *

@jaspify
def main():

    qv = QuantumVariable(4)
    h(qv[0])
    cx(qv[0], qv[1])
    cx(qv[0], qv[2])
    cx(qv[0], qv[3])

    a, b, c, d = tuple(measure(qv[i]) for i in range(4))
    return parity(a, b, c, d)

print(main())
# Yields False

Array example with element-wise parity:

from qrisp import *
import jax.numpy as jnp

@jaspify
def array_parity():
    # Create arrays of measurements
    a = jnp.array([True, False, True])
    b = jnp.array([True, False, True])

    # Compute element-wise parity
    result = parity(a, b)
    return result

print(array_parity())
# Yields [False, False, False]