mqt.qecc.codes.core.pauli

Class for working with representations of Pauli operators.

Attributes

StabilizerTableau

Deprecated alias for PauliTableau; use PauliTableau instead.

Exceptions

InvalidPauliError

Exception raised when an invalid Pauli operator is encountered.

Classes

PauliRowEchelon

The result of a phase-sensitive row reduction of a PauliTableau.

Pauli

Class representing an n-qubit Pauli operator.

PauliTableau

An ordered collection of signed Pauli rows in binary symplectic form.

CheckMatrix

Type alias for CSS check matrices.

Functions

pauli_row_echelon(→ PauliRowEchelon)

Compute a phase-sensitive reduced row echelon form of a PauliTableau.

pauli_rank(→ int)

Compute the rank of the Pauli subgroup generated by a tableau.

pauli_in_reduced_subgroup(→ bool)

Decide subgroup membership against a precomputed pauli_row_echelon() result.

complete_stabilizer_tableau_with_destabilizers(...)

Given a tableau of stabilizers, complete it to a full tableau by adding destabilizers.

is_pauli_string(→ bool)

Check if a string is a valid Pauli string.

Module Contents

class PauliRowEchelon[source]

Bases: NamedTuple

The result of a phase-sensitive row reduction of a PauliTableau.

reduced

The reduced tableau, with dependent rows retained as scalar Paulis.

rank

The Pauli subgroup rank, i.e. log2 of the order of the generated subgroup, including the contribution of the global phases.

n_global_phases

How many global phases the subgroup contains: 1 for {I}, 2 for {I, -I}, 4 for {I, iI, -I, -iI}. This is a count, not a rank.

transform

The binary matrix T with T @ input.symplectic % 2 == reduced.symplectic.

pivot_cols

The pivot column indices. Their number is the symplectic rank, which can be smaller than rank.

pauli_row_echelon(p: PauliTableau) PauliRowEchelon[source]

Compute a phase-sensitive reduced row echelon form of a PauliTableau.

Unlike a plain mod-2 row reduction, this tracks the phase picked up when Pauli rows are combined, so it is the correct reduction to use on a signed tableau.

Parameters:

p – The PauliTableau. It is not modified.

Returns:

A PauliRowEchelon describing the reduction.

pauli_rank(p: PauliTableau) int[source]

Compute the rank of the Pauli subgroup generated by a tableau.

Parameters:

p – The PauliTableau.

Returns:

log2 of the number of elements in the generated Pauli subgroup.

pauli_in_reduced_subgroup(reduced: PauliTableau, n_global_phases: int, pivot_cols: list[int], p: Pauli) bool[source]

Decide subgroup membership against a precomputed pauli_row_echelon() result.

Reducing the candidate against the echelon rows costs O(rows * n), so callers that test many Paulis against the same subgroup should compute the echelon form once and reuse it rather than calling PauliTableau.is_in_subgroup() per query.

Parameters:
Returns:

True if p lies in the subgroup the echelon form describes.

class Pauli(symplectic: SymplecticVector, phase_exponent: int | None = None)[source]

Class representing an n-qubit Pauli operator.

Internally, a Pauli operator is stored as a binary symplectic support (x|z) together with a phase exponent p, representing Q(x,z,p) = i^p X^x Z^z.

classmethod from_pauli_string(p: str) Pauli[source]

Create a new Pauli operator from a Pauli string.

Accepts an optional phase prefix of ‘+’ (default), ‘+i’, ‘-’, or ‘-i’ followed by a sequence of I, X, Y, and Z letters.

classmethod from_stim(p: stim.PauliString) Pauli[source]

Create a new Pauli operator from Stim representation.

classmethod from_symplectic_and_sign(symplectic: SymplecticVector, sign: int) Pauli[source]

Create a Hermitian Pauli operator from its support and a binary sign.

Parameters:
  • symplectic – The binary symplectic support (x|z) of the operator.

  • sign – 0 for a plus sign, 1 for a minus sign, in (-1)^sign i^(x.z) X^x Z^z.

is_hermitian() bool[source]

Check whether this Pauli operator is Hermitian, i.e. p == x.z (mod 2).

sign() int[source]

Return the conventional binary sign r of a Hermitian Pauli, in (-1)^r i^(x.z) X^x Z^z.

Raises:

InvalidPauliError – If this Pauli operator is not Hermitian.

inverse() Pauli[source]

Return the inverse of this Pauli operator.

commute(other: Pauli) bool[source]

Check if this Pauli operator commutes with another Pauli operator.

anticommute(other: Pauli) bool[source]

Check if this Pauli operator anticommutes with another Pauli operator.

as_vector() numpy.typing.NDArray[numpy.int8][source]

Convert the Pauli operator to a vector.

The first 2n entries are the binary symplectic support; the last entry is the phase exponent p.

x_part() numpy.typing.NDArray[numpy.int8][source]

Return the X part of the Pauli operator.

z_part() numpy.typing.NDArray[numpy.int8][source]

Return the Z part of the Pauli operator.

class PauliTableau(tableau: SymplecticMatrix | numpy.typing.NDArray[numpy.int8], phase_exponents: numpy.typing.NDArray[numpy.int8] | None = None)[source]

An ordered collection of signed Pauli rows in binary symplectic form.

Used for stabilizer generators, logical operators, Clifford tableaus, destabilizers, and arbitrary Pauli subgroups.

classmethod from_stim_circuit(circ: stim.Circuit) PauliTableau[source]

Create a PauliTableau from a stim.Circuit.

Parameters:

circ – A stim.Circuit object.

Returns:

A PauliTableau instance.

classmethod from_stim_tableau(stim_tableau: stim.Tableau) PauliTableau[source]

Create a PauliTableau from a stim.Tableau.

Parameters:

stim_tableau – A stim.Tableau object.

Returns:

A PauliTableau instance.

classmethod from_pauli_strings(pauli_strings: Sequence[str]) PauliTableau[source]

Create a new stabilizer tableau from a list of Pauli strings.

classmethod from_paulis(paulis: Sequence[Pauli]) PauliTableau[source]

Create a new stabilizer tableau from a list of Pauli operators.

static phase_from_signs(symplectic_matrix: numpy.typing.NDArray[numpy.int8], signs: numpy.typing.NDArray[numpy.int8]) numpy.typing.NDArray[numpy.int8][source]

Convert per-row binary signs of a symplectic tableau into {0,1,2,3} phase exponents.

Parameters:
  • symplectic_matrix – A r x 2n binary symplectic support matrix.

  • signs – A length-r vector of binary signs (0 for plus, 1 for minus), one per row.

Returns:

A length-r vector of phase exponents p in {0,1,2,3} such that row i equals (-1)^signs[i] i^(x_i.z_i) X^x_i Z^z_i.

classmethod empty(n: int) PauliTableau[source]

Create a new empty stabilizer tableau.

classmethod identity(n: int) PauliTableau[source]

Create a new identity stabilizer tableau.

classmethod from_matrix(matrix: numpy.typing.NDArray[numpy.int8]) PauliTableau[source]

Create a PauliTableau from a symplectic matrix.

Parameters:

matrix – A r x 2n symplectic matrix representing the stabilizer tableau.

Returns:

A PauliTableau instance.

classmethod from_check_matrix(check_matrix: CheckMatrix) PauliTableau[source]

Create a PauliTableau from a CSS check matrix.

Parameters:

check_matrix – A CheckMatrix object representing the CSS check matrix.

Returns:

A PauliTableau instance.

property symplectic: numpy.typing.NDArray[numpy.int8]

The binary symplectic matrix of the tableau, shape (num_rows, 2n).

all_commute(other: PauliTableau) bool[source]

Check if all Pauli operators in this tableau commute with all Pauli operators in another tableau.

multiply_rows(target: int, source: int) None[source]

Left-multiply row target by row source in place, tracking the phase.

Row target becomes P_target * P_source; all other rows are unchanged. This is the phase-sensitive analogue of XOR-ing one symplectic row onto another, and is the only correct way to combine rows of a signed tableau.

Parameters:
  • target – Index of the row that is overwritten.

  • source – Index of the row that is multiplied onto target.

signs() numpy.typing.NDArray[numpy.int8][source]

Return the derived binary sign for each row, in (-1)^r i^(x.z) X^x Z^z.

Raises:

InvalidPauliError – If any row is not Hermitian.

is_hermitian() bool[source]

Check if all rows of the stabilizer tableau are Hermitian.

as_matrix() numpy.typing.NDArray[numpy.int8][source]

Convert the stabilizer tableau to a matrix.

as_hermitian_matrix() numpy.typing.NDArray[numpy.int8][source]

Convert the stabilizer tableau to a binary matrix.

is_in_subgroup(p: Pauli) bool[source]

Check if a Pauli operator is in the subgroup generated by the rows of the PauliTableau.

To test many Paulis against the same subgroup, compute pauli_row_echelon() once and call pauli_in_reduced_subgroup() instead; this method redoes the elimination on every call.

apply_h(qubit: int) None[source]

Apply the Hadamard gate to the stabilizer tableau.

Parameters:

qubit – The index of the qubit to apply the Hadamard gate to.

apply_cx(ctrl: int, tar: int) None[source]

Apply the CNOT gate to the stabilizer tableau.

CX is a tensor product of single-qubit generator conjugations that never reorders an X past a Z on the same qubit, so it never contributes a phase: the exponent p is unchanged, only the support is relabeled.

Parameters:
  • ctrl – The index of the control qubit.

  • tar – The index of the target qubit.

apply_cz(ctrl: int, tar: int) None[source]

Apply the CZ gate to the stabilizer tableau.

Parameters:
  • ctrl – The index of the control qubit.

  • tar – The index of the target qubit.

apply_swap(q1: int, q2: int) None[source]

Apply the SWAP gate to the stabilizer tableau.

Parameters:
  • q1 – The index of the first qubit.

  • q2 – The index of the second qubit.

apply_s(qubit: int) None[source]

Apply the S gate to the stabilizer tableau.

Parameters:

qubit – The index of the qubit to apply the S gate to.

apply_sdg(qubit: int) None[source]

Apply the S† gate to the stabilizer tableau.

apply_x(qubit: int) None[source]

Apply the X gate to the stabilizer tableau.

apply_z(qubit: int) None[source]

Apply the Z gate to the stabilizer tableau.

apply_y(qubit: int) None[source]

Apply the Y gate to the stabilizer tableau.

copy() PauliTableau[source]

Return a copy of the stabilizer tableau.

to_pauli_list() list[Pauli][source]

Return the tableau as a list of Paulis that do not alias the tableau.

to_numpy() numpy.typing.NDArray[numpy.int8][source]

Convert the stabilizer tableau to a NumPy array.

Returns:

A NumPy array where the first 2n columns represent the symplectic matrix and the last column represents the phase vector.

is_css() bool[source]

Check if the stabilizer tableau is in CSS form.

to_css() tuple[CheckMatrix, CheckMatrix][source]

Convert the stabilizer tableau to CSS check matrices.

Returns:

A tuple containing the X and Z check matrices.

get_x_part() numpy.typing.NDArray[numpy.int8][source]

Get the X part of the stabilizer tableau.

get_z_part() numpy.typing.NDArray[numpy.int8][source]

Get the Z part of the stabilizer tableau.

symplectic_submatrix(q: int) numpy.typing.NDArray[numpy.int8][source]

Get the 2x2 symplectic submatrix for a given qubit.

Parameters:

q – The index of the qubit.

Returns:

A 2x2 NumPy array representing the symplectic submatrix for the given qubit.

is_identity() bool[source]

Check if the stabilizer tableau is the identity.

Returns:

True if the stabilizer tableau is the identity, False otherwise.

independent_rows() PauliTableau[source]

Return a new tableau containing an independent subset of the rows, phase-insensitive.

num_rows() int[source]

Return the number of rows in the stabilizer tableau.

is_row(pauli: Pauli) bool[source]

Check if a given Pauli operator is a stabilizer of the tableau.

Parameters:

pauli – A Pauli operator to check.

Returns:

True if the Pauli operator is a stabilizer, False otherwise.

StabilizerTableau

Deprecated alias for PauliTableau; use PauliTableau instead.

complete_stabilizer_tableau_with_destabilizers(stabilizers: PauliTableau, stab_rows: list[int] | None = None) PauliTableau[source]

Given a tableau of stabilizers, complete it to a full tableau by adding destabilizers.

Destabilizer d_i anticommutes with stabilizer s_i but commutes with all other stabilizers, destabilizers, and logical operators.

Parameters:
  • stabilizers – A tableau representing the stabilizers (and possibly some logical operators) of the code.

  • stab_rows – List of row indices that are stabilizers. If None, assumes all rows are stabilizers. Destabilizers will be added for each row specified in stab_rows.

Returns:

logical X, destabilizers, logical Z, stabilizers.

Return type:

A tableau ordered as

Note

This function assumes that all rows not specified in stab_rows are logical operators. These rows are split by position: the first half are treated as logical X operators, and the second half as logical Z operators. Any pre-existing destabilizers in the input tableau that are not identified in stab_rows will be treated as logical operators and may be reordered or reinterpreted according to this convention.

Raises:

ValueError – If any row index in stab_rows is out of bounds or if valid destabilizers cannot be found.

is_pauli_string(p: str) bool[source]

Check if a string is a valid Pauli string.

exception InvalidPauliError(message: str)[source]

Bases: ValueError

Exception raised when an invalid Pauli operator is encountered.

class CheckMatrix(matrix: numpy.typing.NDArray[numpy.int8], pauli_type: str)[source]

Type alias for CSS check matrices.

is_x_type() bool[source]

Check if the check matrix is of type ‘X’.

is_z_type() bool[source]

Check if the check matrix is of type ‘Z’.

copy() CheckMatrix[source]

Create a copy of the check matrix.

is_identity() bool[source]

Check if the check matrix is an identity matrix.

num_qubits() int[source]

Get the number of qubits represented by the check matrix.

num_rows() int[source]

Get the number of rows in the check matrix.

equ_span(other: CheckMatrix | numpy.typing.NDArray[numpy.int8]) bool[source]

Check if the row spans of this check matrix and another check matrix are equal.