1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// SPDX-FileCopyrightText: 2026 The PPVM Authors
// SPDX-License-Identifier: Apache-2.0
//! 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);
//! ```
//!
//! ## Data-parallel / GPU-offloadable surface
//!
//! A handful of primitives in this crate operate on whole contiguous arrays
//! at once, with no per-element host closures — the shape a thread pool or a
//! CUDA kernel would want:
//!
//! - Every tableau row ([`PhasedPauliWord`](ppvm_pauli_word::phase::PhasedPauliWord))
//! stores its Pauli word as fixed-size `bytemuck::Pod` integer bit-planes
//! (`xbits`/`zbits`, backed by `[u8; N]` or `[u64; N]`), reachable as
//! contiguous raw integer slices via `as_raw_slice`/`as_raw_mut_slice` —
//! plain-old-data, not a bit-addressed abstraction.
//! - The single-gate Clifford path
//! (`crates/ppvm-tableau/src/gates/clifford.rs`) has one shared
//! implementation per gate that loops over rows operating directly on
//! those raw integer slices with a hoisted word-index/bit/mask, bypassing
//! `bitvec`'s per-bit bounds checks inside the loop. Both
//! [`data::Tableau`] and [`data::GeneralizedTableau`] (via the
//! `impl_generalized_tableau_clifford*` macros) funnel through it.
//! - The batch path does **not** share that implementation. The
//! [`CliffordBatch`](ppvm_traits::traits::CliffordBatch) methods (`x_many`,
//! `cz_many`, …) each carry their own raw-plane loop that fuses many gates
//! into a single pass over the rows, and `Tableau` and
//! `GeneralizedTableau` have separate `CliffordBatch` impls (the latter
//! via the `impl_gen_tableau_batch_*` macros). Anyone porting the Clifford
//! layer to a thread pool or a CUDA kernel has to cover both the
//! single-gate implementation and these batch bodies.
//! - The batch methods take arbitrary index lists (`&[usize]`,
//! `&[(usize, usize)]`). [`data::GeneralizedTableau::cz_block`] /
//! `cz_block_pairs` / `cz_block_pairs_cross_word` are the
//! contiguous-block variants: they apply CZ to a whole contiguous range
//! of qubits as bulk masked slice operations, which is the layout a
//! kernel can address without an index indirection.
//! - `GeneralizedTableau::branch_with_coefficients` (crate-private) transforms
//! the whole coefficient array in one pass. Its `#[cfg(feature = "rayon")]`
//! path (`branch_coefficients_parallel`, gated by `RAYON_COEFF_THRESHOLD`)
//! computes the per-entry branch/non-branch coefficient math in parallel,
//! with no shared mutable state — the accumulation of those results into
//! the coefficient map afterwards remains sequential.
/// Core [`Tableau`](data::Tableau) and
/// [`GeneralizedTableau`](data::GeneralizedTableau) types.
/// `Display` implementations for tableau types.
/// Pauli-string expectation values and pattern traces.
/// Gate implementations (Clifford, T, rotations).
/// Z-basis measurement, including loss-aware variants.
/// Per-qubit [`QubitStatus`](qubit_status::QubitStatus) relative to the
/// computational subspace.
/// Noise channels: depolarizing, Pauli error, loss.
/// [`SparseVector`](sparsevec::SparseVector) trait and implementations.
/// [`TableauIndex`](tableau_index::TableauIndex) — abstraction over
/// the bitstring index type (`usize`, `u128`, `U256`, …).
/// [`TableauLike`](tableau_like::TableauLike) — shared trait for
/// stabilizer-tableau backends.
/// Convenience re-exports for downstream code.