Skip to content

Generalized tableau

GeneralizedTableau dataclass

GeneralizedTableau(n_qubits: int, min_abs_coeff: float = 1e-10, seed: InitVar[int | None] = None)

Bases: CliffordMixin, CliffordExtensionMixin, RotationsMixin, NoiseMixin, LossMixin

Generalized stabilizer tableau for quantum circuit simulation.

Represents an arbitrary quantum state in the basis spanned by the stabilizer tableau. It supports Clifford gates, arbitrary single- and two-qubit rotations, noise channels, and mid-circuit measurement. The coefficient vector grows exponentially with the number of non-Clifford operations applied.

Attributes:

Name Type Description
n_qubits int

The number of qubits.

min_abs_coeff float

Coefficient threshold - coefficients smaller than this are pruned from the sparse coefficient vector.

seed float

Optional RNG seed for reproducible simulations. If None (the default), the RNG is seeded from OS entropy.

__copy__

__copy__() -> GeneralizedTableau

Return a copy of this tableau, including its RNG state.

Both the original and the copy will produce identical random sequences from this point forward. To get an independent copy with a fresh RNG, use :meth:fork instead.

Source code in ppvm-python/src/ppvm/generalized_tableau.py
 96
 97
 98
 99
100
101
102
103
104
105
def __copy__(self) -> "GeneralizedTableau":
    """Return a copy of this tableau, including its RNG state.

    Both the original and the copy will produce identical random sequences
    from this point forward. To get an independent copy with a fresh RNG,
    use :meth:`fork` instead.
    """
    copied = GeneralizedTableau(self.n_qubits, self.min_abs_coeff)
    object.__setattr__(copied, "_interface", self._interface.__copy__())
    return copied

__deepcopy__

__deepcopy__(memo: dict) -> GeneralizedTableau

Return a deep copy of this tableau, including its RNG state.

Both the original and the copy will produce identical random sequences from this point forward. To get an independent copy with a fresh RNG, use :meth:fork instead.

Source code in ppvm-python/src/ppvm/generalized_tableau.py
107
108
109
110
111
112
113
114
115
116
def __deepcopy__(self, memo: dict) -> "GeneralizedTableau":
    """Return a deep copy of this tableau, including its RNG state.

    Both the original and the copy will produce identical random sequences
    from this point forward. To get an independent copy with a fresh RNG,
    use :meth:`fork` instead.
    """
    copied = GeneralizedTableau(self.n_qubits, self.min_abs_coeff)
    object.__setattr__(copied, "_interface", self._interface.__deepcopy__(memo))
    return copied

__str__

__str__() -> str

Return a human-readable representation of the tableau state.

Source code in ppvm-python/src/ppvm/generalized_tableau.py
118
119
120
def __str__(self) -> str:
    """Return a human-readable representation of the tableau state."""
    return self._interface.__str__()

fork

fork(seed: int | None = None) -> GeneralizedTableau

Fork this tableau into an independent simulation branch.

Clones all quantum state but reinitializes the RNG, so the returned tableau evolves independently from this one. If seed is provided the new RNG is seeded deterministically; otherwise it is seeded from OS entropy.

Use this when branching a simulation into independent trajectories. To preserve the RNG state exactly (e.g. for checkpointing), use copy.copy() or copy.deepcopy() instead.

Parameters:

Name Type Description Default
seed int | None

Optional integer seed for the forked RNG.

None

Returns:

Type Description
GeneralizedTableau

A new GeneralizedTableau with the same quantum state but an

GeneralizedTableau

independent RNG.

Source code in ppvm-python/src/ppvm/generalized_tableau.py
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def fork(self, seed: int | None = None) -> "GeneralizedTableau":
    """Fork this tableau into an independent simulation branch.

    Clones all quantum state but reinitializes the RNG, so the returned
    tableau evolves independently from this one. If ``seed`` is provided
    the new RNG is seeded deterministically; otherwise it is seeded from
    OS entropy.

    Use this when branching a simulation into independent trajectories.
    To preserve the RNG state exactly (e.g. for checkpointing), use
    ``copy.copy()`` or ``copy.deepcopy()`` instead.

    Args:
        seed: Optional integer seed for the forked RNG.

    Returns:
        A new ``GeneralizedTableau`` with the same quantum state but an
        independent RNG.
    """
    forked = GeneralizedTableau(self.n_qubits, self.min_abs_coeff)
    object.__setattr__(forked, "_interface", self._interface.fork(seed))
    return forked

is_lost

is_lost(addr0: int) -> bool

Check whether a qubit has been lost.

Parameters:

Name Type Description Default
addr0 int

The index of the qubit.

required

Returns:

Type Description
bool

True if the qubit is lost, False otherwise.

Source code in ppvm-python/src/ppvm/generalized_tableau.py
185
186
187
188
189
190
191
192
193
194
def is_lost(self, addr0: int) -> bool:
    """Check whether a qubit has been lost.

    Args:
        addr0: The index of the qubit.

    Returns:
        True if the qubit is lost, False otherwise.
    """
    return self._interface.is_lost(addr0)

loss_values

loss_values() -> list[bool]

Return the loss state of all qubits.

Returns:

Type Description
list[bool]

A list of booleans of length n_qubits, where each entry is

list[bool]

True if the corresponding qubit is lost and False otherwise.

Source code in ppvm-python/src/ppvm/generalized_tableau.py
196
197
198
199
200
201
202
203
def loss_values(self) -> list[bool]:
    """Return the loss state of all qubits.

    Returns:
        A list of booleans of length ``n_qubits``, where each entry is
        True if the corresponding qubit is lost and False otherwise.
    """
    return self._interface.loss_values()

measure

measure(addr0: int) -> MeasurementResult

Measure the specified qubit in the Z basis.

Parameters:

Name Type Description Default
addr0 int

The index of the target qubit.

required

Returns:

Type Description
MeasurementResult

The measurement outcome as a MeasurementResult, which is

MeasurementResult

LOST if the qubit has been lost, ZERO or ONE otherwise.

Source code in ppvm-python/src/ppvm/generalized_tableau.py
138
139
140
141
142
143
144
145
146
147
148
149
def measure(self, addr0: int) -> MeasurementResult:
    """Measure the specified qubit in the Z basis.

    Args:
        addr0: The index of the target qubit.

    Returns:
        The measurement outcome as a ``MeasurementResult``, which is
        ``LOST`` if the qubit has been lost, ``ZERO`` or ``ONE`` otherwise.
    """
    m = self._interface.measure(addr0)
    return MeasurementResult._from_raw(m)

reset

reset(addr0: int) -> None

Reset the specified qubit to the |0> state.

Parameters:

Name Type Description Default
addr0 int

The index of the target qubit.

required
Source code in ppvm-python/src/ppvm/generalized_tableau.py
169
170
171
172
173
174
175
def reset(self, addr0: int) -> None:
    """Reset the specified qubit to the |0> state.

    Args:
        addr0: The index of the target qubit.
    """
    self._interface.reset(addr0)

reset_loss_channel

reset_loss_channel(addr0: int) -> None

Reset a lost qubit to being active again.

Parameters:

Name Type Description Default
addr0 int

The index of the target qubit.

required
Source code in ppvm-python/src/ppvm/generalized_tableau.py
177
178
179
180
181
182
183
def reset_loss_channel(self, addr0: int) -> None:
    """Reset a lost qubit to being active again.

    Args:
        addr0: The index of the target qubit.
    """
    self._interface.reset_loss_channel(addr0)

run_stim_file

run_stim_file(file_path: str) -> list[MeasurementResult]

Execute a STIM circuit from a file and return all measurement results.

.. note:: This method mutates the tableau in place. To run multiple independent shots, call :meth:fork to obtain a fresh copy before each run.

Reads the circuit from file_path and runs it identically to :meth:run_stim_string. Only the squin subset of the STIM instruction set is supported; control flow is not supported. Measurements are collected in the order they appear in the circuit, following the STIM convention: each measurement instruction appends its results left-to-right as the qubits are listed, and later instructions append after earlier ones.

Parameters:

Name Type Description Default
file_path str

Path to a .stim file containing a STIM circuit.

required

Returns:

Type Description
list[MeasurementResult]

A list of MeasurementResult values, one per measured qubit,

list[MeasurementResult]

in circuit order. Each value is ZERO, ONE, or LOST

list[MeasurementResult]

(if the qubit had been lost prior to measurement).

Raises:

Type Description
PanicException

If the file cannot be read.

Source code in ppvm-python/src/ppvm/generalized_tableau.py
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
def run_stim_file(self, file_path: str) -> list[MeasurementResult]:
    """Execute a STIM circuit from a file and return all measurement results.

    .. note::
        This method **mutates** the tableau in place. To run multiple
        independent shots, call :meth:`fork` to obtain a fresh copy before
        each run.

    Reads the circuit from ``file_path`` and runs it identically to
    :meth:`run_stim_string`. Only the squin subset of the STIM instruction
    set is supported; control flow is not supported. Measurements are
    collected in the order they appear in the circuit, following the STIM
    convention: each measurement instruction appends its results
    left-to-right as the qubits are listed, and later instructions append
    after earlier ones.

    Args:
        file_path: Path to a ``.stim`` file containing a STIM circuit.

    Returns:
        A list of ``MeasurementResult`` values, one per measured qubit,
        in circuit order. Each value is ``ZERO``, ``ONE``, or ``LOST``
        (if the qubit had been lost prior to measurement).

    Raises:
        pyo3_runtime.PanicException: If the file cannot be read.
    """
    results = self._interface.run_stim_file(file_path)
    return list(map(MeasurementResult._from_raw, results))

run_stim_string

run_stim_string(circuit: str) -> list[MeasurementResult]

Execute a STIM circuit given as a string and return all measurement results.

.. note:: This method mutates the tableau in place. To run multiple independent shots, call :meth:fork to obtain a fresh copy before each run.

Parses and runs a STIM-format circuit, applying each instruction to this tableau in sequence. Only the squin subset of the STIM instruction set is supported; control flow is not supported. Measurements are collected in the order they appear in the circuit, following the STIM convention: each measurement instruction appends its results left-to-right as the qubits are listed, and later instructions append after earlier ones.

Parameters:

Name Type Description Default
circuit str

A multi-line string containing a STIM circuit.

required

Returns:

Type Description
list[MeasurementResult]

A list of MeasurementResult values, one per measured qubit,

list[MeasurementResult]

in circuit order. Each value is ZERO, ONE, or LOST

list[MeasurementResult]

(if the qubit had been lost prior to measurement).

Source code in ppvm-python/src/ppvm/generalized_tableau.py
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
def run_stim_string(self, circuit: str) -> list[MeasurementResult]:
    """Execute a STIM circuit given as a string and return all measurement results.

    .. note::
        This method **mutates** the tableau in place. To run multiple
        independent shots, call :meth:`fork` to obtain a fresh copy before
        each run.

    Parses and runs a STIM-format circuit, applying each instruction to
    this tableau in sequence. Only the squin subset of the STIM instruction
    set is supported; control flow is not supported. Measurements are
    collected in the order they appear in the circuit, following the STIM
    convention: each measurement instruction appends its results
    left-to-right as the qubits are listed, and later instructions append
    after earlier ones.

    Args:
        circuit: A multi-line string containing a STIM circuit.

    Returns:
        A list of ``MeasurementResult`` values, one per measured qubit,
        in circuit order. Each value is ``ZERO``, ``ONE``, or ``LOST``
        (if the qubit had been lost prior to measurement).
    """
    results = self._interface.run_stim_string(circuit)
    return list(map(MeasurementResult._from_raw, results))

t

t(addr0: int) -> None

Apply a T gate (π/8 rotation) to the specified qubit.

Parameters:

Name Type Description Default
addr0 int

The index of the target qubit.

required
Source code in ppvm-python/src/ppvm/generalized_tableau.py
122
123
124
125
126
127
128
def t(self, addr0: int) -> None:
    """Apply a T gate (π/8 rotation) to the specified qubit.

    Args:
        addr0: The index of the target qubit.
    """
    self._interface.t(addr0)

t_adj

t_adj(addr0: int) -> None

Apply a T adjoint gate (negative π/8 rotation) to the specified qubit.

Parameters:

Name Type Description Default
addr0 int

The index of the target qubit.

required
Source code in ppvm-python/src/ppvm/generalized_tableau.py
130
131
132
133
134
135
136
def t_adj(self, addr0: int) -> None:
    """Apply a T adjoint gate (negative π/8 rotation) to the specified qubit.

    Args:
        addr0: The index of the target qubit.
    """
    self._interface.t_adj(addr0)

u3

u3(addr0: int, theta: float, phi: float, lam: float)

Apply the U3 gate to the specified qubit.

U3(θ, φ, λ) = RZ(φ) · RY(θ) · RZ(λ)

The corresponding unitary matrix is:

[ cos(θ/2)            -e^(iλ)·sin(θ/2)       ]
[ e^(iφ)·sin(θ/2)     e^(i(φ+λ))·cos(θ/2)   ]

Parameters:

Name Type Description Default
addr0 int

The address of the qubit to apply the gate to.

required
theta float

Rotation angle θ (in radians) for the RY component.

required
phi float

Rotation angle φ (in radians) for the first RZ component.

required
lam float

Rotation angle λ (in radians) for the second RZ component.

required
Source code in ppvm-python/src/ppvm/generalized_tableau.py
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
def u3(self, addr0: int, theta: float, phi: float, lam: float):
    """Apply the U3 gate to the specified qubit.

    U3(θ, φ, λ) = RZ(φ) · RY(θ) · RZ(λ)

    The corresponding unitary matrix is:

        [ cos(θ/2)            -e^(iλ)·sin(θ/2)       ]
        [ e^(iφ)·sin(θ/2)     e^(i(φ+λ))·cos(θ/2)   ]

    Args:
        addr0: The address of the qubit to apply the gate to.
        theta: Rotation angle θ (in radians) for the RY component.
        phi: Rotation angle φ (in radians) for the first RZ component.
        lam: Rotation angle λ (in radians) for the second RZ component.
    """
    self._interface.u3(addr0, theta, phi, lam)

MeasurementResult

Bases: IntEnum

A measurement outcome, which accounts for a qubit being potentially lost.