Skip to content

Stim v1.3 Python API Reference

Craig Gidney edited this page May 27, 2021 · 1 revision

stim.Circuit

A mutable stabilizer circuit.

Examples:
    >>> import stim
    >>> c = stim.Circuit()
    >>> c.append_operation("X", [0])
    >>> c.append_operation("M", [0])
    >>> c.compile_sampler().sample(shots=1)
    array([[1]], dtype=uint8)

    >>> stim.Circuit('''
    ...    H 0
    ...    CNOT 0 1
    ...    M 0 1
    ...    DETECTOR rec[-1] rec[-2]
    ... ''').compile_detector_sampler().sample(shots=1)
    array([[0]], dtype=uint8)

stim.CompiledDetectorSampler

An analyzed stabilizer circuit whose detection events can be sampled quickly.

stim.CompiledMeasurementSampler

An analyzed stabilizer circuit whose measurements can be sampled quickly.

stim.PauliString

A signed Pauli tensor product (e.g. "+X \u2297 X \u2297 X" or "-Y \u2297 Z".

Represents a collection of Pauli operations (I, X, Y, Z) applied pairwise to a collection of qubits.

Examples:
    >>> import stim
    >>> stim.PauliString("XX") * stim.PauliString("YY")
    stim.PauliString("-ZZ")
    >>> print(stim.PauliString(5))
    +_____

stim.Tableau

A stabilizer tableau.

Represents a Clifford operation by explicitly storing how that operation conjugates a list of Pauli
group generators into composite Pauli products.

Examples:
    >>> import stim
    >>> stim.Tableau.from_named_gate("H")
    stim.Tableau.from_conjugated_generators(
        xs=[
            stim.PauliString("+Z"),
        ],
        zs=[
            stim.PauliString("+X"),
        ],
    )

    >>> t = stim.Tableau.random(5)
    >>> t_inv = t**-1
    >>> print(t * t_inv)
    +-xz-xz-xz-xz-xz-
    | ++ ++ ++ ++ ++
    | XZ __ __ __ __
    | __ XZ __ __ __
    | __ __ XZ __ __
    | __ __ __ XZ __
    | __ __ __ __ XZ

    >>> x2z3 = t.x_output(2) * t.z_output(3)
    >>> t_inv(x2z3)
    stim.PauliString("+__XZ_")

stim.TableauSimulator

A quantum stabilizer circuit simulator whose internal state is an inverse stabilizer tableau.

Supports interactive usage, where gates and measurements are applied on demand.

Examples:
    >>> import stim
    >>> s = stim.TableauSimulator()
    >>> s.h(0)
    >>> if s.measure(0):
    ...     s.h(1)
    ...     s.cnot(1, 2)
    >>> s.measure(1) == s.measure(2)
    True

    >>> s = stim.TableauSimulator()
    >>> s.h(0)
    >>> s.cnot(0, 1)
    >>> s.current_inverse_tableau()
    stim.Tableau.from_conjugated_generators(
        xs=[
            stim.PauliString("+ZX"),
            stim.PauliString("+_X"),
        ],
        zs=[
            stim.PauliString("+X_"),
            stim.PauliString("+XZ"),
        ],
    )

stim.target_inv(qubit_index: int) -> int

Returns a target flagged as inverted that can be passed into Circuit.append_operation
For example, the '!1' in 'M 0 !1 2' is qubit 1 flagged as inverted,
meaning the measurement result from qubit 1 should be inverted when reported.

stim.target_rec(lookback_index: int) -> int

Returns a record target that can be passed into Circuit.append_operation.
For example, the 'rec[-2]' in 'DETECTOR rec[-2]' is a record target.

stim.target_x(qubit_index: int) -> int

Returns a target flagged as Pauli X that can be passed into Circuit.append_operation
For example, the 'X1' in 'CORRELATED_ERROR(0.1) X1 Y2 Z3' is qubit 1 flagged as Pauli X.

stim.target_y(qubit_index: int) -> int

Returns a target flagged as Pauli Y that can be passed into Circuit.append_operation
For example, the 'Y2' in 'CORRELATED_ERROR(0.1) X1 Y2 Z3' is qubit 2 flagged as Pauli Y.

stim.target_z(qubit_index: int) -> int

Returns a target flagged as Pauli Z that can be passed into Circuit.append_operation
For example, the 'Z3' in 'CORRELATED_ERROR(0.1) X1 Y2 Z3' is qubit 3 flagged as Pauli Z.

stim.Circuit.__add__(self, second: stim.Circuit) -> stim.Circuit

Creates a circuit by appending two circuits.

Examples:
    >>> import stim
    >>> c1 = stim.Circuit('''
    ...    X 0
    ...    Y 1 2
    ... ''')
    >>> c2 = stim.Circuit('''
    ...    M 0 1 2
    ... ''')
    >>> print(c1 + c2)
    X 0
    Y 1 2
    M 0 1 2

stim.Circuit.__eq__(self, arg0: stim.Circuit) -> bool

Determines if two circuits have identical contents.

stim.Circuit.__iadd__(self, second: stim.Circuit) -> stim.Circuit

Appends a circuit into the receiving circuit (mutating it).

Examples:
    >>> import stim
    >>> c1 = stim.Circuit('''
    ...    X 0
    ...    Y 1 2
    ... ''')
    >>> c2 = stim.Circuit('''
    ...    M 0 1 2
    ... ''')
    >>> c1 += c2
    >>> print(c1)
    X 0
    Y 1 2
    M 0 1 2

stim.Circuit.__imul__(self, repetitions: int) -> stim.Circuit

Mutates the circuit into multiple copies of itself.

Examples:
    >>> import stim
    >>> c = stim.Circuit('''
    ...    X 0
    ...    Y 1 2
    ... ''')
    >>> c *= 3
    >>> print(c)
    REPEAT 3 {
        X 0
        Y 1 2
    }

stim.Circuit.__init__(self, stim_program_text: str = '') -> None

Creates a stim.Circuit.

Args:
    stim_program_text: Defaults to empty. Describes operations to append into the circuit.

Examples:
    >>> import stim
    >>> empty = stim.Circuit()
    >>> not_empty = stim.Circuit('''
    ...    X 0
    ...    CNOT 0 1
    ...    M 1
    ... ''')

stim.Circuit.__mul__(self, repetitions: int) -> stim.Circuit

Creates a circuit by repeating a circuit multiple times.

Examples:
    >>> import stim
    >>> c = stim.Circuit('''
    ...    X 0
    ...    Y 1 2
    ... ''')
    >>> print(c * 3)
    REPEAT 3 {
        X 0
        Y 1 2
    }

stim.Circuit.__ne__(self, arg0: stim.Circuit) -> bool

Determines if two circuits have non-identical contents.

stim.Circuit.__rmul__(self, repetitions: int) -> stim.Circuit

Creates a circuit by repeating a circuit multiple times.

Examples:
    >>> import stim
    >>> c = stim.Circuit('''
    ...    X 0
    ...    Y 1 2
    ... ''')
    >>> print(3 * c)
    REPEAT 3 {
        X 0
        Y 1 2
    }

stim.Circuit.append_from_stim_program_text(self, stim_program_text: str) -> None

Appends operations described by a STIM format program into the circuit.

Examples:
    >>> import stim
    >>> c = stim.Circuit()
    >>> c.append_from_stim_program_text('''
    ...    H 0  # comment
    ...    CNOT 0 2
    ...
    ...    M 2
    ...    CNOT rec[-1] 1
    ... ''')
    >>> print(c)
    H 0
    CX 0 2
    M 2
    CX rec[-1] 1

Args:
    text: The STIM program text containing the circuit operations to append.

stim.Circuit.append_operation(self, name: str, targets: List[int], arg: float = 0.0) -> None

Appends an operation into the circuit.

Examples:
    >>> import stim
    >>> c = stim.Circuit()
    >>> c.append_operation("X", [0])
    >>> c.append_operation("H", [0, 1])
    >>> c.append_operation("M", [0, stim.target_inv(1)])
    >>> c.append_operation("CNOT", [stim.target_rec(-1), 0])
    >>> c.append_operation("X_ERROR", [0], 0.125)
    >>> c.append_operation("CORRELATED_ERROR", [stim.target_x(0), stim.target_y(2)], 0.25)
    >>> print(c)
    X 0
    H 0 1
    M 0 !1
    CX rec[-1] 0
    X_ERROR(0.125) 0
    E(0.25) X0 Y2

Args:
    name: The name of the operation's gate (e.g. "H" or "M" or "CNOT").
    targets: The gate targets. Gates implicitly broadcast over their targets.
    arg: A modifier for the gate, e.g. the probability of an error. Defaults to 0.

stim.Circuit.clear(self) -> None

Clears the contents of the circuit.

Examples:
    >>> import stim
    >>> c = stim.Circuit('''
    ...    X 0
    ...    Y 1 2
    ... ''')
    >>> c.clear()
    >>> c
    stim.Circuit()

stim.Circuit.compile_detector_sampler(self) -> CompiledDetectorSampler

Returns a CompiledDetectorSampler, which can quickly batch sample detection events, for the circuit.

Examples:
    >>> import stim
    >>> c = stim.Circuit('''
    ...    H 0
    ...    CNOT 0 1
    ...    M 0 1
    ...    DETECTOR rec[-1] rec[-2]
    ... ''')
    >>> s = c.compile_detector_sampler()
    >>> s.sample(shots=1)
    array([[0]], dtype=uint8)

stim.Circuit.compile_sampler(self) -> CompiledMeasurementSampler

Returns a CompiledMeasurementSampler, which can quickly batch sample measurements, for the circuit.

Examples:
    >>> import stim
    >>> c = stim.Circuit('''
    ...    X 2
    ...    M 0 1 2
    ... ''')
    >>> s = c.compile_sampler()
    >>> s.sample(shots=1)
    array([[0, 0, 1]], dtype=uint8)

stim.Circuit.copy(self) -> stim.Circuit

Returns a copy of the circuit. An independent circuit with the same contents.

Examples:
    >>> import stim

    >>> c1 = stim.Circuit("H 0")
    >>> c2 = c1.copy()
    >>> c2 is c1
    False
    >>> c2 == c1
    True

stim.Circuit.flattened_operations(self) -> list

Flattens the circuit's operations into a list.

The operations within repeat blocks are actually repeated in the output.

Returns:
    A List[Tuple[name, targets, arg]] of the operations in the circuit.
        name: A string with the gate's name.
        targets: A list of things acted on by the gate. Each thing can be:
            int: The index of a qubit.
            Tuple["inv", int]: The index of a qubit to measure with an inverted result.
            Tuple["rec", int]: A measurement record target like `rec[-1]`.
            Tuple["X", int]: A Pauli X operation to apply during a correlated error.
            Tuple["Y", int]: A Pauli Y operation to apply during a correlated error.
            Tuple["Z", int]: A Pauli Z operation to apply during a correlated error.
        arg: The gate's numeric argument. For most gates this is just 0. For noisy
            gates this is the probability of the noise being applied.

Examples:
    >>> import stim
    >>> stim.Circuit('''
    ...    H 0
    ...    X_ERROR(0.125) 1
    ...    M 0 !1
    ... ''').flattened_operations()
    [('H', [0], 0.0), ('X_ERROR', [1], 0.125), ('M', [0, ('inv', 1)], 0.0)]

    >>> stim.Circuit('''
    ...    REPEAT 2 {
    ...        H 6
    ...    }
    ... ''').flattened_operations()
    [('H', [6], 0.0), ('H', [6], 0.0)]

stim.Circuit.num_measurements

Counts the number of measurement bits produced when sampling from the circuit.

Examples:
    >>> import stim
    >>> c = stim.Circuit('''
    ...    M 0
    ...    M 0 1
    ... ''')
    >>> c.num_measurements
    3

stim.Circuit.num_qubits

Counts the number of qubits used when simulating the circuit.

Examples:
    >>> import stim
    >>> c = stim.Circuit('''
    ...    M 0
    ...    M 0 1
    ... ''')
    >>> c.num_qubits
    2
    >>> c.append_from_stim_program_text('''
    ...    X 100
    ... ''')
    >>> c.num_qubits
    101

stim.CompiledDetectorSampler.sample(self, shots: int, *, prepend_observables: bool = False, append_observables: bool = False) -> numpy.ndarray[numpy.uint8]

Returns a numpy array containing a batch of detector samples from the circuit.

The circuit must define the detectors using DETECTOR instructions. Observables defined by OBSERVABLE_INCLUDE
instructions can also be included in the results as honorary detectors.

Args:
    shots: The number of times to sample every detector in the circuit.
    prepend_observables: Defaults to false. When set, observables are included with the detectors and are
        placed at the start of the results.
    append_observables: Defaults to false. When set, observables are included with the detectors and are
        placed at the end of the results.

Returns:
    A numpy array with `dtype=uint8` and `shape=(shots, n)` where
    `n = num_detectors + num_observables*(append_observables + prepend_observables)`.
    The bit for detection event `m` in shot `s` is at `result[s, m]`.

stim.CompiledDetectorSampler.sample_bit_packed(self, shots: int, *, prepend_observables: bool = False, append_observables: bool = False) -> numpy.ndarray[numpy.uint8]

Returns a numpy array containing bit packed batch of detector samples from the circuit.

The circuit must define the detectors using DETECTOR instructions. Observables defined by OBSERVABLE_INCLUDE
instructions can also be included in the results as honorary detectors.

Args:
    shots: The number of times to sample every detector in the circuit.
    prepend_observables: Defaults to false. When set, observables are included with the detectors and are
        placed at the start of the results.
    append_observables: Defaults to false. When set, observables are included with the detectors and are
        placed at the end of the results.

Returns:
    A numpy array with `dtype=uint8` and `shape=(shots, n)` where
    `n = num_detectors + num_observables*(append_observables + prepend_observables)`.
    The bit for detection event `m` in shot `s` is at `result[s, (m // 8)] & 2**(m % 8)`.

stim.CompiledMeasurementSampler.__repr__(self) -> str

Returns an eval-able text description.

stim.CompiledMeasurementSampler.sample(self, shots: int) -> numpy.ndarray[numpy.uint8]

Returns a numpy array containing a batch of measurement samples from the circuit.

Examples:
    >>> import stim
    >>> c = stim.Circuit('''
    ...    X 0   2 3
    ...    M 0 1 2 3
    ... ''')
    >>> s = c.compile_sampler()
    >>> s.sample(shots=1)
    array([[1, 0, 1, 1]], dtype=uint8)

Args:
    shots: The number of times to sample every measurement in the circuit.

Returns:
    A numpy array with `dtype=uint8` and `shape=(shots, num_measurements)`.
    The bit for measurement `m` in shot `s` is at `result[s, m]`.

stim.CompiledMeasurementSampler.sample_bit_packed(self, shots: int) -> numpy.ndarray[numpy.uint8]

Returns a numpy array containing a bit packed batch of measurement samples from the circuit.

Examples:
    >>> import stim
    >>> c = stim.Circuit('''
    ...    X 0 1 2 3 4 5 6 7     10
    ...    M 0 1 2 3 4 5 6 7 8 9 10
    ... ''')
    >>> s = c.compile_sampler()
    >>> s.sample_bit_packed(shots=1)
    array([[255,   4]], dtype=uint8)

Args:
    shots: The number of times to sample every measurement in the circuit.

Returns:
    A numpy array with `dtype=uint8` and `shape=(shots, (num_measurements + 7) // 8)`.
    The bit for measurement `m` in shot `s` is at `result[s, (m // 8)] & 2**(m % 8)`.

stim.PauliString.__add__(self, rhs: stim.PauliString) -> stim.PauliString

Returns the tensor product of two Pauli strings.

Concatenates the Pauli strings and multiplies their signs.

Args:
    rhs: A second stim.PauliString.

Examples:
    >>> import stim

    >>> stim.PauliString("X") + stim.PauliString("YZ")
    stim.PauliString("+XYZ")

    >>> stim.PauliString("iX") + stim.PauliString("-X")
    stim.PauliString("-iXX")

Returns:
    The tensor product.

stim.PauliString.__eq__(self, arg0: stim.PauliString) -> bool

Determines if two Pauli strings have identical contents.

stim.PauliString.__getitem__(*args, **kwargs)

Overloaded function.

1. __getitem__(self: stim.PauliString, index: int) -> int

Returns an individual Pauli or Pauli string slice from the pauli string.

Individual Paulis are returned as an int using the encoding 0=I, 1=X, 2=Y, 3=Z.
Slices are returned as a stim.PauliString (always with positive sign).

Examples:
    >>> import stim
    >>> p = stim.PauliString("_XYZ")
    >>> p[2]
    2
    >>> p[-1]
    3
    >>> p[:2]
    stim.PauliString("+_X")
    >>> p[::-1]
    stim.PauliString("+ZYX_")

Args:
    index: The index of the pauli to return or slice of paulis to return.

Returns:
    0: Identity.
    1: Pauli X.
    2: Pauli Y.
    3: Pauli Z.


2. __getitem__(self: stim.PauliString, slice: slice) -> stim.PauliString

Returns an individual Pauli or Pauli string slice from the pauli string.

Individual Paulis are returned as an int using the encoding 0=I, 1=X, 2=Y, 3=Z.
Slices are returned as a stim.PauliString (always with positive sign).

Examples:
    >>> import stim
    >>> p = stim.PauliString("_XYZ")
    >>> p[2]
    2
    >>> p[-1]
    3
    >>> p[:2]
    stim.PauliString("+_X")
    >>> p[::-1]
    stim.PauliString("+ZYX_")

Args:
    index: The index of the pauli to return or slice of paulis to return.

Returns:
    0: Identity.
    1: Pauli X.
    2: Pauli Y.
    3: Pauli Z.

stim.PauliString.__iadd__(self, rhs: stim.PauliString) -> stim.PauliString

Performs an inplace tensor product.

Concatenates the given Pauli string onto the receiving string and multiplies their signs.

Args:
    rhs: A second stim.PauliString.

Examples:
    >>> import stim

    >>> p = stim.PauliString("iX")
    >>> alias = p
    >>> p += stim.PauliString("-YY")
    >>> p
    stim.PauliString("-iXYY")
    >>> alias is p
    True

Returns:
    The mutated pauli string.

stim.PauliString.__imul__(self, rhs: object) -> stim.PauliString

Inplace right-multiplies the Pauli string by another Pauli string, a complex unit, or a tensor power.

Args:
    rhs: The right hand side of the multiplication. This can be:
        - A stim.PauliString to right-multiply term-by-term into the paulis of the pauli string.
        - A complex unit (1, -1, 1j, -1j) to multiply into the sign of the pauli string.
        - A non-negative integer indicating the tensor power to raise the pauli string to (how many times to repeat it).

Examples:
    >>> import stim

    >>> p = stim.PauliString("X")
    >>> p *= 1j
    >>> p
    stim.PauliString("+iX")

    >>> p = stim.PauliString("iXY_")
    >>> p *= 3
    >>> p
    stim.PauliString("-iXY_XY_XY_")

    >>> p = stim.PauliString("X")
    >>> alias = p
    >>> p *= stim.PauliString("Y")
    >>> alias
    stim.PauliString("+iZ")

    >>> p = stim.PauliString("X")
    >>> p *= stim.PauliString("_YY")
    >>> p
    stim.PauliString("+XYY")

Returns:
    The mutated Pauli string.

Raises:
    ValueError: The Pauli strings have different lengths.

stim.PauliString.__init__(*args, **kwargs)

Overloaded function.

1. __init__(self: stim.PauliString, num_qubits: int) -> None

Creates an identity Pauli string over the given number of qubits.

Examples:
    >>> import stim
    >>> p = stim.PauliString(5)
    >>> print(p)
    +_____

Args:
    num_qubits: The number of qubits the Pauli string acts on.


2. __init__(self: stim.PauliString, text: str) -> None

Creates a stim.PauliString from a text string.

The string can optionally start with a sign ('+', '-', 'i', '+i', or '-i').
The rest of the string should be characters from '_IXYZ' where
'_' and 'I' mean identity, 'X' means Pauli X, 'Y' means Pauli Y, and 'Z' means Pauli Z.

Examples:
    >>> import stim
    >>> print(stim.PauliString("YZ"))
    +YZ
    >>> print(stim.PauliString("+IXYZ"))
    +_XYZ
    >>> print(stim.PauliString("-___X_"))
    -___X_
    >>> print(stim.PauliString("iX"))
    +iX

Args:
    text: A text description of the Pauli string's contents, such as "+XXX" or "-_YX".


3. __init__(self: stim.PauliString, copy: stim.PauliString) -> None

Creates a copy of a stim.PauliString.

Examples:
    >>> import stim
    >>> a = stim.PauliString("YZ")
    >>> b = stim.PauliString(a)
    >>> b is a
    False
    >>> b == a
    True

Args:
    copy: The pauli string to make a copy of.


4. __init__(self: stim.PauliString, pauli_indices: List[int]) -> None

Creates a stim.PauliString from a list of integer pauli indices.

The indexing scheme that is used is:
    0 -> I
    1 -> X
    2 -> Y
    3 -> Z

Examples:
    >>> import stim
    >>> stim.PauliString([0, 1, 2, 3, 0, 3])
    stim.PauliString("+_XYZ_Z")

Args:
    pauli_indices: A sequence of integers from 0 to 3 (inclusive) indicating paulis.

stim.PauliString.__len__(self) -> int

Returns the length the pauli string; the number of qubits it operates on.

stim.PauliString.__mul__(self, rhs: object) -> stim.PauliString

Right-multiplies the Pauli string by another Pauli string, a complex unit, or a tensor power.

Args:
    rhs: The right hand side of the multiplication. This can be:
        - A stim.PauliString to right-multiply term-by-term with the paulis of the pauli string.
        - A complex unit (1, -1, 1j, -1j) to multiply with the sign of the pauli string.
        - A non-negative integer indicating the tensor power to raise the pauli string to (how many times to repeat it).

Examples:
    >>> import stim

    >>> stim.PauliString("X") * 1
    stim.PauliString("+X")
    >>> stim.PauliString("X") * -1
    stim.PauliString("-X")
    >>> stim.PauliString("X") * 1j
    stim.PauliString("+iX")

    >>> stim.PauliString("X") * 2
    stim.PauliString("+XX")
    >>> stim.PauliString("-X") * 2
    stim.PauliString("+XX")
    >>> stim.PauliString("iX") * 2
    stim.PauliString("-XX")
    >>> stim.PauliString("X") * 3
    stim.PauliString("+XXX")
    >>> stim.PauliString("iX") * 3
    stim.PauliString("-iXXX")

    >>> stim.PauliString("X") * stim.PauliString("Y")
    stim.PauliString("+iZ")
    >>> stim.PauliString("X") * stim.PauliString("XX_")
    stim.PauliString("+_X_")
    >>> stim.PauliString("XXXX") * stim.PauliString("_XYZ")
    stim.PauliString("+X_ZY")

Returns:
    The product or tensor power.

Raises:
    TypeError: The right hand side isn't a stim.PauliString, a non-negative integer, or a complex unit (1, -1, 1j, or -1j).

stim.PauliString.__ne__(self, arg0: stim.PauliString) -> bool

Determines if two Pauli strings have non-identical contents.

stim.PauliString.__neg__(self) -> stim.PauliString

Returns the negation of the pauli string.

Examples:
    >>> import stim
    >>> -stim.PauliString("X")
    stim.PauliString("-X")
    >>> -stim.PauliString("-Y")
    stim.PauliString("+Y")
    >>> -stim.PauliString("iZZZ")
    stim.PauliString("-iZZZ")

stim.PauliString.__pos__(self) -> stim.PauliString

Returns a pauli string with the same contents.

Examples:
    >>> import stim
    >>> +stim.PauliString("+X")
    stim.PauliString("+X")
    >>> +stim.PauliString("-YY")
    stim.PauliString("-YY")
    >>> +stim.PauliString("iZZZ")
    stim.PauliString("+iZZZ")

stim.PauliString.__repr__(self) -> str

Returns an eval-able text description.

stim.PauliString.__rmul__(self, lhs: object) -> stim.PauliString

Left-multiplies the Pauli string by another Pauli string, a complex unit, or a tensor power.

Args:
    rhs: The left hand side of the multiplication. This can be:
        - A stim.PauliString to left-multiply term-by-term into the paulis of the pauli string.
        - A complex unit (1, -1, 1j, -1j) to multiply into the sign of the pauli string.
        - A non-negative integer indicating the tensor power to raise the pauli string to (how many times to repeat it).

Examples:
    >>> import stim

    >>> 1 * stim.PauliString("X")
    stim.PauliString("+X")
    >>> -1 * stim.PauliString("X")
    stim.PauliString("-X")
    >>> 1j * stim.PauliString("X")
    stim.PauliString("+iX")

    >>> 2 * stim.PauliString("X")
    stim.PauliString("+XX")
    >>> 2 * stim.PauliString("-X")
    stim.PauliString("+XX")
    >>> 2 * stim.PauliString("iX")
    stim.PauliString("-XX")
    >>> 3 * stim.PauliString("X")
    stim.PauliString("+XXX")
    >>> 3 * stim.PauliString("iX")
    stim.PauliString("-iXXX")

    >>> stim.PauliString("X") * stim.PauliString("Y")
    stim.PauliString("+iZ")
    >>> stim.PauliString("X") * stim.PauliString("XX_")
    stim.PauliString("+_X_")
    >>> stim.PauliString("XXXX") * stim.PauliString("_XYZ")
    stim.PauliString("+X_ZY")

Returns:
    The product.

Raises:
    ValueError: The scalar phase factor isn't 1, -1, 1j, or -1j.

stim.PauliString.__str__(self) -> str

Returns a text description.

stim.PauliString.commutes(self, other: stim.PauliString) -> bool

Determines if two Pauli strings commute or not.

Two Pauli strings commute if they have an even number of matched
non-equal non-identity Pauli terms. Otherwise they anticommute.

Args:
    other: The other Pauli string.

Examples:
    >>> import stim
    >>> xx = stim.PauliString("XX")
    >>> xx.commutes(stim.PauliString("X_"))
    True
    >>> xx.commutes(stim.PauliString("XX"))
    True
    >>> xx.commutes(stim.PauliString("XY"))
    False
    >>> xx.commutes(stim.PauliString("XZ"))
    False
    >>> xx.commutes(stim.PauliString("ZZ"))
    True
    >>> xx.commutes(stim.PauliString("X_Y__"))
    True
    >>> xx.commutes(stim.PauliString(""))
    True

Returns:
    True if the Pauli strings commute, False if they anti-commute.

stim.PauliString.copy(self) -> stim.PauliString

Returns a copy of the pauli string. An independent pauli string with the same contents.

Examples:
    >>> import stim
    >>> p1 = stim.PauliString.random(2)
    >>> p2 = p1.copy()
    >>> p2 is p1
    False
    >>> p2 == p1
    True

stim.PauliString.extended_product(self, other: stim.PauliString) -> Tuple[complex, stim.PauliString]

[DEPRECATED] Use multiplication (__mul__ or *) instead.

stim.PauliString.random(num_qubits: int, *, allow_imaginary: bool = False) -> stim.PauliString

Samples a uniformly random Hermitian Pauli string over the given number of qubits.

Args:
    num_qubits: The number of qubits the Pauli string should act on.
    allow_imaginary: Defaults to False. If True, the sign of the result may be 1j or -1j
        in addition to +1 or -1. In other words, setting this to True allows the result
        to be non-Hermitian.

Examples:
    >>> import stim
    >>> p = stim.PauliString.random(5)
    >>> len(p)
    5
    >>> p.sign in [-1, +1]
    True

    >>> p2 = stim.PauliString.random(3, allow_imaginary=True)
    >>> len(p2)
    3
    >>> p2.sign in [-1, +1, 1j, -1j]
    True

Returns:
    The sampled Pauli string.

stim.PauliString.sign

The sign of the Pauli string. Can be +1, -1, 1j, or -1j.

Examples:
    >>> import stim
    >>> stim.PauliString("X").sign
    (1+0j)
    >>> stim.PauliString("-X").sign
    (-1+0j)
    >>> stim.PauliString("iX").sign
    1j
    >>> stim.PauliString("-iX").sign
    (-0-1j)

stim.Tableau.__add__(self, rhs: stim.Tableau) -> stim.Tableau

Returns the direct sum (diagonal concatenation) of two Tableaus.

Args:
    rhs: A second stim.Tableau.

Examples:
    >>> import stim

    >>> s = stim.Tableau.from_named_gate("S")
    >>> cz = stim.Tableau.from_named_gate("CZ")
    >>> print(s + cz)
    +-xz-xz-xz-
    | ++ ++ ++
    | YZ __ __
    | __ XZ Z_
    | __ Z_ XZ

Returns:
    The direct sum.

stim.Tableau.__call__(self, pauli_string: stim.PauliString) -> stim.PauliString

Returns the result of conjugating the given PauliString by the Tableau's Clifford operation.

Args:
    pauli_string: The pauli string to conjugate.

Returns:
    The new conjugated pauli string.

Examples:
    >>> import stim
    >>> t = stim.Tableau.from_named_gate("CNOT")
    >>> p = stim.PauliString("XX")
    >>> result = t(p)
    >>> print(result)
    +X_

References:
    "Hadamard-free circuits expose the structure of the Clifford group"
    Sergey Bravyi, Dmitri Maslov
    https://arxiv.org/abs/2003.09412

stim.Tableau.__eq__(self, arg0: stim.Tableau) -> bool

Determines if two tableaus have identical contents.

stim.Tableau.__iadd__(self, rhs: stim.Tableau) -> stim.Tableau

Performs an inplace direct sum (diagonal concatenation).

Args:
    rhs: A second stim.Tableau.

Examples:
    >>> import stim

    >>> s = stim.Tableau.from_named_gate("S")
    >>> cz = stim.Tableau.from_named_gate("CZ")
    >>> alias = s
    >>> s += cz
    >>> alias is s
    True
    >>> print(s)
    +-xz-xz-xz-
    | ++ ++ ++
    | YZ __ __
    | __ XZ Z_
    | __ Z_ XZ

Returns:
    The mutated tableau.

stim.Tableau.__init__(self, num_qubits: int) -> None

Creates an identity tableau over the given number of qubits.

Examples:
    >>> import stim
    >>> t = stim.Tableau(3)
    >>> print(t)
    +-xz-xz-xz-
    | ++ ++ ++
    | XZ __ __
    | __ XZ __
    | __ __ XZ

Args:
    num_qubits: The number of qubits the tableau's operation acts on.

stim.Tableau.__len__(self) -> int

Returns the number of qubits operated on by the tableau.

stim.Tableau.__mul__(self, rhs: stim.Tableau) -> stim.Tableau

Returns the product of two tableaus.

If the tableau T1 represents the Clifford operation with unitary C1,
and the tableau T2 represents the Clifford operation with unitary C2,
then the tableau T1*T2 represents the Clifford operation with unitary C1*C2.

Args:
    rhs: The tableau  on the right hand side of the multiplication.

Examples:
    >>> import stim
    >>> t1 = stim.Tableau.random(4)
    >>> t2 = stim.Tableau.random(4)
    >>> t3 = t2 * t1
    >>> p = stim.PauliString.random(4)
    >>> t3(p) == t2(t1(p))
    True

stim.Tableau.__ne__(self, arg0: stim.Tableau) -> bool

Determines if two tableaus have non-identical contents.

stim.Tableau.__pow__(self, exponent: int) -> stim.Tableau

Raises the tableau to an integer power.

Large powers are reached efficiently using repeated squaring.
Negative powers are reached by inverting the tableau.

Args:
    exponent: The power to raise to. Can be negative, zero, or positive.

Examples:
    >>> import stim
    >>> s = stim.Tableau.from_named_gate("S")
    >>> s**0 == stim.Tableau(1)
    True
    >>> s**1 == s
    True
    >>> s**2 == stim.Tableau.from_named_gate("Z")
    True
    >>> s**-1 == s**3 == stim.Tableau.from_named_gate("S_DAG")
    True
    >>> s**5 == s
    True
    >>> s**(400000000 + 1) == s
    True
    >>> s**(-400000000 + 1) == s
    True

stim.Tableau.__repr__(self) -> str

Returns an eval-able text description.

stim.Tableau.__str__(self) -> str

Returns a text description.

stim.Tableau.append(self, gate: stim.Tableau, targets: List[int]) -> None

Appends an operation's effect into this tableau, mutating this tableau.

Time cost is O(n*m*m) where n=len(self) and m=len(gate).

Args:
    gate: The tableau of the operation being appended into this tableau.
    targets: The qubits being targeted by the gate.

Examples:
    >>> import stim
    >>> cnot = stim.Tableau.from_named_gate("CNOT")
    >>> t = stim.Tableau(2)
    >>> t.append(cnot, [0, 1])
    >>> t.append(cnot, [1, 0])
    >>> t.append(cnot, [0, 1])
    >>> t == stim.Tableau.from_named_gate("SWAP")
    True

stim.Tableau.copy(self) -> stim.Tableau

Returns a copy of the tableau. An independent tableau with the same contents.

Examples:
    >>> import stim
    >>> t1 = stim.Tableau.random(2)
    >>> t2 = t1.copy()
    >>> t2 is t1
    False
    >>> t2 == t1
    True

stim.Tableau.from_conjugated_generators(*, xs: List[stim.PauliString], zs: List[stim.PauliString]) -> stim.Tableau

Creates a tableau from the given outputs for each generator.

Verifies that the tableau is well formed.

Args:
    xs: A List[stim.PauliString] with the results of conjugating X0, X1, etc.
    zs: A List[stim.PauliString] with the results of conjugating Z0, Z1, etc.

Returns:
    The created tableau.

Raises:
    ValueError: The given outputs are malformed. Their lengths are inconsistent,
        or they don't satisfy the required commutation relationships.

Examples:
    >>> import stim
    >>> identity3 = stim.Tableau.from_conjugated_generators(
    ...     xs=[
    ...         stim.PauliString("X__"),
    ...         stim.PauliString("_X_"),
    ...         stim.PauliString("__X"),
    ...     ],
    ...     zs=[
    ...         stim.PauliString("Z__"),
    ...         stim.PauliString("_Z_"),
    ...         stim.PauliString("__Z"),
    ...     ],
    ... )
    >>> identity3 == stim.Tableau(3)
    True

stim.Tableau.from_named_gate(name: str) -> stim.Tableau

Returns the tableau of a named Clifford gate.

Args:
    name: The name of the Clifford gate.

Returns:
    The gate's tableau.

Examples:
    >>> import stim
    >>> print(stim.Tableau.from_named_gate("H"))
    +-xz-
    | ++
    | ZX
    >>> print(stim.Tableau.from_named_gate("CNOT"))
    +-xz-xz-
    | ++ ++
    | XZ _Z
    | X_ XZ
    >>> print(stim.Tableau.from_named_gate("S"))
    +-xz-
    | ++
    | YZ

stim.Tableau.prepend(self, gate: stim.Tableau, targets: List[int]) -> None

Prepends an operation's effect into this tableau, mutating this tableau.

Time cost is O(n*m*m) where n=len(self) and m=len(gate).

Args:
    gate: The tableau of the operation being prepended into this tableau.
    targets: The qubits being targeted by the gate.

Examples:
    >>> import stim
    >>> h = stim.Tableau.from_named_gate("H")
    >>> cnot = stim.Tableau.from_named_gate("CNOT")
    >>> t = stim.Tableau.from_named_gate("H")
    >>> t.prepend(stim.Tableau.from_named_gate("X"), [0])
    >>> t == stim.Tableau.from_named_gate("SQRT_Y_DAG")
    True

stim.Tableau.random(num_qubits: int) -> stim.Tableau

Samples a uniformly random Clifford operation over the given number of qubits and returns its tableau.

Args:
    num_qubits: The number of qubits the tableau should act on.

Returns:
    The sampled tableau.

Examples:
    >>> import stim
    >>> t = stim.Tableau.random(42)

References:
    "Hadamard-free circuits expose the structure of the Clifford group"
    Sergey Bravyi, Dmitri Maslov
    https://arxiv.org/abs/2003.09412

stim.Tableau.then(self, second: stim.Tableau) -> stim.Tableau

Returns the result of composing two tableaus.

If the tableau T1 represents the Clifford operation with unitary C1,
and the tableau T2 represents the Clifford operation with unitary C2,
then the tableau T1.then(T2) represents the Clifford operation with unitary C2*C1.

Args:
    second: The result is equivalent to applying the second tableau after
        the receiving tableau.

Examples:
    >>> import stim
    >>> t1 = stim.Tableau.random(4)
    >>> t2 = stim.Tableau.random(4)
    >>> t3 = t1.then(t2)
    >>> p = stim.PauliString.random(4)
    >>> t3(p) == t2(t1(p))
    True

stim.Tableau.x_output(self, target: int) -> stim.PauliString

Returns the result of conjugating a Pauli X by the tableau's Clifford operation.

Args:
    target: The qubit targeted by the Pauli X operation.

Examples:
    >>> import stim
    >>> h = stim.Tableau.from_named_gate("H")
    >>> h.x_output(0)
    stim.PauliString("+Z")

    >>> cnot = stim.Tableau.from_named_gate("CNOT")
    >>> cnot.x_output(0)
    stim.PauliString("+XX")
    >>> cnot.x_output(1)
    stim.PauliString("+_X")

stim.Tableau.y_output(self, target: int) -> stim.PauliString

Returns the result of conjugating a Pauli Y by the tableau's Clifford operation.

Args:
    target: The qubit targeted by the Pauli Y operation.

Examples:
    >>> import stim
    >>> h = stim.Tableau.from_named_gate("H")
    >>> h.y_output(0)
    stim.PauliString("-Y")

    >>> cnot = stim.Tableau.from_named_gate("CNOT")
    >>> cnot.y_output(0)
    stim.PauliString("+YX")
    >>> cnot.y_output(1)
    stim.PauliString("+ZY")

stim.Tableau.z_output(self, target: int) -> stim.PauliString

Returns the result of conjugating a Pauli Z by the tableau's Clifford operation.

Args:
    target: The qubit targeted by the Pauli Z operation.

Examples:
    >>> import stim
    >>> h = stim.Tableau.from_named_gate("H")
    >>> h.z_output(0)
    stim.PauliString("+X")

    >>> cnot = stim.Tableau.from_named_gate("CNOT")
    >>> cnot.z_output(0)
    stim.PauliString("+Z_")
    >>> cnot.z_output(1)
    stim.PauliString("+ZZ")

stim.TableauSimulator.canonical_stabilizers(self) -> List[stim.PauliString]

Returns a list of the stabilizers of the simulator's current state in a standard form.

Two simulators have the same canonical stabilizers if and only if their current quantum state is equal
(and tracking the same number of qubits).

The canonical form is computed as follows:

    1. Get a list of stabilizers using the `z_output`s of `simulator.current_inverse_tableau()**-1`.
    2. Perform Gaussian elimination on each generator g (ordered X0, Z0, X1, Z1, X2, Z2, etc).
        2a) Pick any stabilizer that uses the generator g. If there are none, go to the next g.
        2b) Multiply that stabilizer into all other stabilizers that use the generator g.
        2c) Swap that stabilizer with the stabilizer at position `next_output` then increment `next_output`.

Returns:
    A List[stim.PauliString] of the simulator's state's stabilizers.

Examples:
    >>> import stim
    >>> s = stim.TableauSimulator()
    >>> s.h(0)
    >>> s.cnot(0, 1)
    >>> s.x(2)
    >>> s.canonical_stabilizers()
    [stim.PauliString("+XX_"), stim.PauliString("+ZZ_"), stim.PauliString("-__Z")]

    >>> # Scramble the stabilizers then check that the canonical form is unchanged.
    >>> s.set_inverse_tableau(s.current_inverse_tableau()**-1)
    >>> s.cnot(0, 1)
    >>> s.cz(0, 2)
    >>> s.s(0, 2)
    >>> s.cy(2, 1)
    >>> s.set_inverse_tableau(s.current_inverse_tableau()**-1)
    >>> s.canonical_stabilizers()
    [stim.PauliString("+XX_"), stim.PauliString("+ZZ_"), stim.PauliString("-__Z")]

stim.TableauSimulator.cnot(self, *args) -> None

Applies a controlled X gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.copy(self) -> stim.TableauSimulator

Returns a copy of the simulator. A simulator with the same internal state.

Examples:
    >>> import stim

    >>> s1 = stim.TableauSimulator()
    >>> s1.set_inverse_tableau(stim.Tableau.random(1))
    >>> s2 = s1.copy()
    >>> s2 is s1
    False
    >>> s2.current_inverse_tableau() == s1.current_inverse_tableau()
    True

    >>> s = stim.TableauSimulator()
    >>> def brute_force_post_select(qubit, desired_result):
    ...     global s
    ...     while True:
    ...         copy = s.copy()
    ...         if copy.measure(qubit) == desired_result:
    ...             s = copy
    ...             break
    >>> s.h(0)
    >>> brute_force_post_select(qubit=0, desired_result=True)
    >>> s.measure(0)
    True

stim.TableauSimulator.current_inverse_tableau(self) -> Tableau

Returns a copy of the internal state of the simulator as a stim.Tableau.

Returns:
    A stim.Tableau copy of the simulator's state.

Examples:
    >>> import stim
    >>> s = stim.TableauSimulator()
    >>> s.h(0)
    >>> s.current_inverse_tableau()
    stim.Tableau.from_conjugated_generators(
        xs=[
            stim.PauliString("+Z"),
        ],
        zs=[
            stim.PauliString("+X"),
        ],
    )
    >>> s.cnot(0, 1)
    >>> s.current_inverse_tableau()
    stim.Tableau.from_conjugated_generators(
        xs=[
            stim.PauliString("+ZX"),
            stim.PauliString("+_X"),
        ],
        zs=[
            stim.PauliString("+X_"),
            stim.PauliString("+XZ"),
        ],
    )

stim.TableauSimulator.current_measurement_record(self) -> List[bool]

Returns a copy of the record of all measurements performed by the simulator.

Examples:
    >>> import stim
    >>> s = stim.TableauSimulator()
    >>> s.current_measurement_record()
    []
    >>> s.measure(0)
    False
    >>> s.x(0)
    >>> s.measure(0)
    True
    >>> s.current_measurement_record()
    [False, True]
    >>> s.do(stim.Circuit("M 0"))
    >>> s.current_measurement_record()
    [False, True, True]

Returns:
    A list of booleans containing the result of every measurement performed by the simulator so far.

stim.TableauSimulator.cy(self, *args) -> None

Applies a controlled Y gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.cz(self, *args) -> None

Applies a controlled Z gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.do(*args, **kwargs)

Overloaded function.

1. do(self: stim.TableauSimulator, circuit: stim.Circuit) -> None

Applies all the operations in the given stim.Circuit to the simulator's state.

Examples:
    >>> import stim
    >>> s = stim.TableauSimulator()
    >>> s.do(stim.Circuit('''
    ...     X 0
    ...     M 0
    ... '''))
    >>> s.current_measurement_record()
    [True]

Args:
    circuit: A stim.Circuit containing operations to apply.


2. do(self: stim.TableauSimulator, pauli_string: stim.PauliString) -> None

Applies all the Pauli operations in the given stim.PauliString to the simulator's state.

The Pauli at offset k is applied to the qubit with index k.

Examples:
    >>> import stim
    >>> s = stim.TableauSimulator()
    >>> s.do(stim.PauliString("IXYZ"))
    >>> s.measure_many(0, 1, 2, 3)
    [False, True, True, False]

Args:
    pauli_string: A stim.PauliString containing Pauli operations to apply.

stim.TableauSimulator.h(self, *args) -> None

Applies a Hadamard gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.

stim.TableauSimulator.h_xy(self, *args) -> None

Applies a variant of the Hadamard gate that swaps the X and Y axes to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.

stim.TableauSimulator.h_yz(self, *args) -> None

Applies a variant of the Hadamard gate that swaps the Y and Z axes to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.

stim.TableauSimulator.iswap(self, *args) -> None

Applies an ISWAP gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.iswap_dag(self, *args) -> None

Applies an ISWAP_DAG gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.measure(self, target: int) -> bool

Measures a single qubit.

Unlike the other methods on TableauSimulator, this one does not broadcast
over multiple targets. This is to avoid returning a list, which would
create a pitfall where typing `if sim.measure(qubit)` would be a bug.

To measure multiple qubits, use `TableauSimulator.measure_many`.

Args:
    target: The index of the qubit to measure.

Returns:
    The measurement result as a bool.

stim.TableauSimulator.measure_kickback(self, target: int) -> tuple

Measures a qubit and returns the result as well as its Pauli kickback (if any).

The "Pauli kickback" of a stabilizer circuit measurement is a set of Pauli operations that
flip the post-measurement system state between the two possible post-measurement states.
For example, consider measuring one of the qubits in the state |00>+|11> in the Z basis.
If the measurement result is False, then the system projects into the state |00>.
If the measurement result is True, then the system projects into the state |11>.
Applying a Pauli X operation to both qubits flips between |00> and |11>.
Therefore the Pauli kickback of the measurement is `stim.PauliString("XX")`.
Note that there are often many possible equivalent Pauli kickbacks. For example,
if in the previous example there was a third qubit in the |0> state, then both
`stim.PauliString("XX_")` and `stim.PauliString("XXZ")` are valid kickbacks.

Measurements with determinist results don't have a Pauli kickback.

Args:
    target: The index of the qubit to measure.

Returns:
    A (result, kickback) tuple.
    The result is a bool containing the measurement's output.
    The kickback is either None (meaning the measurement was deterministic) or a stim.PauliString
    (meaning the measurement was random, and the operations in the Pauli string flip between the
    two possible post-measurement states).

Examples:
    >>> import stim
    >>> s = stim.TableauSimulator()

    >>> s.measure_kickback(0)
    (False, None)

    >>> s.h(0)
    >>> s.measure_kickback(0)[1]
    stim.PauliString("+X")

    >>> def pseudo_post_select(qubit, desired_result):
    ...     m, kick = s.measure_kickback(qubit)
    ...     if m != desired_result:
    ...         if kick is None:
    ...             raise ValueError("Deterministic measurement differed from desired result.")
    ...         s.do(kick)
    >>> s = stim.TableauSimulator()
    >>> s.h(0)
    >>> s.cnot(0, 1)
    >>> s.cnot(0, 2)
    >>> pseudo_post_select(qubit=2, desired_result=True)
    >>> s.measure_many(0, 1, 2)
    [True, True, True]

stim.TableauSimulator.measure_many(self, *args) -> List[bool]

Measures multiple qubits.

Args:
    *targets: The indices of the qubits to measure.

Returns:
    The measurement results as a list of bools.

stim.TableauSimulator.peek_bloch(self, target: int) -> stim.PauliString

Returns the current bloch vector of the qubit, represented as a stim.PauliString.

This is a non-physical operation. It reports information about the qubit without disturbing it.

Args:
    target: The qubit to peek at.

Returns:
    stim.PauliString("I"): The qubit is entangled. Its bloch vector is x=y=z=0.
    stim.PauliString("+Z"): The qubit is in the |0> state. Its bloch vector is z=+1, x=y=0.
    stim.PauliString("-Z"): The qubit is in the |1> state. Its bloch vector is z=-1, x=y=0.
    stim.PauliString("+Y"): The qubit is in the |i> state. Its bloch vector is y=+1, x=z=0.
    stim.PauliString("-Y"): The qubit is in the |-i> state. Its bloch vector is y=-1, x=z=0.
    stim.PauliString("+X"): The qubit is in the |+> state. Its bloch vector is x=+1, y=z=0.
    stim.PauliString("-X"): The qubit is in the |-> state. Its bloch vector is x=-1, y=z=0.

Examples:
    >>> import stim
    >>> s = stim.TableauSimulator()
    >>> s.peek_bloch(0)
    stim.PauliString("+Z")
    >>> s.x(0)
    >>> s.peek_bloch(0)
    stim.PauliString("-Z")
    >>> s.h(0)
    >>> s.peek_bloch(0)
    stim.PauliString("-X")
    >>> s.sqrt_x(1)
    >>> s.peek_bloch(1)
    stim.PauliString("-Y")
    >>> s.cz(0, 1)
    >>> s.peek_bloch(0)
    stim.PauliString("+_")

stim.TableauSimulator.reset(self, *args) -> None

Resets qubits to zero (e.g. by swapping them for zero'd qubit from the environment).

Args:
    *targets: The indices of the qubits to reset.

stim.TableauSimulator.s(self, *args) -> None

Applies a SQRT_Z gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.

stim.TableauSimulator.s_dag(self, *args) -> None

Applies a SQRT_Z_DAG gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.

stim.TableauSimulator.set_inverse_tableau(self, arg0: Tableau) -> None

Overwrites the simulator's internal state with a copy of the given inverse tableau.

The inverse tableau specifies how Pauli product observables of qubits at the current time transform
into equivalent Pauli product observables at the beginning of time, when all qubits were in the
|0> state. For example, if the Z observable on qubit 5 maps to a product of Z observables at the
start of time then a Z basis measurement on qubit 5 will be deterministic and equal to the sign
of the product. Whereas if it mapped to a product of observables including an X or a Y then the Z
basis measurement would be random.

Any qubits not within the length of the tableau are implicitly in the |0> state.

Args:
    new_inverse_tableau: The tableau to overwrite the internal state with.

Examples:
    >>> import stim
    >>> s = stim.TableauSimulator()
    >>> t = stim.Tableau.random(4)
    >>> s.set_inverse_tableau(t)
    >>> s.current_inverse_tableau() == t
    True

stim.TableauSimulator.set_num_qubits(self, arg0: int) -> None

Forces the simulator's internal state to track exactly the qubits whose indices are in range(new_num_qubits).

Note that untracked qubits are always assumed to be in the |0> state. Therefore, calling this method
will effectively force any qubit whose index is outside range(new_num_qubits) to be reset to |0>.

Note that this method does not prevent future operations from implicitly expanding the size of the
tracked state (e.g. setting the number of qubits to 5 will not prevent a Hadamard from then being
applied to qubit 100, increasing the number of qubits to 101).

Args:
    new_num_qubits: The length of the range of qubits the internal simulator should be tracking.

Examples:
    >>> import stim
    >>> s = stim.TableauSimulator()
    >>> len(s.current_inverse_tableau())
    0

    >>> s.set_num_qubits(5)
    >>> len(s.current_inverse_tableau())
    5

    >>> s.x(0, 1, 2, 3)
    >>> s.set_num_qubits(2)
    >>> s.measure_many(0, 1, 2, 3)
    [True, True, False, False]

stim.TableauSimulator.sqrt_x(self, *args) -> None

Applies a SQRT_X gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.

stim.TableauSimulator.sqrt_x_dag(self, *args) -> None

Applies a SQRT_X_DAG gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.

stim.TableauSimulator.sqrt_y(self, *args) -> None

Applies a SQRT_Y gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.

stim.TableauSimulator.sqrt_y_dag(self, *args) -> None

Applies a SQRT_Y_DAG gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.

stim.TableauSimulator.swap(self, *args) -> None

Applies a swap gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.x(self, *args) -> None

Applies a Pauli X gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.

stim.TableauSimulator.xcx(self, *args) -> None

Applies an X-controlled X gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.xcy(self, *args) -> None

Applies an X-controlled Y gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.xcz(self, *args) -> None

Applies an X-controlled Z gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.y(self, *args) -> None

Applies a Pauli Y gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.

stim.TableauSimulator.ycx(self, *args) -> None

Applies a Y-controlled X gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.ycy(self, *args) -> None

Applies a Y-controlled Y gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.ycz(self, *args) -> None

Applies a Y-controlled Z gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
        Applies the gate to the first two targets, then the next two targets, and so forth.
        There must be an even number of targets.

stim.TableauSimulator.z(self, *args) -> None

Applies a Pauli Z gate to the simulator's state.

Args:
    *targets: The indices of the qubits to target with the gate.
Clone this wiki locally