ppvm/ Pauli propagation & tableau simulation
API contents

Python — ppvm

Rust

ppvm-sym
Generated reference

API Reference

Python items 121Rust items 112Generated

Pythonppvm

Pythonic wrapper around the native Rust runtime. All items below live under the ppvm top-level module.

generalized_tableau

classGeneralizedTableauppvm.generalized_tableau.GeneralizedTableau
class GeneralizedTableau

Generalized stabilizer tableau for quantum circuit simulation.

Full docstring

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.

classMeasurementResultppvm.generalized_tableau.MeasurementResult
class MeasurementResult

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

functionsample_stimppvm.generalized_tableau.sample_stim
def sample_stim(prog: StimProgram, n_qubits = None, min_abs_coeff: float = 1e-10, num_shots: int = 1, seed = None)

Multi-shot sampling — module-level alias for GeneralizedTableau.sample.

Full docstring

Multi-shot sampling — module-level alias for GeneralizedTableau.sample.

When n_qubits is None (the default) the qubit count is inferred from the program; see GeneralizedTableau.sample. Shots are sampled in parallel across CPU cores with the GIL released; see GeneralizedTableau.sample for seeding and RAYON_NUM_THREADS.

methodasymmetric_loss_channelppvm.generalized_tableau.GeneralizedTableau.asymmetric_loss_channel
asymmetric_loss_channel(addr0: int, p0: float, p1: float) -> None

Apply a state-dependent ("asymmetric") loss channel to a qubit.

Full docstring

Apply a state-dependent ("asymmetric") loss channel to a qubit.

The qubit is lost from |0> with probability p0 and from |1> with probability p1, so the total loss probability depends on the current populations: p_tot = p0 * (1 + <Z>)/2 + p1 * (1 - <Z>)/2.

.. note:: This is the trajectory approximation of the loss channel. It is exact for the loss statistics and in the symmetric limit p0 == p1 (where it matches loss_channel), but it does not apply the survival back-action, so for p0 != p1 the surviving qubit's state is left unchanged. See issue #39.

Parameters
addr0int

The index of the target qubit.

p0float

The loss probability from the |0> state.

p1float

The loss probability from the |1> state.

methodcoefficientsppvm.generalized_tableau.GeneralizedTableau.coefficients
coefficients()

Return a snapshot of the sparse coefficient vector.

Full docstring

Return a snapshot of the sparse coefficient vector.

The tableau represents the state as a sparse superposition over the basis states of its stabilizer frame. This returns that vector as a mapping from basis-state index to complex amplitude.

The returned dict is a copy: mutating it does not affect the tableau's internal state.

Returns

A dict mapping each populated basis-state index to its complex amplitude.

methodcurrent_measurement_recordppvm.generalized_tableau.GeneralizedTableau.current_measurement_record
current_measurement_record()

Return all measurement outcomes recorded so far.

Full docstring

Return all measurement outcomes recorded so far.

Returns

A list of MeasurementResult outcomes in measurement order.

methodcz_blockppvm.generalized_tableau.GeneralizedTableau.cz_block
cz_block(control_base: int, target_base: int, count: int) -> None

Apply a fused block of CZ gates over constant-offset qubit pairs.

Full docstring

Apply a fused block of CZ gates over constant-offset qubit pairs.

Applies CZ to (control_base + i, target_base + i) for i in range(count) -- i.e. the gates zip(range(control_base, ...), range(target_base, ...)) would produce. This uses a word-level kernel that is much faster than the equivalent cz call when the pairs form a contiguous, constant-offset block (e.g. entangling two adjacent qubit registers). For scattered pairs, use cz.

CZ is symmetric, so control_base and target_base may be given in either order.

Parameters
control_baseint

First qubit of the control run.

target_baseint

First qubit of the target run.

countint

Number of CZ pairs.

methodexpectationppvm.generalized_tableau.GeneralizedTableau.expectation
expectation(word: str) -> float

Compute ⟨ψ|word|ψ⟩ for a single multi-qubit Pauli string.

Full docstring

Compute ⟨ψ|word|ψ⟩ for a single multi-qubit Pauli string.

Parameters
wordstr

A dense Pauli string with one character per qubit, each drawn from I, X, Y, Z (e.g. "ZZ" for a two-qubit state). Its length must equal the tableau's qubit count.

Returns
float

The real expectation value of word in the current state.

methodforkppvm.generalized_tableau.GeneralizedTableau.fork
fork(seed = None) -> GeneralizedTableau

Fork this tableau into an independent simulation branch.

Full docstring

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
seed

Optional integer seed for the forked RNG.

Returns
GeneralizedTableau

A new GeneralizedTableau with the same quantum state but an independent RNG.

methodis_lostppvm.generalized_tableau.GeneralizedTableau.is_lost
is_lost(addr0: int) -> bool

Check whether a qubit has been lost.

Full docstring

Check whether a qubit has been lost.

Parameters
addr0int

The index of the qubit.

Returns
bool

True if the qubit is lost, False otherwise.

methodloss_valuesppvm.generalized_tableau.GeneralizedTableau.loss_values
loss_values()

Return the loss state of all qubits.

Full docstring

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.

methodmeasureppvm.generalized_tableau.GeneralizedTableau.measure
measure(addr0: int) -> MeasurementResult

Measure the specified qubit in the Z basis.

Full docstring

Measure the specified qubit in the Z basis.

Parameters
addr0int

The index of the target qubit.

Returns
MeasurementResult

The measurement outcome as a MeasurementResult, which is LOST if the qubit has been lost, ZERO or ONE otherwise.

methodmeasure_manyppvm.generalized_tableau.GeneralizedTableau.measure_many
measure_many(targets = ())

Measure several qubits in the Z basis.

Full docstring

Measure several qubits in the Z basis.

Parameters
*targets

The indices of the target qubits.

Returns

A list of MeasurementResult outcomes, one per target.

methodnum_coefficientsppvm.generalized_tableau.GeneralizedTableau.num_coefficients
num_coefficients() -> int

Return the number of branches in the coefficient vector.

Full docstring

Return the number of branches in the coefficient vector.

This is the number of entries in the dict returned by coefficients, computed without materializing it.

Returns
int

The count of populated entries in the sparse coefficient vector.

methodresetppvm.generalized_tableau.GeneralizedTableau.reset
reset(targets = ()) -> None

Reset each target qubit to the |0> state.

Full docstring

Reset each target qubit to the |0> state.

Parameters
*targets

The indices of the target qubits.

methodreset_loss_channelppvm.generalized_tableau.GeneralizedTableau.reset_loss_channel
reset_loss_channel(addr0: int) -> None

Reset a lost qubit to being active again.

Full docstring

Reset a lost qubit to being active again.

Parameters
addr0int

The index of the target qubit.

methodreset_xppvm.generalized_tableau.GeneralizedTableau.reset_x
reset_x(targets = ()) -> None

Reset each target qubit to the |+> state.

Full docstring

Reset each target qubit to the |+> state.

Parameters
*targets

The indices of the target qubits.

methodreset_yppvm.generalized_tableau.GeneralizedTableau.reset_y
reset_y(targets = ()) -> None

Reset each target qubit to the |+i> state.

Full docstring

Reset each target qubit to the |+i> state.

Parameters
*targets

The indices of the target qubits.

methodreset_zppvm.generalized_tableau.GeneralizedTableau.reset_z
reset_z(targets = ()) -> None

Reset each target qubit to the |0> state.

Full docstring

Reset each target qubit to the |0> state.

Parameters
*targets

The indices of the target qubits.

methodrunppvm.generalized_tableau.GeneralizedTableau.run
run(prog: StimProgram)

Execute a parsed Stim program against this tableau (single shot).

Full docstring

Execute a parsed Stim program against this tableau (single shot).

.. note:: This mutates the tableau in place. For independent shots use fork or ppvm.sample_stim / sample helpers (which build a fresh tableau per shot).

methodsampleppvm.generalized_tableau.GeneralizedTableau.sample
sample(cls, prog: StimProgram, n_qubits = None, min_abs_coeff: float = 1e-10, num_shots: int = 1, seed = None)

Run num_shots shots of prog and return all measurement results.

Full docstring

Run num_shots shots of prog and return all measurement results.

Each shot starts from a fresh tableau, so this is the right entry point for multi-shot sampling.

When n_qubits is None (the default) the qubit count is inferred from the program via prog.num_qubits (one past the highest qubit index it references), falling back to 1 for a program that touches no qubits. Pass an explicit n_qubits to size the tableau larger.

Shots run in parallel across CPU cores (the GIL is released during sampling), with a serial fallback for small batches. When seed is given (it must fit in an unsigned 64-bit integer), shot i uses (seed + i) % 2**64 (wrapping u64 arithmetic), so results are reproducible and independent of the number of threads. Set the RAYON_NUM_THREADS environment variable before the first call to control the pool size (it defaults to the number of logical cores).

methodtppvm.generalized_tableau.GeneralizedTableau.t
t(targets = ()) -> None

Apply a T gate (π/8 rotation) to each target qubit.

Full docstring

Apply a T gate (π/8 rotation) to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodt_dagppvm.generalized_tableau.GeneralizedTableau.t_dag
t_dag(targets = ()) -> None

Apply a T adjoint gate (negative π/8 rotation) to each target qubit.

Full docstring

Apply a T adjoint gate (negative π/8 rotation) to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodtraceppvm.generalized_tableau.GeneralizedTableau.trace
trace(pattern: str) -> float

Sum Pauli expectations over every word matching pattern.

Full docstring

Sum Pauli expectations over every word matching pattern.

Enumerates each PauliWord accepted by pattern and returns the sum of their expectations. Star quantifiers (X*) are not supported — use counted repetition (Z?{n}) or positional anchors instead.

Parameters
patternstr

A Pauli pattern string (e.g. "Z?{2}" or "Z0Z1").

Returns
float

The summed expectation value.

methodu3ppvm.generalized_tableau.GeneralizedTableau.u3
u3(addr0: int, theta: float, phi: float, lam: float)

Apply the U3 gate to the specified qubit.

Full docstring

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
addr0int

The address of the qubit to apply the gate to.

thetafloat

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

phifloat

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

lamfloat

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

attributeMAX_N_QUBITSppvm.generalized_tableau.MAX_N_QUBITS
MAX_N_QUBITS

Maximum number of qubits supported by the Python bindings.

Full docstring

Maximum number of qubits supported by the Python bindings.

The native module pre-compiles a fixed set of tableau interfaces; beyond this limit, use the Rust crate directly.

generalized_tableau_sum

classGeneralizedTableauSumppvm.generalized_tableau_sum.GeneralizedTableauSum
class GeneralizedTableauSum

A sum over generalized tableaus, representing a density matrix that is a weighted sum over pure state projectors (classical mixture). Each projector is represented by a generalized tableau. The respective weights are the probabilities wi…

Full docstring

A sum over generalized tableaus, representing a density matrix that is a weighted sum over pure state projectors (classical mixture). Each projector is represented by a generalized tableau. The respective weights are the probabilities with which the system is in the corresponding state.

classTableauSumSamplerppvm.generalized_tableau_sum.TableauSumSampler
class TableauSumSampler

Sample a GeneralizedTableauSum.

Full docstring

Sample a GeneralizedTableauSum.

Construct via GeneralizedTableauSum.sampler().

methodmeasureppvm.generalized_tableau_sum.GeneralizedTableauSum.measure
measure(addr0: int)

Branch on a mid-circuit Z measurement and return outcome probabilities.

Full docstring

Branch on a mid-circuit Z measurement and return outcome probabilities.

Parameters
addr0int

The index of the target qubit.

Returns

A mapping from MeasurementResult (ZERO, ONE, LOST) to the corresponding outcome probability.

methodresetppvm.generalized_tableau_sum.GeneralizedTableauSum.reset
reset(targets = ()) -> None

Reset each target qubit to the |0> state.

Full docstring

Reset each target qubit to the |0> state.

Parameters
*targets

The indices of the target qubits.

methodreset_loss_channelppvm.generalized_tableau_sum.GeneralizedTableauSum.reset_loss_channel
reset_loss_channel(addr0: int) -> None

Reset a lost qubit to being active again.

Full docstring

Reset a lost qubit to being active again.

Parameters
addr0int

The index of the target qubit.

methodsamplerppvm.generalized_tableau_sum.GeneralizedTableauSum.sampler
sampler() -> TableauSumSampler

Compile a sampler over a snapshot of the current state.

Full docstring

Compile a sampler over a snapshot of the current state.

The sampler holds its own RNG and a copy of the sum's branches, so further gates applied to this tableau do not affect it.

Returns
TableauSumSampler

A sampler drawing shots from the current state.

methodtppvm.generalized_tableau_sum.GeneralizedTableauSum.t
t(targets = ()) -> None

Apply a T gate (π/8 rotation) to each target qubit.

Full docstring

Apply a T gate (π/8 rotation) to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodt_dagppvm.generalized_tableau_sum.GeneralizedTableauSum.t_dag
t_dag(targets = ()) -> None

Apply a T adjoint gate (negative π/8 rotation) to each target qubit.

Full docstring

Apply a T adjoint gate (negative π/8 rotation) to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodu3ppvm.generalized_tableau_sum.GeneralizedTableauSum.u3
u3(addr0: int, theta: float, phi: float, lam: float)

Apply the U3 gate to the specified qubit.

Full docstring

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
addr0int

The address of the qubit to apply the gate to.

thetafloat

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

phifloat

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

lamfloat

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

methodraw_sampleppvm.generalized_tableau_sum.TableauSumSampler.raw_sample
raw_sample()

Draw a single shot as raw integer codes (0/1/2 for |0>/|1>/lost).

Full docstring

Draw a single shot as raw integer codes (0/1/2 for |0>/|1>/lost).

Faster than sample, as it skips the MeasurementResult conversion.

Returns

Per-qubit integer outcome codes, indexed by qubit address.

methodraw_shotsppvm.generalized_tableau_sum.TableauSumSampler.raw_shots
raw_shots(num_shots: int)

Draw num_shots shots as raw integer codes (0/1/2 for |0>/|1>/lost).

Full docstring

Draw num_shots shots as raw integer codes (0/1/2 for |0>/|1>/lost).

Faster than sample_shots, as it skips the MeasurementResult conversion.

Parameters
num_shotsint

The number of shots to draw.

Returns

One list of per-qubit integer outcome codes per shot.

methodsampleppvm.generalized_tableau_sum.TableauSumSampler.sample
sample()

Draw a single shot: one measurement outcome per qubit.

Full docstring

Draw a single shot: one measurement outcome per qubit.

Returns

Per-qubit outcomes, indexed by qubit address.

methodsample_shotsppvm.generalized_tableau_sum.TableauSumSampler.sample_shots
sample_shots(num_shots: int)

Draw num_shots shots, each with one outcome per qubit.

Full docstring

Draw num_shots shots, each with one outcome per qubit.

Parameters
num_shotsint

The number of shots to draw.

Returns

One list of per-qubit outcomes per shot.

mixins

classCliffordExtensionMixinppvm.mixins.CliffordExtensionMixin
class CliffordExtensionMixin

Additional Clifford gates without per-gate truncation control.

classCliffordMixinppvm.mixins.CliffordMixin
class CliffordMixin

Clifford gates without per-gate truncation control.

classLossMixinppvm.mixins.LossMixin
class LossMixin

Loss channels without per-gate truncation control.

classNoiseMixinppvm.mixins.NoiseMixin
class NoiseMixin

Noise channels without per-gate truncation control.

classRotationsMixinppvm.mixins.RotationsMixin
class RotationsMixin

Rotation gates without per-gate truncation control.

classTruncatingCliffordExtensionMixinppvm.mixins.TruncatingCliffordExtensionMixin
class TruncatingCliffordExtensionMixin

Additional Clifford gates with a per-gate truncate kwarg.

classTruncatingCliffordMixinppvm.mixins.TruncatingCliffordMixin
class TruncatingCliffordMixin

Clifford gates with a per-gate truncate kwarg (used by PauliSum).

classTruncatingNoiseMixinppvm.mixins.TruncatingNoiseMixin
class TruncatingNoiseMixin

Noise channels with a per-gate truncate kwarg (used by PauliSum).

Full docstring

Noise channels with a per-gate truncate kwarg (used by PauliSum).

two_qubit_pauli_error_probabilities is inherited unchanged from NoiseMixin.

classTruncatingRotationsMixinppvm.mixins.TruncatingRotationsMixin
class TruncatingRotationsMixin

Rotation gates with a per-gate truncate kwarg (used by PauliSum).

methodcyppvm.mixins.CliffordExtensionMixin.cy
cy(targets = ()) -> None

Apply controlled-Y gates over consecutive control/target pairs.

Full docstring

Apply controlled-Y gates over consecutive control/target pairs.

Parameters
*targets

A flat list of qubit indices, broadcast as (control, target) pairs.

methods_dagppvm.mixins.CliffordExtensionMixin.s_dag
s_dag(targets = ()) -> None

Apply an S adjoint gate (sqrt(Z) dagger) to each target qubit.

Full docstring

Apply an S adjoint gate (sqrt(Z) dagger) to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodsqrt_xppvm.mixins.CliffordExtensionMixin.sqrt_x
sqrt_x(targets = ()) -> None

Apply a sqrt(X) gate to each target qubit.

Full docstring

Apply a sqrt(X) gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodsqrt_x_dagppvm.mixins.CliffordExtensionMixin.sqrt_x_dag
sqrt_x_dag(targets = ()) -> None

Apply a sqrt(X) adjoint gate to each target qubit.

Full docstring

Apply a sqrt(X) adjoint gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodsqrt_yppvm.mixins.CliffordExtensionMixin.sqrt_y
sqrt_y(targets = ()) -> None

Apply a sqrt(Y) gate to each target qubit.

Full docstring

Apply a sqrt(Y) gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodsqrt_y_dagppvm.mixins.CliffordExtensionMixin.sqrt_y_dag
sqrt_y_dag(targets = ()) -> None

Apply a sqrt(Y) adjoint gate to each target qubit.

Full docstring

Apply a sqrt(Y) adjoint gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodcnotppvm.mixins.CliffordMixin.cnot
cnot(targets = ()) -> None

Apply CNOT (controlled-X) gates over consecutive control/target pairs.

Full docstring

Apply CNOT (controlled-X) gates over consecutive control/target pairs.

Parameters
*targets

A flat list of qubit indices, broadcast as (control, target) pairs.

methodczppvm.mixins.CliffordMixin.cz
cz(targets = ()) -> None

Apply CZ (controlled-Z) gates over consecutive qubit pairs.

Full docstring

Apply CZ (controlled-Z) gates over consecutive qubit pairs.

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

methodhppvm.mixins.CliffordMixin.h
h(targets = ()) -> None

Apply a Hadamard gate to each target qubit.

Full docstring

Apply a Hadamard gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodsppvm.mixins.CliffordMixin.s
s(targets = ()) -> None

Apply an S gate (sqrt(Z)) to each target qubit.

Full docstring

Apply an S gate (sqrt(Z)) to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodxppvm.mixins.CliffordMixin.x
x(targets = ()) -> None

Apply a Pauli X gate to each target qubit.

Full docstring

Apply a Pauli X gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodyppvm.mixins.CliffordMixin.y
y(targets = ()) -> None

Apply a Pauli Y gate to each target qubit.

Full docstring

Apply a Pauli Y gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodzppvm.mixins.CliffordMixin.z
z(targets = ()) -> None

Apply a Pauli Z gate to each target qubit.

Full docstring

Apply a Pauli Z gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

methodcorrelated_loss_channelppvm.mixins.LossMixin.correlated_loss_channel
correlated_loss_channel(addr0: int, addr1: int, p) -> None

Apply a correlated loss channel to two qubits.

Full docstring

Apply a correlated loss channel to two qubits.

Parameters
addr0int

The index of the first target qubit.

addr1int

The index of the second target qubit.

p

A list of three probabilities:

  • p[0]: probability of losing both qubits simultaneously when both are in the qubit subspace.
  • p[1]: probability of losing exactly one qubit when both are in the qubit subspace (which qubit is lost is 50/50 random).
  • p[2]: probability of losing the remaining active qubit when the other has already been lost prior to this channel.
methodloss_channelppvm.mixins.LossMixin.loss_channel
loss_channel(addr0: int, p: float) -> None

Apply a loss channel to the specified qubit.

Full docstring

Apply a loss channel to the specified qubit.

Parameters
addr0int

The index of the target qubit.

pfloat

The loss probability.

methoddepolarize1ppvm.mixins.NoiseMixin.depolarize1
depolarize1(args: Any = (), p = None) -> None

Apply a single-qubit depolarizing channel to each target qubit.

Full docstring

Apply a single-qubit depolarizing channel to each target qubit.

Parameters
*targets

The indices of the target qubits.

p

The depolarizing probability.

methoddepolarize2ppvm.mixins.NoiseMixin.depolarize2
depolarize2(args: Any = (), p = None) -> None

Apply a two-qubit depolarizing channel over consecutive qubit pairs.

Full docstring

Apply a two-qubit depolarizing channel over consecutive qubit pairs.

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

p

The depolarizing probability.

methodpauli_errorppvm.mixins.NoiseMixin.pauli_error
pauli_error(args: Any = (), p = None) -> None

Apply a single-qubit Pauli error channel to each target qubit.

Full docstring

Apply a single-qubit Pauli error channel to each target qubit.

Parameters
*targets

The indices of the target qubits.

p

Error probabilities [p_x, p_y, p_z] for X, Y, Z errors. The identity probability is implicitly 1 - sum(p).

methodtwo_qubit_pauli_errorppvm.mixins.NoiseMixin.two_qubit_pauli_error
two_qubit_pauli_error(args: Any = (), p = None) -> None

Apply a two-qubit Pauli error channel over consecutive qubit pairs.

Full docstring

Apply a two-qubit Pauli error channel over consecutive qubit pairs.

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

p

Error probabilities for the 15 non-identity two-qubit Pauli operators. Use two_qubit_pauli_error_probabilities to convert from a dictionary format.

methodtwo_qubit_pauli_error_probabilitiesppvm.mixins.NoiseMixin.two_qubit_pauli_error_probabilities
two_qubit_pauli_error_probabilities(error_probabilities)

Convert a dictionary of two-qubit Pauli error probabilities to a list.

Full docstring

Convert a dictionary of two-qubit Pauli error probabilities to a list.

Convenience method to convert a dictionary mapping two-qubit Pauli strings (e.g., "IX", "ZZ") to their probabilities into the ordered list format required by two_qubit_pauli_error.

Parameters
error_probabilities

Dictionary mapping two-qubit Pauli strings to their error probabilities. Missing keys default to 0.0.

Returns

A list of 15 probabilities in the canonical order (excludes "II").

methodx_errorppvm.mixins.NoiseMixin.x_error
x_error(args: Any = (), p = None) -> None

Apply an X error channel to each target qubit.

Full docstring

Apply an X error channel to each target qubit.

Parameters
*targets

The indices of the target qubits.

p

The probability of applying an X error.

methody_errorppvm.mixins.NoiseMixin.y_error
y_error(args: Any = (), p = None) -> None

Apply a Y error channel to each target qubit.

Full docstring

Apply a Y error channel to each target qubit.

Parameters
*targets

The indices of the target qubits.

p

The probability of applying a Y error.

methodz_errorppvm.mixins.NoiseMixin.z_error
z_error(args: Any = (), p = None) -> None

Apply a Z error channel to each target qubit.

Full docstring

Apply a Z error channel to each target qubit.

Parameters
*targets

The indices of the target qubits.

p

The probability of applying a Z error.

methodrppvm.mixins.RotationsMixin.r
r(addr0: int, axis_angle: float, theta: float) -> None

Apply a rotation about an axis in the X-Y plane to the specified qubit.

Full docstring

Apply a rotation about an axis in the X-Y plane to the specified qubit.

math R(\phi, \theta) = e^{-i \frac{\theta}{2} (\cos\phi\, X + \sin\phi\, Y)} = R_Z(\phi) R_X(\theta) R_Z(-\phi)

Parameters
addr0int

The index of the target qubit.

axis_anglefloat

The angle φ (in radians) of the rotation axis within the X-Y plane, measured from the X-axis.

thetafloat

The rotation angle in radians.

methodrxppvm.mixins.RotationsMixin.rx
rx(args: Any = (), theta = None) -> None

Apply an RX rotation gate to each target qubit.

Full docstring

Apply an RX rotation gate to each target qubit.

math R_X(\theta) = e^{-i \frac{\theta}{2} X} = \cos\frac{\theta}{2} I - i \sin\frac{\theta}{2} X

Parameters
*targets

The indices of the target qubits.

theta

The rotation angle in radians.

methodrxxppvm.mixins.RotationsMixin.rxx
rxx(args: Any = (), theta = None) -> None

Apply RXX (Ising XX) rotation gates over consecutive qubit pairs.

Full docstring

Apply RXX (Ising XX) rotation gates over consecutive qubit pairs.

math R_{XX}(\theta) = e^{-i \frac{\theta}{2} X \otimes X}

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

theta

The rotation angle in radians.

methodryppvm.mixins.RotationsMixin.ry
ry(args: Any = (), theta = None) -> None

Apply an RY rotation gate to each target qubit.

Full docstring

Apply an RY rotation gate to each target qubit.

math R_Y(\theta) = e^{-i \frac{\theta}{2} Y} = \cos\frac{\theta}{2} I - i \sin\frac{\theta}{2} Y

Parameters
*targets

The indices of the target qubits.

theta

The rotation angle in radians.

methodryyppvm.mixins.RotationsMixin.ryy
ryy(args: Any = (), theta = None) -> None

Apply RYY (Ising YY) rotation gates over consecutive qubit pairs.

Full docstring

Apply RYY (Ising YY) rotation gates over consecutive qubit pairs.

math R_{YY}(\theta) = e^{-i \frac{\theta}{2} Y \otimes Y}

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

theta

The rotation angle in radians.

methodrzppvm.mixins.RotationsMixin.rz
rz(args: Any = (), theta = None) -> None

Apply an RZ rotation gate to each target qubit.

Full docstring

Apply an RZ rotation gate to each target qubit.

math R_Z(\theta) = e^{-i \frac{\theta}{2} Z} = \cos\frac{\theta}{2} I - i \sin\frac{\theta}{2} Z

Parameters
*targets

The indices of the target qubits.

theta

The rotation angle in radians.

methodrzzppvm.mixins.RotationsMixin.rzz
rzz(args: Any = (), theta = None) -> None

Apply RZZ (Ising ZZ) rotation gates over consecutive qubit pairs.

Full docstring

Apply RZZ (Ising ZZ) rotation gates over consecutive qubit pairs.

math R_{ZZ}(\theta) = e^{-i \frac{\theta}{2} Z \otimes Z}

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

theta

The rotation angle in radians.

methodcyppvm.mixins.TruncatingCliffordExtensionMixin.cy
cy(targets = (), truncate: bool = True) -> None

Apply controlled-Y gates over consecutive control/target pairs.

Full docstring

Apply controlled-Y gates over consecutive control/target pairs.

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

truncatebool

See TruncatingCliffordMixin.x.

methods_dagppvm.mixins.TruncatingCliffordExtensionMixin.s_dag
s_dag(targets = (), truncate: bool = True) -> None

Apply an S adjoint gate (sqrt(Z) dagger) to each target qubit.

Full docstring

Apply an S adjoint gate (sqrt(Z) dagger) to each target qubit.

Parameters
*targets

The indices of the target qubits.

truncatebool

See TruncatingCliffordMixin.x.

methodsqrt_xppvm.mixins.TruncatingCliffordExtensionMixin.sqrt_x
sqrt_x(targets = (), truncate: bool = True) -> None

Apply a sqrt(X) gate to each target qubit.

Full docstring

Apply a sqrt(X) gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

truncatebool

See TruncatingCliffordMixin.x.

methodsqrt_x_dagppvm.mixins.TruncatingCliffordExtensionMixin.sqrt_x_dag
sqrt_x_dag(targets = (), truncate: bool = True) -> None

Apply a sqrt(X) adjoint gate to each target qubit.

Full docstring

Apply a sqrt(X) adjoint gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

truncatebool

See TruncatingCliffordMixin.x.

methodsqrt_yppvm.mixins.TruncatingCliffordExtensionMixin.sqrt_y
sqrt_y(targets = (), truncate: bool = True) -> None

Apply a sqrt(Y) gate to each target qubit.

Full docstring

Apply a sqrt(Y) gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

truncatebool

See TruncatingCliffordMixin.x.

methodsqrt_y_dagppvm.mixins.TruncatingCliffordExtensionMixin.sqrt_y_dag
sqrt_y_dag(targets = (), truncate: bool = True) -> None

Apply a sqrt(Y) adjoint gate to each target qubit.

Full docstring

Apply a sqrt(Y) adjoint gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

truncatebool

See TruncatingCliffordMixin.x.

methodcnotppvm.mixins.TruncatingCliffordMixin.cnot
cnot(targets = (), truncate: bool = True) -> None

Apply CNOT (controlled-X) gates over consecutive control/target pairs.

Full docstring

Apply CNOT (controlled-X) gates over consecutive control/target pairs.

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

truncatebool

See x.

methodczppvm.mixins.TruncatingCliffordMixin.cz
cz(targets = (), truncate: bool = True) -> None

Apply CZ (controlled-Z) gates over consecutive qubit pairs.

Full docstring

Apply CZ (controlled-Z) gates over consecutive qubit pairs.

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

truncatebool

See x.

methodhppvm.mixins.TruncatingCliffordMixin.h
h(targets = (), truncate: bool = True) -> None

Apply a Hadamard gate to each target qubit.

Full docstring

Apply a Hadamard gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

truncatebool

See x.

methodsppvm.mixins.TruncatingCliffordMixin.s
s(targets = (), truncate: bool = True) -> None

Apply an S gate (sqrt(Z)) to each target qubit.

Full docstring

Apply an S gate (sqrt(Z)) to each target qubit.

Parameters
*targets

The indices of the target qubits.

truncatebool

See x.

methodxppvm.mixins.TruncatingCliffordMixin.x
x(targets = (), truncate: bool = True) -> None

Apply a Pauli X gate to each target qubit.

Full docstring

Apply a Pauli X gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

truncatebool

If True (default), run the configured truncation strategy after the gate; if False, leave the map untruncated so the next gate sees the full unpruned state.

methodyppvm.mixins.TruncatingCliffordMixin.y
y(targets = (), truncate: bool = True) -> None

Apply a Pauli Y gate to each target qubit.

Full docstring

Apply a Pauli Y gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

truncatebool

See x.

methodzppvm.mixins.TruncatingCliffordMixin.z
z(targets = (), truncate: bool = True) -> None

Apply a Pauli Z gate to each target qubit.

Full docstring

Apply a Pauli Z gate to each target qubit.

Parameters
*targets

The indices of the target qubits.

truncatebool

See x.

methoddepolarize1ppvm.mixins.TruncatingNoiseMixin.depolarize1
depolarize1(args: Any = (), p = None, truncate: bool = True) -> None

Apply a single-qubit depolarizing channel to each target qubit.

Full docstring

Apply a single-qubit depolarizing channel to each target qubit.

Parameters
*targets

The indices of the target qubits.

p

The depolarizing probability.

truncatebool

See pauli_error.

methoddepolarize2ppvm.mixins.TruncatingNoiseMixin.depolarize2
depolarize2(args: Any = (), p = None, truncate: bool = True) -> None

Apply a two-qubit depolarizing channel over consecutive qubit pairs.

Full docstring

Apply a two-qubit depolarizing channel over consecutive qubit pairs.

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

p

The depolarizing probability.

truncatebool

See pauli_error.

methodpauli_errorppvm.mixins.TruncatingNoiseMixin.pauli_error
pauli_error(args: Any = (), p = None, truncate: bool = True) -> None

Apply a single-qubit Pauli error channel to each target qubit.

Full docstring

Apply a single-qubit Pauli error channel to each target qubit.

Parameters
*targets

The indices of the target qubits.

p

Error probabilities [p_x, p_y, p_z] for X, Y, Z errors. The identity probability is implicitly 1 - sum(p).

truncatebool

If True (default), run the configured truncation strategy after the channel; if False, defer it.

methodtwo_qubit_pauli_errorppvm.mixins.TruncatingNoiseMixin.two_qubit_pauli_error
two_qubit_pauli_error(args: Any = (), p = None, truncate: bool = True) -> None

Apply a two-qubit Pauli error channel over consecutive qubit pairs.

Full docstring

Apply a two-qubit Pauli error channel over consecutive qubit pairs.

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

p

Error probabilities for the 15 non-identity two-qubit Pauli operators. Use two_qubit_pauli_error_probabilities to convert from a dictionary format.

truncatebool

See pauli_error.

methodx_errorppvm.mixins.TruncatingNoiseMixin.x_error
x_error(args: Any = (), p = None, truncate: bool = True) -> None

Apply an X error channel to each target qubit.

Full docstring

Apply an X error channel to each target qubit.

Parameters
*targets

The indices of the target qubits.

p

The probability of applying an X error.

truncatebool

See pauli_error.

methody_errorppvm.mixins.TruncatingNoiseMixin.y_error
y_error(args: Any = (), p = None, truncate: bool = True) -> None

Apply a Y error channel to each target qubit.

Full docstring

Apply a Y error channel to each target qubit.

Parameters
*targets

The indices of the target qubits.

p

The probability of applying a Y error.

truncatebool

See pauli_error.

methodz_errorppvm.mixins.TruncatingNoiseMixin.z_error
z_error(args: Any = (), p = None, truncate: bool = True) -> None

Apply a Z error channel to each target qubit.

Full docstring

Apply a Z error channel to each target qubit.

Parameters
*targets

The indices of the target qubits.

p

The probability of applying a Z error.

truncatebool

See pauli_error.

methodrppvm.mixins.TruncatingRotationsMixin.r
r(addr0: int, axis_angle: float, theta: float, truncate: bool = True) -> None

Apply a rotation about an axis in the X-Y plane to the specified qubit.

Full docstring

Apply a rotation about an axis in the X-Y plane to the specified qubit.

See RotationsMixin.r for the gate definition.

Parameters
addr0int

The index of the target qubit.

axis_anglefloat

The angle φ (in radians) of the rotation axis within the X-Y plane, measured from the X-axis.

thetafloat

The rotation angle in radians.

truncatebool

See rx.

methodrxppvm.mixins.TruncatingRotationsMixin.rx
rx(args: Any = (), theta = None, truncate: bool = True) -> None

Apply an RX rotation gate to each target qubit.

Full docstring

Apply an RX rotation gate to each target qubit.

See RotationsMixin.rx for the gate definition.

Parameters
*targets

The indices of the target qubits.

theta

The rotation angle in radians.

truncatebool

If True (default), run the configured truncation strategy after the gate; if False, defer it.

methodrxxppvm.mixins.TruncatingRotationsMixin.rxx
rxx(args: Any = (), theta = None, truncate: bool = True) -> None

Apply RXX (Ising XX) rotation gates over consecutive qubit pairs.

Full docstring

Apply RXX (Ising XX) rotation gates over consecutive qubit pairs.

See RotationsMixin.rxx for the gate definition.

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

theta

The rotation angle in radians.

truncatebool

If True (default), run the configured truncation strategy after the gate. Set to False to compose a U(1)-conserving step like rxx + ryy on the same edge without dropping the conserved-charge component between them — then call PauliSum.truncate once at the end of the composition.

methodryppvm.mixins.TruncatingRotationsMixin.ry
ry(args: Any = (), theta = None, truncate: bool = True) -> None

Apply an RY rotation gate to each target qubit.

Full docstring

Apply an RY rotation gate to each target qubit.

See RotationsMixin.ry for the gate definition.

Parameters
*targets

The indices of the target qubits.

theta

The rotation angle in radians.

truncatebool

See rx.

methodryyppvm.mixins.TruncatingRotationsMixin.ryy
ryy(args: Any = (), theta = None, truncate: bool = True) -> None

Apply RYY (Ising YY) rotation gates over consecutive qubit pairs.

Full docstring

Apply RYY (Ising YY) rotation gates over consecutive qubit pairs.

See RotationsMixin.ryy for the gate definition.

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

theta

The rotation angle in radians.

truncatebool

See rxx.

methodrzppvm.mixins.TruncatingRotationsMixin.rz
rz(args: Any = (), theta = None, truncate: bool = True) -> None

Apply an RZ rotation gate to each target qubit.

Full docstring

Apply an RZ rotation gate to each target qubit.

See RotationsMixin.rz for the gate definition.

Parameters
*targets

The indices of the target qubits.

theta

The rotation angle in radians.

truncatebool

See rx.

methodrzzppvm.mixins.TruncatingRotationsMixin.rzz
rzz(args: Any = (), theta = None, truncate: bool = True) -> None

Apply RZZ (Ising ZZ) rotation gates over consecutive qubit pairs.

Full docstring

Apply RZZ (Ising ZZ) rotation gates over consecutive qubit pairs.

See RotationsMixin.rzz for the gate definition.

Parameters
*targets

A flat list of qubit indices, broadcast as pairs.

theta

The rotation angle in radians.

truncatebool

See rxx.

paulisum

classLossyPauliSumppvm.paulisum.LossyPauliSum
class LossyPauliSum

A PauliSum that supports modelling qubit loss.

Full docstring

A PauliSum that supports modelling qubit loss.

This is achieved by extending the set of Pauli basis operators to include an addition operator {I, X, Y, Z, L}, where L is the projector on a third leakage state. This basis effectively allows simulating qutrits, where we neglect any coherences between the qubit subspace and the leakage state.

In addition to the new channels, there is also another truncation strategy: Since Pauli Strings that have an L at multiple positions contribute only minimally, these can get truncated by setting an appropriate max_loss_weight. The truncation is similar to how max_pauli_weight truncates strings, but only counting Ls.

classPauliSumppvm.paulisum.PauliSum
class PauliSum

A weighted sum of Pauli strings for quantum simulation.

Full docstring

A weighted sum of Pauli strings for quantum simulation.

PauliSum represents a linear combination of Pauli operators, commonly used to represent quantum observables or Hamiltonians. It provides methods for applying quantum gates (Clifford operations and rotations) and computing expectation values via the trace operation.

methodcorrelated_loss_channelppvm.paulisum.LossyPauliSum.correlated_loss_channel
correlated_loss_channel(addr0: int, addr1: int, p, truncate: bool = True) -> None

Apply a correlated loss channel.

Full docstring

Apply a correlated loss channel.

This applies a correlated loss channel to the qubits at addr0 and addr1. The channel accepts 3 probabilities as argument: * p[0]: The probability of losing both qubits, when they are originally in the qubit subspace. * p[1]: The probability of losing a single qubit, when both qubits are originally in the qubit subspace. * p[2]: The probability of losing one qubit when the other one has already been lost prior to applying the channel. This is to account for the fact that when one qubit is missing during e.g. a controlled gate, the remaining qubit undergoes a different dynamic. We account for this difference with this distinct probability. truncate: If True (default), run the configured truncation strategy after the channel; if False, defer it.

methodloss_channelppvm.paulisum.LossyPauliSum.loss_channel
loss_channel(addr0: int, p: float, truncate: bool = True) -> None

Apply a single-qubit loss channel.

Full docstring

Apply a single-qubit loss channel.

Reduces the trace of qubit-subspace operators by (1 - p). Adds back population into I or Z if the Pauli string has an L at addr0. This can only occur if a reset channel has been applied before and accounts for the fact of falsely counting a lost qubit as 0 in a measurement.

Parameters
addr0int

The index of the target qubit.

pfloat

Loss probability in [0, 1].

truncatebool

If True (default), run the configured truncation strategy after the channel; if False, defer it.

methodreset_loss_channelppvm.paulisum.LossyPauliSum.reset_loss_channel
reset_loss_channel(addr0: int, truncate: bool = True) -> None

Reset a lost qubit to the 0 state. Usually, you want to apply this channel at the end of the circuit, i.e. at the beginning when propagating backwards.

Full docstring

Reset a lost qubit to the 0 state. Usually, you want to apply this channel at the end of the circuit, i.e. at the beginning when propagating backwards.

NOTE: This channel causes exponential branching in I and Z. Make sure to set an appropriate max_loss_weight to truncate.

Parameters
addr0int

The index of the qubit to reset.

truncatebool

If True (default), run the configured truncation strategy after the channel; if False, defer it.

methodamplitude_dampingppvm.paulisum.PauliSum.amplitude_damping
amplitude_damping(addr0: int, gamma: float, truncate: bool = True)

Apply an amplitude-damping channel.

Full docstring

Apply an amplitude-damping channel.

Parameters
addr0int

The index of the target qubit.

gammafloat

The damping rate. X and Y are damped with sqrt(1 - gamma), whereas Z branches into gamma * I + (1 - gamma) * Z.

truncatebool

If True (default), run the configured truncation strategy after the channel; if False, defer it (use truncate to fire the cut later).

methodcopyppvm.paulisum.PauliSum.copy
copy() -> Self

Create a copy of the PauliSum instance.

Full docstring

Create a copy of the PauliSum instance.

Returns
Self

A new PauliSum instance that is a copy of the current one.

methodcurrent_max_weightppvm.paulisum.PauliSum.current_max_weight
current_max_weight() -> int

Get the current maximum weight of the Pauli sum.

Full docstring

Get the current maximum weight of the Pauli sum.

Returns
int

The weight as integer.

methodnewppvm.paulisum.PauliSum.new
new(cls, n_qubits: int, terms, min_abs_coeff: float = 1e-10, max_pauli_weight = None, max_loss_weight = None, preserve_strings = None) -> Self

Create a PauliSum from one or more terms with flexible input formats.

Full docstring

Create a PauliSum from one or more terms with flexible input formats.

Parameters
n_qubitsint

Number of qubits.

terms

A single term or list of terms. Each term is either:

  • A full Pauli string (e.g. "IX"), with coefficient 1.0.
  • A compact string "P{i}" (e.g. "X1"), placing Pauli P at 0-based qubit index i with coefficient 1.0.
  • A tuple (str, float) pairing either of the above with an explicit coefficient.
min_abs_coefffloat

Terms with absolute coefficient below this threshold are dropped. Defaults to 1e-10.

max_pauli_weight

Maximum number of non-identity Paulis per term. If None, truncation is disabled.

max_loss_weight

Maximum loss weight per term (only used by LossyPauliSum). If None, truncation is disabled. Note, that this should usually be chosen to be quite low, since e.g. 10 would correspond to keeping terms that contribute if up to 10 qubits are lost simultaneously.

preserve_strings

Pauli strings (length n_qubits each) that truncation must never drop. Empty by default.

Returns
Self

A new instance of the class this method is called on.

Raises
ValueError

If a compact qubit index is out of range for n_qubits.

methodoverlapppvm.paulisum.PauliSum.overlap
overlap(other: PauliSum) -> float

Compute the overlap of the current PauliSum with another PauliSum. The overlap is defined as

Full docstring

Compute the overlap of the current PauliSum with another PauliSum. The overlap is defined as

math \text{tr}(A^\dagger \cdot B),

where self -> A other -> B

Returns
float

The trace overlap of the PauliSums.

methodoverlap_with_zeroppvm.paulisum.PauliSum.overlap_with_zero
overlap_with_zero() -> float

Compute the overlap with the all-zeros computational basis state.

Full docstring

Compute the overlap with the all-zeros computational basis state.

Returns
float

The expectation value of the Pauli sum with respect to |0...0>.

methodtraceppvm.paulisum.PauliSum.trace
trace(pattern: str) -> float

Compute the trace using a pattern string.

Full docstring

Compute the trace using a pattern string.

Parameters
patternstr

A pattern specifying which terms to include in the trace. Use 'Z' to project onto |0>, '?' for any single character, and '*' to match zero or more characters.

Returns
float

The trace result.

methodtruncateppvm.paulisum.PauliSum.truncate
truncate() -> None

Run the configured truncation strategy (min_abs_coeff and/or max_pauli_weight) on the current state.

Full docstring

Run the configured truncation strategy (min_abs_coeff and/or max_pauli_weight) on the current state.

Useful when gates were called with truncate=False to chain a composition of commuting operations (e.g. rxx + ryy on the same edge, an exchange-like step that conserves total Z), so that intermediate truncation does not drop conserved-charge components. Call truncate once at the end of the composition to apply the cut to the combined result.

methodweightsppvm.paulisum.PauliSum.weights
weights()

Get the weight of each Pauli term.

Full docstring

Get the weight of each Pauli term.

Returns

A list of tuples, each containing a Pauli string and its weight.

attributetermsppvm.paulisum.PauliSum.terms
terms

Get the list of Pauli terms and their coefficients.

Full docstring

Get the list of Pauli terms and their coefficients.

Returns

A list of tuples, each containing a Pauli string and its coefficient.

squin_interpreter

modulesquin_interpreterppvm.squin_interpreter
module ppvm.squin_interpreter

TODO: once we open-source, all of this will be moved into bloqade-circuit

Rustcrates

ppvm-traits

Trait system, the `Config` bundle, the `Pauli` alphabet, and map impls.

moduleppvm_traitsppvm_traits
mod ppvm_traits

Foundational trait system, Config trait, single-qubit Pauli alphabet, and the ACMap/Trace map implementations shared across ppvm crates.

structNoStrategyppvm_traits::traits::strategy::NoStrategy
struct NoStrategy

Strategy that never truncates — exact simulation, all entries kept.

enumPaulippvm_traits::char::Pauli
enum Pauli

A single-qubit Pauli symbol.

Full docstring

A single-qubit Pauli symbol.

The four standard Paulis are encoded so that the low two bits identify the operator (I = 0b00, X = 0b01, Z = 0b10, Y = 0b11), which is the same encoding stabilizer-formalism tools commonly use. The extra variant Pauli::L marks a qubit as lost, used by the loss-aware portions of the runtime.

Examples

use ppvm_traits::char::Pauli;

assert_eq!(Pauli::I.to_string(), "I");
assert_eq!(Pauli::X.to_string(), "X");
assert_eq!(Pauli::Y.to_string(), "Y");
assert_eq!(Pauli::Z.to_string(), "Z");
assert_eq!(Pauli::L.to_string(), "L");
traitConfigppvm_traits::config::Config
trait Config

Compile-time configuration bundle for a PauliSum.

Full docstring

Compile-time configuration bundle for a PauliSum.

Config is a zero-cost generic dispatch mechanism: it pins down the storage backing (Storage), coefficient type (Coeff), truncation strategy (Strategy), hasher (BuildHasher), Pauli-word representation (PauliWordType), and concrete map (Map) used by a single PauliSum instantiation. Pre-built bundles live in the submodules (fxhash, indexmap, …); user code may define its own.

traitCRxppvm_traits::traits::branch::crx::CRx
trait CRx<T>

Controlled RX rotation.

traitProjectionppvm_traits::traits::branch::proj::Projection
trait Projection

Projective Z-basis projectors |0⟩⟨0| and |1⟩⟨1|.

traitRotationOneppvm_traits::traits::branch::rot1::RotationOne
trait RotationOne<T>

Single-qubit Pauli rotations exp(-i θ/2 · P).

traitRotXYppvm_traits::traits::branch::rot1::RotXY
trait RotXY<T>

Rotation about an axis in the x/y plane: R(axis_angle, θ) = exp(-i θ/2 · (cos(axis_angle)·X + sin(axis_angle)·Y)).

Full docstring

Rotation about an axis in the x/y plane: R(axis_angle, θ) = exp(-i θ/2 · (cos(axis_angle)·X + sin(axis_angle)·Y)).

The in-plane axis is X rotated about Z by axis_angle, so R(axis_angle, θ) = RZ(axis_angle)·RX(θ)·RZ(−axis_angle).

traitRotationTwoppvm_traits::traits::branch::rot2::RotationTwo
trait RotationTwo<T>

Two-qubit Pauli rotations, generated by P_a ⊗ P_b for any pair of non-identity Paulis. Provides the named convenience methods rxx, rxy, …, rzz on top of the generic [rotate_2].

Full docstring

Two-qubit Pauli rotations, generated by P_a ⊗ P_b for any pair of non-identity Paulis. Provides the named convenience methods rxx, rxy, …, rzz on top of the generic rotate_2.

traitTGateppvm_traits::traits::branch::tgate::TGate
trait TGate<T>

The non-Clifford T gate and its adjoint.

Full docstring

The non-Clifford T gate and its adjoint.

T = diag(1, e^{iπ/4}). Implemented by the simulator backends; see the example in ppvm_tableau.

traitU3Gateppvm_traits::traits::branch::u3::U3Gate
trait U3Gate<T>

The general single-qubit U3(θ, φ, λ) gate.

traitCliffordppvm_traits::traits::clifford::Clifford
trait Clifford

The minimal Clifford gate set: the single-qubit Paulis (X, Y, Z), Hadamard (H), phase gate (S), and the two entangling Cliffords CNOT and CZ.

Full docstring

The minimal Clifford gate set: the single-qubit Paulis (X, Y, Z), Hadamard (H), phase gate (S), and the two entangling Cliffords CNOT and CZ.

Implemented by PauliSum, by every tableau type, and — via the blanket impl in this module — by every PauliWordTrait implementor.

Examples

Build the GHZ-preparation circuit on a PauliSum (Heisenberg picture, so gates are applied in reverse). PauliSum lives in the downstream ppvm-pauli-sum crate, so this example is ignored here:

use ppvm_pauli_sum::prelude::*;

let mut state: PauliSum<config::indexmap::ByteFxHashF64<1>> =
    PauliSum::builder().n_qubits(2).build();
state += ("ZZ", 1.0);
state.cnot(0, 1);
state.h(0);
assert_eq!(state.len(), 1);
traitCliffordBatchppvm_traits::traits::clifford::CliffordBatch
trait CliffordBatch

Batched Clifford gates: apply the same gate to many qubits in one call.

Full docstring

Batched Clifford gates: apply the same gate to many qubits in one call.

Default implementations loop over the corresponding single-qubit (or single-pair) method on Clifford. Types like the stabilizer Tableau override these methods with a fused inner-loop or bitmask implementation. Types that don't need specialization can implement this trait with an empty impl to use the defaults.

traitCliffordExtensionsppvm_traits::traits::clifford::CliffordExtensions
trait CliffordExtensions

Additional Clifford gates beyond the minimal set: S†, √X, √X†, √Y, √Y†, and CY.

traitCoefficientppvm_traits::traits::coefficient::Coefficient
trait Coefficient

Numeric coefficient type usable inside a PauliSum.

Full docstring

Numeric coefficient type usable inside a PauliSum.

Coefficient bundles every arithmetic operation a Pauli-propagation step needs — addition, multiplication, signed multiplication, half, sin/cos, and a cutoff predicate used by truncation strategies. The built-in f64 impl covers the common case; Complex<f64> is available when phase tracking is required.

traitComplexCoefficientppvm_traits::traits::coefficient::ComplexCoefficient
trait ComplexCoefficient

A Coefficient extended with multiplication by a fourth-root-of-unity phase. Used by PhasedPauliWord.

traitHashFinalizeppvm_traits::traits::hash::HashFinalize
trait HashFinalize

Post-processing that a PauliWord's hasher applies to its raw 64-bit digest before it is cached as the map-key hash.

Full docstring

Post-processing that a PauliWord's hasher applies to its raw 64-bit digest before it is cached as the map-key hash.

The cached value is what hashbrown ultimately splits into a bucket index (low bits) and a control-byte tag (top 7 bits). Whether the raw digest is good enough for that split is a property of the hasher, not of the Pauli word: an AES-based hasher such as gxhash avalanches well even for an 8-byte key, whereas FxHasher — a couple of multiply-rotate rounds — leaves the low bits of a short key highly correlated and needs a fold to fix them.

Keeping this on the hasher is what makes the abstraction correct. An earlier version folded based on storage width alone, which conflated "narrow storage" with "weak hasher" and so wrongly folded gxhash too. Here each hasher declares how (if at all) its output must be adjusted, and PauliWord::rehash just defers to it. The default is the identity — the right choice for any hasher that already distributes its low bits well — so a custom hasher opts in with a bare impl HashFinalize for MyHasher {}.

traitACMapppvm_traits::traits::map::ACMap
trait ACMap<S, V, H, W>

Aggregate trait combining every operation a backing map must support to be usable as the storage for a PauliSum.

Full docstring

Aggregate trait combining every operation a backing map must support to be usable as the storage for a PauliSum.

You don't normally implement ACMap directly: the blanket impl below covers any type that implements all the constituent traits.

traitACMapAddAssignppvm_traits::traits::map::ACMapAddAssign
trait ACMapAddAssign<S, V, H, W>

+= semantics for an ACMap: insert a new entry or accumulate into the existing one with the same key.

traitACMapBaseppvm_traits::traits::map::ACMapBase
trait ACMapBase

Minimal interface for any "associative coefficient map" backing a PauliSum — construction, length, and clear.

Full docstring

Minimal interface for any "associative coefficient map" backing a PauliSum — construction, length, and clear.

Implementations exist for HashMap, IndexMap, and DashMap; pick one via a Config.

traitACMapConsumeppvm_traits::traits::map::ACMapConsume
trait ACMapConsume

Merge two maps with accumulation: drain dest into self, summing values that share a key.

traitACMapContainsppvm_traits::traits::map::ACMapContains
trait ACMapContains<S, V, H, W>

Membership queries — (key, value) exact match or with a custom predicate on the value.

traitACMapInsertppvm_traits::traits::map::ACMapInsert
trait ACMapInsert<S, V, H, W>

Combined in-place modify + insert pattern used to express branching gates (where one input entry can produce several output entries).

traitACMapIterppvm_traits::traits::map::ACMapIter
trait ACMapIter<'a>

Borrowing iteration over an ACMap. Lives in its own trait so that implementations may pick their own item / iterator types.

traitACMapMulAssignppvm_traits::traits::map::ACMapMulAssign
trait ACMapMulAssign<V, H>

Scalar *= semantics for an ACMap: multiply every value by a constant.

traitACMapRetainppvm_traits::traits::map::ACMapRetain
trait ACMapRetain<S, V, H, W>

Drop entries that don't satisfy a predicate — used by truncation strategies.

traitACMapScaleppvm_traits::traits::map::ACMapScale
trait ACMapScale<S, V, H, W>

In-place per-entry transformation of values.

traitLossyMeasureppvm_traits::traits::measure::LossyMeasure
trait LossyMeasure

Loss-aware Z-basis measurement.

traitMeasureppvm_traits::traits::measure::Measure
trait Measure

Projective Z-basis measurement returning a bare boolean outcome.

traitAmplitudeDampingppvm_traits::traits::noise::AmplitudeDamping
trait AmplitudeDamping<T>

Amplitude-damping channel (single qubit).

traitAsymmetricLossChannelppvm_traits::traits::noise::AsymmetricLossChannel
trait AsymmetricLossChannel<T>

State-dependent ("asymmetric") single-qubit loss channel: a qubit is lost from |0⟩ with probability p0 and from |1⟩ with probability p1. Unlike LossChannel, the total loss probability depends on the qubit's populations, so th…

Full docstring

State-dependent ("asymmetric") single-qubit loss channel: a qubit is lost from |0⟩ with probability p0 and from |1⟩ with probability p1. Unlike LossChannel, the total loss probability depends on the qubit's populations, so the channel reads the current ⟨Z⟩.

traitCorrelatedLossChannelppvm_traits::traits::noise::CorrelatedLossChannel
trait CorrelatedLossChannel<T>

Correlated two-qubit loss channel.

traitDepolarizingppvm_traits::traits::noise::Depolarizing
trait Depolarizing<T>

Single-qubit depolarizing channel.

traitDepolarizing2ppvm_traits::traits::noise::Depolarizing2
trait Depolarizing2<T>

Two-qubit depolarizing channel.

traitLossChannelppvm_traits::traits::noise::LossChannel
trait LossChannel<T>

Single-qubit loss channel — with probability p, mark the qubit as lost (Pauli::L).

traitPauliErrorppvm_traits::traits::noise::PauliError
trait PauliError<T>

Single-qubit Pauli error channel — apply X, Y, or Z with the three given probabilities.

traitPauliErrorAllppvm_traits::traits::noise::PauliErrorAll
trait PauliErrorAll<T>

Apply the same single-qubit Pauli error channel uniformly to every qubit in the system.

traitResetLossChannelppvm_traits::traits::noise::ResetLossChannel
trait ResetLossChannel<T>

Reset the loss bit on a qubit — used to model a re-cooling / re-loading event that brings a previously-lost atom back.

traitTwoQubitPauliErrorppvm_traits::traits::noise::TwoQubitPauliError
trait TwoQubitPauliError<T>

Two-qubit Pauli error channel.

traitResetppvm_traits::traits::reset::Reset
trait Reset

Reset one qubit to a computational/Pauli basis state.

traitPauliStorageppvm_traits::traits::storage::PauliStorage
trait PauliStorage

Backing storage for a PauliWord — a fixed-size, Copy-able block of bits (typically [u8; N] or [u64; N]).

Full docstring

Backing storage for a PauliWord — a fixed-size, Copy-able block of bits (typically [u8; N] or [u64; N]).

The bytemuck::Pod bound guarantees the storage is a plain-old-data type with no padding and all bit patterns valid, which lets PauliWord::rehash view it as a &[u8] for fast byte-slice hashing without unsafe. Every concrete storage used here ([u8; N], [u64; N]) is already Pod.

traitStrategyppvm_traits::traits::strategy::Strategy
trait Strategy

A truncation policy applied to a PauliSum during Pauli propagation.

Full docstring

A truncation policy applied to a PauliSum during Pauli propagation.

The strategy controls two things: the initial capacity allocated for the underlying map (estimating how many Pauli paths the simulation is expected to generate) and the cut applied when truncate is called explicitly. Implementations include NoStrategy, the coefficient-magnitude threshold, the max-Pauli-weight bound, etc.

traitTraceppvm_traits::traits::trace::Trace
trait Trace<'a, RHS>

Trait for computing trace(self * RHS).

Full docstring

Trait for computing trace(self * RHS).

If a type implements Trace, a corresponding TraceBy implementation is also provided automatically.

traitPauliIterppvm_traits::traits::word_trait::PauliIter
trait PauliIter

Iterate over a Pauli word slot-by-slot.

traitPauliWordTraitppvm_traits::traits::word_trait::PauliWordTrait
trait PauliWordTrait

Word-level Pauli operations. Types implementing this trait automatically gain crate::traits::Clifford and crate::traits::CliffordExtensions behavior via blanket impls in the crate::traits::clifford module, using get_lbit / `g…

Full docstring

Word-level Pauli operations. Types implementing this trait automatically gain crate::traits::Clifford and crate::traits::CliffordExtensions behavior via blanket impls in the crate::traits::clifford module, using get_lbit / get_xbit / set_xbit / set_zbit / rehash to transform Pauli words.

Word-level vs. state-level gate semantics

The blanket Clifford impl applies gates at the bit level of a single Pauli word. X / Y / Z are bit-level no-ops on a Pauli word — they affect phase, not the X/Z bits — so word.x(i), word.y(i), word.z(i) are deliberately silent. Phase is tracked separately by PhasedPauliWord, which implements Clifford manually.

If you need a word representation whose gate behavior is not pure bit manipulation (phase tracking, fused multi-qubit updates, alternative loss semantics), do not implement PauliWordTrait on it — define a specialized Clifford impl instead, the way PhasedPauliWord does. Implementing both PauliWordTrait and a custom impl Clifford for ... for the same type will not compile: the blanket impl overlaps with your custom impl (coherence error), not silently shadows it.

ppvm-pauli-word

Packed Pauli strings: `PauliWord`, phased, lossy, and pattern variants.

moduleppvm_pauli_wordppvm_pauli_word
mod ppvm_pauli_word

Packed Pauli-word types: PauliWord, PhasedPauliWord, LossyPauliWord, and PauliPattern. Built on the ppvm-traits foundation.

structLossyPauliWordppvm_pauli_word::loss::data::LossyPauliWord
struct LossyPauliWord<A, S>

A PauliWord-like type that additionally tracks per-qubit loss.

Full docstring

A PauliWord-like type that additionally tracks per-qubit loss.

In neutral-atom hardware (and in any loss-aware error model), a measurement can return "lost" instead of 0 or 1. LossyPauliWord adds a parallel lbits array marking which qubits have been lost; a set loss bit excludes that qubit from the standard Pauli operations and shows up as the [Pauli::L] symbol.

Examples

use ppvm_traits::char::Pauli;
use ppvm_pauli_word::loss::LossyPauliWord;
use ppvm_traits::traits::PauliWordTrait;

let w: LossyPauliWord<[u8; 1]> = "XLZL".into();
assert_eq!(w.weight(), 4);          // X, L, Z, L are all non-identity
assert_eq!(w.loss_weight(), 2);     // two qubits are lost
assert!(w.is(1, Pauli::L));
assert!(w.is(0, Pauli::X));
structPauliPatternppvm_pauli_word::pattern::data::PauliPattern
struct PauliPattern

A Pauli pattern representing a set of matching Pauli words.

Full docstring

A Pauli pattern representing a set of matching Pauli words.

Example

[XY]2Z3 represents X2Z3 or Y2Z3. Z? represents any Pauli word with I or Z.

structEnumMatchesPauliPatternppvm_pauli_word::pattern::enumerate::EnumMatchesPauliPattern
struct EnumMatchesPauliPattern<'a, A>

Iterator over the concrete [PauliWord]s accepted by a [PauliPattern].

structPhasedPauliWordppvm_pauli_word::phase::data::PhasedPauliWord
struct PhasedPauliWord<A, H, W>

A PauliWord paired with one of the four fourth-roots of unity.

Full docstring

A PauliWord paired with one of the four fourth-roots of unity.

The phase field encodes the scalar prefactor:

phase scalar
0 +1
1 +i
2 -1
3 -i

(i.e. the low bit is the imaginary flag and the high bit is the sign.)

Examples

use ppvm_pauli_word::phase::PhasedPauliWord;

// Parse from a "[sign][i]<PauliString>" literal.
let pw: PhasedPauliWord<u64> = "+iXYZI".into();
assert_eq!(pw.n_qubits(), 4);
assert_eq!(pw.phase, 1);            // +i
assert!(pw.is_positive());

let neg: PhasedPauliWord<u64> = "-XYZI".into();
assert_eq!(neg.phase, 2);           // -1
assert!(!neg.is_positive());
structPauliWordppvm_pauli_word::word::data::PauliWord
struct PauliWord<A, S, REHASH>

A fixed-width Pauli string stored as parallel x and z bit arrays.

Full docstring

A fixed-width Pauli string stored as parallel x and z bit arrays.

Each qubit slot is encoded by two bits, (x, z), giving the four Pauli operators I = (0,0), X = (1,0), Z = (0,1), Y = (1,1) — the same encoding stabilizer-formalism tools use. The bit arrays live in a single PauliStorage blob (typically [u8; N] or [u64; N]), so a PauliWord<[u8; 1]> packs up to 8 qubits, [u8; 2] up to 16, etc.

A cached hash speeds up use as a map key; pass REHASH = false if you build words in bulk and want to control rehashing manually.

Examples

use ppvm_traits::char::Pauli;
use ppvm_traits::traits::PauliWordTrait;
use ppvm_pauli_word::word::PauliWord;

// Build a word from a string …
let w: PauliWord<[u8; 1]> = "XYZI".into();
assert_eq!(w.n_qubits(), 4);
assert_eq!(w.get(0), Pauli::X);
assert_eq!(w.get(3), Pauli::I);

// … or build it slot-by-slot.
let mut w2: PauliWord<[u8; 1]> = PauliWord::new(2);
w2.set(0, Pauli::X).set(1, Pauli::Y);
assert_eq!(w2.to_string(), "XY");
assert_eq!(w2.weight(), 2);
enumNotIdentityppvm_pauli_word::pattern::data::NotIdentity
enum NotIdentity

A single-qubit Pauli that is not the identity: X, Y, or Z. Encoded so the low two bits match Pauli (X = 1, Z = 2, Y = 3), which lets From<NotIdentity> for Pauli be a no-op transmute.

traitContainsppvm_pauli_word::pattern::contains::Contains
trait Contains<T>

Membership test for pattern types.

Full docstring

Membership test for pattern types.

Implemented by Pauli patterns over symbols (Contains<Pauli>) and over whole words (Contains<W: PauliIter>); used by the masking machinery to ask "does this pattern accept this concrete word?"

ppvm-pauli-sum

The `PauliSum` engine, truncation strategies, and concrete config bundles.

moduleppvm_pauli_sumppvm_pauli_sum
mod ppvm_pauli_sum

PauliSum / LossyPauliSum Pauli-propagation engine, truncation strategies, and pre-built Config bundles. Built on ppvm-traits and ppvm-pauli-word.

moduledashmapppvm_pauli_sum::config::dashmap
mod dashmap

Pre-built configs backed by dashmap::DashMap for concurrent access. Native-only: dashmap pulls rayon, which needs OS threads, so this module is unavailable on wasm32.

modulefx64hashppvm_pauli_sum::config::fx64hash
mod fx64hash

Pre-built configs using rustc-hash's FxHasher and f64 coefficients.

modulefxhashppvm_pauli_sum::config::fxhash
mod fxhash

Pre-built configs using FxHasher.

modulegxhashppvm_pauli_sum::config::gxhash
mod gxhash

Pre-built configs using gxhash — fast on platforms with AES hardware acceleration. Requires the gxhash feature.

moduleindexmapppvm_pauli_sum::config::indexmap
mod indexmap

Pre-built configs backed by indexmap::IndexMap, preserving insertion order — useful for deterministic iteration and snapshot testing.

modulepreludeppvm_pauli_sum::prelude
mod prelude

Drop-in replacement for the old ppvm_runtime::prelude.

structByteFxHashppvm_pauli_sum::config::dashmap::ByteFxHash
struct ByteFxHash<N, C, St, W>

DashMap-backed concurrent Config with [u8; N] storage and FxHasher.

structByteGxHashppvm_pauli_sum::config::dashmap::ByteGxHash
struct ByteGxHash<N, C, St, W>

DashMap-backed concurrent Config with [u8; N] storage and gxhash.

structByte8ppvm_pauli_sum::config::fx64hash::Byte8
struct Byte8<N, C, St, W>

HashMap-backed Config with native-word ([usize; N]) storage and FxHasher.

Full docstring

HashMap-backed Config with native-word ([usize; N]) storage and FxHasher.

The storage element is usize, i.e. the target's native machine word: u64 on 64-bit targets (identical layout and performance to a hardcoded [u64; N]) and u32 on 32-bit targets such as wasm32. Using usize rather than u64 keeps this config available on every target — bitvec only implements BitStore for u64 on 64-bit pointer widths, but always implements it for usize. (The Byte8 name refers to the 64-bit word this config packs into on native targets.)

structByteppvm_pauli_sum::config::fxhash::Byte
struct Byte<N, C, St, W>

HashMap-backed Config with [u8; N] storage and FxHasher.

structByteppvm_pauli_sum::config::gxhash::Byte
struct Byte<N, C, St, W>

HashMap-backed Config with [u8; N] storage and gxhash.

structByteFxHashppvm_pauli_sum::config::indexmap::ByteFxHash
struct ByteFxHash<N, C, St, W>

IndexMap-backed Config with [u8; N] storage and FxHasher.

structByteGxHashppvm_pauli_sum::config::indexmap::ByteGxHash
struct ByteGxHash<N, C, St, W>

IndexMap-backed Config with [u8; N] storage and gxhash.

Full docstring

IndexMap-backed Config with [u8; N] storage and gxhash.

gxhash is AES-based and native-only, so this config is unavailable on wasm32; use ByteFxHash there.

structCoefficientThresholdppvm_pauli_sum::strategy::CoefficientThreshold
struct CoefficientThreshold

Drop terms whose coefficient magnitude falls below the given threshold. Defaults to 1e-12.

Full docstring

Drop terms whose coefficient magnitude falls below the given threshold. Defaults to 1e-12.

Examples

use ppvm_pauli_sum::prelude::*;
use ppvm_pauli_sum::strategy::CoefficientThreshold;

let strict = CoefficientThreshold(1e-6);
let mut state: PauliSum<config::indexmap::ByteFxHashF64<1, CoefficientThreshold>> =
    PauliSum::builder().n_qubits(2).strategy(strict).build();
state += ("ZZ", 1.0);
state += ("XX", 1e-9);              // below threshold
state.truncate();
assert_eq!(state.len(), 1);         // the XX term was dropped
structCombinedStrategyppvm_pauli_sum::strategy::CombinedStrategy
struct CombinedStrategy<S1, S2>

Two strategies run in sequence: S1 then S2.

Full docstring

Two strategies run in sequence: S1 then S2.

The capacity hint is the smaller of the two; truncation applies both policies in order, so use this when you want, e.g., "drop by coefficient threshold and cap maximum Pauli weight".

structMaxLossWeightppvm_pauli_sum::strategy::MaxLossWeight
struct MaxLossWeight

Drop terms whose loss weight (number of lost qubits) exceeds the given bound. Only meaningful for LossyPauliWord.

structMaxPauliWeightppvm_pauli_sum::strategy::MaxPauliWeight
struct MaxPauliWeight

Drop terms whose Pauli weight (number of non-identity slots) exceeds the given bound.

Full docstring

Drop terms whose Pauli weight (number of non-identity slots) exceeds the given bound.

Examples

use ppvm_pauli_sum::prelude::*;
use ppvm_pauli_sum::strategy::MaxPauliWeight;

// Keep only weight-1 terms.
let strat = MaxPauliWeight(1);
let mut state: PauliSum<config::indexmap::ByteFxHashF64<1, MaxPauliWeight>> =
    PauliSum::builder().n_qubits(3).strategy(strat).build();
state += ("XII", 1.0);              // weight 1, kept
state += ("XYI", 1.0);              // weight 2, dropped
state.truncate();
assert_eq!(state.len(), 1);
structEmptyppvm_pauli_sum::sum::data::pauli_sum_builder::Empty
struct Empty

Represents a [State] that has [IsUnset] implemented for all members.

Full docstring

Represents a [State] that has [IsUnset] implemented for all members.

This is the initial state of the builder before any setters are called.

structSetCapacityppvm_pauli_sum::sum::data::pauli_sum_builder::SetCapacity
struct SetCapacity<S>

Represents a [State] that has [IsSet] implemented for [State::Capacity].

Full docstring

Represents a [State] that has [IsSet] implemented for [State::Capacity].

The state for all other members is left the same as in the input state.

structSetNQubitsppvm_pauli_sum::sum::data::pauli_sum_builder::SetNQubits
struct SetNQubits<S>

Represents a [State] that has [IsSet] implemented for [State::NQubits].

Full docstring

Represents a [State] that has [IsSet] implemented for [State::NQubits].

The state for all other members is left the same as in the input state.

structSetPreserveStringsppvm_pauli_sum::sum::data::pauli_sum_builder::SetPreserveStrings
struct SetPreserveStrings<S>

Represents a [State] that has [IsSet] implemented for [State::PreserveStrings].

Full docstring

Represents a [State] that has [IsSet] implemented for [State::PreserveStrings].

The state for all other members is left the same as in the input state.

structSetStrategyppvm_pauli_sum::sum::data::pauli_sum_builder::SetStrategy
struct SetStrategy<S>

Represents a [State] that has [IsSet] implemented for [State::Strategy].

Full docstring

Represents a [State] that has [IsSet] implemented for [State::Strategy].

The state for all other members is left the same as in the input state.

structPauliSumppvm_pauli_sum::sum::data::PauliSum
struct PauliSum<T>

A sparse formal sum Σ cᵢ Pᵢ of Pauli strings.

Full docstring

A sparse formal sum Σ cᵢ Pᵢ of Pauli strings.

The central data type of the Pauli-propagation backend. Keys are PauliWord-shaped Pauli strings; values are numeric coefficients. Generic over a Config that fixes the concrete storage / hasher / coefficient / strategy.

Internally PauliSum holds two maps — a primary and an auxiliary — and swaps between them during gate propagation to avoid repeated allocations. The [PauliSum::data] / [PauliSum::aux] accessors expose the current orientation; most callers will only ever touch the primary side via the high-level gate / measurement traits.

Examples

Heisenberg-picture propagation of ZZ through the GHZ circuit:

use ppvm_pauli_sum::prelude::*;

let mut state: PauliSum<config::indexmap::ByteFxHashF64<1>> =
    PauliSum::builder().n_qubits(2).build();
state += ("ZZ", 1.0);

// Circuit: H(0); CNOT(0, 1) — apply in reverse for Heisenberg propagation.
state.cnot(0, 1);
state.h(0);

// ZZ → IZ under the GHZ circuit, with coefficient 1.0.
assert_eq!(state.len(), 1);
structPauliSumBuilderppvm_pauli_sum::sum::data::PauliSumBuilder
struct PauliSumBuilder<T, S>

Use builder syntax to set the inputs and finish with build().

traitIsCompleteppvm_pauli_sum::sum::data::pauli_sum_builder::IsComplete
trait IsComplete

Marker trait that indicates that all required members are set.

Full docstring

Marker trait that indicates that all required members are set.

In this state, you can finish building by calling the method PauliSumBuilder::build()

traitStateppvm_pauli_sum::sum::data::pauli_sum_builder::State
trait State

Builder's type state specifies if members are set or not (unset).

Full docstring

Builder's type state specifies if members are set or not (unset).

You can use the associated types of this trait to control the state of individual members with the [IsSet] and [IsUnset] traits. You can change the state of the members with the Set* structs available in this module.

type aliasByteFxHashF64ppvm_pauli_sum::config::dashmap::ByteFxHashF64
type ByteFxHashF64

ByteFxHash specialised to f64 coefficients.

type aliasByteGxHashF64ppvm_pauli_sum::config::dashmap::ByteGxHashF64
type ByteGxHashF64

ByteGxHash specialised to f64 coefficients.

type aliasByte8F64ppvm_pauli_sum::config::fx64hash::Byte8F64
type Byte8F64

Byte8 specialised to f64 coefficients.

type aliasByteF64ppvm_pauli_sum::config::fxhash::ByteF64
type ByteF64

Byte specialised to f64 coefficients.

type aliasByteF64ppvm_pauli_sum::config::gxhash::ByteF64
type ByteF64

Byte specialised to f64 coefficients.

type aliasByteFxHashF64ppvm_pauli_sum::config::indexmap::ByteFxHashF64
type ByteFxHashF64

ByteFxHash specialised to f64 coefficients.

type aliasByteGxHashF64ppvm_pauli_sum::config::indexmap::ByteGxHashF64
type ByteGxHashF64

ByteGxHash specialised to f64 coefficients.

macroimpl_op_mul_assign_coefficientppvm_pauli_sum::impl_op_mul_assign_coefficient
impl_op_mul_assign_coefficient!

Implement multiplication by a scalar coefficient for PauliSum. Use this macro to implement MulAssign for other scalar types if needed. This macro will forward the multiplication to the underlying map's mul_assign method.

ppvm-tableau

Generalized stabilizer tableau simulator (Clifford + non-Clifford).

moduleppvm_tableauppvm_tableau
mod ppvm_tableau

Generalized stabilizer-tableau simulator built on top of the ppvm core crates (ppvm-traits and ppvm-pauli-word).

Full docstring

Generalized stabilizer-tableau simulator built on top of the ppvm core crates (ppvm-traits and ppvm-pauli-word).

Provides a forward-evolving state representation using the stabilizer formalism, extended to non-Clifford gates by tracking a sparse vector of coefficients indexed over bitstrings. The two top-level types are data::Tableau (pure Clifford) and data::GeneralizedTableau (Clifford + non-Clifford with sparse coefficient tracking).

Quick example

Prepare a Bell pair and verify the two measurements are perfectly correlated:

use ppvm_tableau::prelude::*;
use ppvm_pauli_sum::config::fxhash::ByteF64;

let mut tab: GeneralizedTableau<ByteF64<1>> =
    GeneralizedTableau::new_with_seed(2, 1e-12, 0);
tab.h(0);
tab.cnot(0, 1);

let r0 = LossyMeasure::measure(&mut tab, 0);
let r1 = LossyMeasure::measure(&mut tab, 1);
assert_eq!(r0, r1);
moduledisplayppvm_tableau::display
mod display

Display implementations for tableau types.

moduleexpectationppvm_tableau::expectation
mod expectation

Pauli-string expectation values and pattern traces. Pauli-string expectation values for GeneralizedTableau.

Full docstring

Pauli-string expectation values and pattern traces. Pauli-string expectation values for GeneralizedTableau.

Two entry points:

  • [GeneralizedTableau::expectation] — single-Pauli ⟨ψ|P|ψ⟩ for a PauliWord. Conjugates P through the tableau and overlaps the resulting Pauli with the sparse coefficient vector using the same formulas as the measurement code.
  • [GeneralizedTableau::trace] — Σ_{P matches pattern} ⟨ψ|P|ψ⟩ for a PauliPattern. Enumerates the matching Paulis and sums their expectations.

Decision 9 in the multi-backend plan calls these out as the natural primitive for the tableau backend; semantics intentionally diverge from the PauliSum trace.

modulegatesppvm_tableau::gates
mod gates

Gate implementations (Clifford, T, rotations).

modulemeasureppvm_tableau::measure
mod measure

Z-basis measurement, including loss-aware variants.

modulenoiseppvm_tableau::noise
mod noise

Noise channels: depolarizing, Pauli error, loss.

modulepreludeppvm_tableau::prelude
mod prelude

Convenience re-exports for downstream code.

moduletableau_indexppvm_tableau::tableau_index
mod tableau_index

TableauIndex — abstraction over the bitstring index type (usize, u128, U256, …).

moduletableau_likeppvm_tableau::tableau_like
mod tableau_like

TableauLike — shared trait for stabilizer-tableau backends. TableauLike trait: shared interface for stabilizer-tableau backends.

Full docstring

TableauLike — shared trait for stabilizer-tableau backends. TableauLike trait: shared interface for stabilizer-tableau backends.

Any type implementing TableauLike gets default implementations of single- and two-qubit Pauli noise channels (Depolarizing, PauliError, Depolarizing2, TwoQubitPauliError). New tableau backends only need to provide TableauLike::rng_mut and (optionally) override TableauLike::is_qubit_lost.

structGeneralizedTableauppvm_tableau::data::GeneralizedTableau
struct GeneralizedTableau<T, IndexType, SparseVectorType>

A Tableau extended with sparse coefficient tracking to handle non-Clifford gates.

Full docstring

A Tableau extended with sparse coefficient tracking to handle non-Clifford gates.

Non-Clifford gates (T, rotations) split a single tableau into a sum of weighted branches indexed by bitstrings. GeneralizedTableau stores those weights in a SparseVector keyed by an IndexType. Choose:

  • IndexType = usize for up to 64 qubits,
  • IndexType = u128 for up to 128,
  • IndexType = bnum::types::U256 and friends for the very wide regime.

Per-qubit loss is tracked in is_lost; gates respect it automatically.

Examples

Prepare a Bell pair and sample one shot. With a fixed seed the two measurements are perfectly correlated on every shot:

use ppvm_pauli_sum::config::fxhash::ByteF64;
use ppvm_traits::traits::{Clifford, LossyMeasure};
use ppvm_tableau::data::GeneralizedTableau;

let mut tab: GeneralizedTableau<ByteF64<1>> =
    GeneralizedTableau::new_with_seed(2, 1e-12, 0);
tab.h(0);
tab.cnot(0, 1);

let r0 = LossyMeasure::measure(&mut tab, 0);
let r1 = LossyMeasure::measure(&mut tab, 1);
assert_eq!(r0, r1);

Non-Clifford gates work through the same interface — apply a T gate followed by T† and the state is unchanged:

use ppvm_pauli_sum::config::fxhash::ByteF64;
use ppvm_traits::traits::{Clifford, TGate};
use ppvm_tableau::data::GeneralizedTableau;

let mut tab: GeneralizedTableau<ByteF64<1>> =
    GeneralizedTableau::new_with_seed(1, 1e-12, 0);
tab.h(0);
tab.t(0);
tab.t_dag(0);
// T followed by T† is the identity; the |+⟩ state is restored.
structTableauppvm_tableau::data::Tableau
struct Tableau<T>

A 2n-row stabilizer / destabilizer tableau.

Full docstring

A 2n-row stabilizer / destabilizer tableau.

Rows 0..n hold the destabilizers; rows n..2n hold the stabilizers. Each row is a PhasedPauliWord tracking both its X/Z bits and a phase in {±1, ±i}. Implements every Clifford-only operation natively (Hadamard, phase, CNOT, CZ, etc.).

Examples

use ppvm_pauli_sum::config::fxhash::ByteF64;
use ppvm_traits::traits::Clifford;
use ppvm_tableau::data::Tableau;

let mut tab: Tableau<ByteF64<1>> = Tableau::new(2);
tab.h(0);
tab.cnot(0, 1);
assert_eq!(tab.n_qubits, 2);
assert_eq!(tab.stabilizers().len(), 2);
structMeasureScratchppvm_tableau::measure::MeasureScratch
struct MeasureScratch<I, R>

Per-measurement scratch buffers, reused across qubits within a single measure_all invocation — and, when threaded through measure_all_with_scratch, across many shots of a sampler too. R…

Full docstring

Per-measurement scratch buffers, reused across qubits within a single measure_all invocation — and, when threaded through measure_all_with_scratch, across many shots of a sampler too. Reusing one scratch keeps the case-a HashMap and the b-entries Vec out of the per-shot allocator churn.

  • odd_phase_mask is lazily computed and cached until the destabilizers change (i.e. until a case-a measurement runs update_tableau_according_to_outcome).
  • coeff_map is the case-a HashMap holding (idx → amplitude) between the overlap, partition, and merge passes.
  • b_entries is the case-a partition's "k-bit = 1" scratch Vec.

Construct one per active sampling thread; the type is not meant to be shared across threads concurrently.

traitSparseVectorppvm_tableau::sparsevec::SparseVector
trait SparseVector<T, I>

A sparse vector keyed by index type I with values of type T.

Full docstring

A sparse vector keyed by index type I with values of type T.

Used by GeneralizedTableau to store the coefficient over each branching bitstring. The default implementation is Vec<(T, I)>; alternative backings (BTreeMap, HashMap, etc.) can be provided by downstream code.

traitTableauIndexppvm_tableau::tableau_index::TableauIndex
trait TableauIndex

Bit-string index type used by GeneralizedTableau to address individual branches of its sparse coefficient vector.

Full docstring

Bit-string index type used by GeneralizedTableau to address individual branches of its sparse coefficient vector.

Blanket-implemented for every primitive (and bnum-style) integer type that supports the required bit operations. Pick:

  • usize for ≤ 64 qubits,
  • u128 for ≤ 128,
  • bnum::types::U256 / U512 / U1024 for the wide regime.
traitTableauLikeppvm_tableau::tableau_like::TableauLike
trait TableauLike

A stabilizer-tableau-like backend that supports Clifford gates and an RNG.

Full docstring

A stabilizer-tableau-like backend that supports Clifford gates and an RNG.

Implementing this trait grants default implementations of the Pauli noise channels via [TableauLike::depolarize_impl] and friends. The associated Rng type lets each backend choose its own RNG; nothing in this trait depends on SmallRng.

functionsymplectic_innerppvm_tableau::data::symplectic_inner
fn symplectic_inner(alpha, beta) -> …

Symplectic inner product of two tableau index values — the count of shared set bits, used in stabilizer phase calculations.

ppvm-sym

Symbolic, parametric Pauli propagation.

moduleppvm_symppvm_sym
mod ppvm_sym

Symbolic, parametric Pauli propagation.

Full docstring

Symbolic, parametric Pauli propagation.

ppvm-sym provides a Term type that represents a polynomial in sines and cosines of symbolic parameters. It is used by ppvm to propagate Pauli operators through parametric circuits (e.g., variational ansätze) without committing to specific angle values until the very end.

Quick example

Build the symbolic expression sin(x0) * cos(x1), then evaluate it at a concrete (x0, x1):

use ppvm_sym::Term;

let expr = Term::var(0).sin() * Term::var(1).cos();

let v = expr.eval(&[0.5, 1.0]).unwrap();
let expected = 0.5_f64.sin() * 1.0_f64.cos();
assert!((v - expected).abs() < 1e-12);
structProdppvm_sym::term::Prod
struct Prod

<coeff> sin^m cos^n

Full docstring

<coeff> sin^m cos^n

A single product of trigonometric atoms over symbolic variables. Sines and cosines are grouped by variable id; powers are tracked as totals so we can quickly compute and bound them. The order of variables is kept canonical (ascending) so two Prod values representing the same monomial compare equal.

structSumppvm_sym::term::Sum
struct Sum

A formal sum c₀ + Σᵢ cᵢ · pᵢ, where each pᵢ is a Prod and cᵢ is an f64 coefficient.

structTermppvm_sym::term::Term
struct Term

A symbolic polynomial in sin(x_i) and cos(x_i).

Full docstring

A symbolic polynomial in sin(x_i) and cos(x_i).

Term is the public-facing wrapper around its Inner enum. It also carries two truncation parameters, applied during multiplication and addition:

Examples

use ppvm_sym::Term;

// sin²(x0) at x0 = π/2 equals 1.
let expr = Term::var(0).sin() * Term::var(0).sin();
let v = expr.eval(&[std::f64::consts::FRAC_PI_2]).unwrap();
assert!((v - 1.0).abs() < 1e-12);
  • max_sin — drop terms whose total sine power exceeds this bound.
  • min_eps — drop terms whose coefficient magnitude falls below this threshold.
enumInnerppvm_sym::term::Inner
enum Inner

Internal representation of a Term.

Full docstring

Internal representation of a Term.

Sum holds a full formal sum; One is the optimisation for a single weighted product; Var is a bare symbolic variable used before it has been wrapped in a sin or cos; Const is a numeric scalar.