pub struct Tableau<T: Config> {
pub n_qubits: usize,
pub data: Vec<PhasedPauliWord<T::Storage, T::BuildHasher, PauliWord<T::Storage, T::BuildHasher, false>>>,
/* private fields */
}Expand description
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);Fields§
§n_qubits: usizeNumber of qubits.
data: Vec<PhasedPauliWord<T::Storage, T::BuildHasher, PauliWord<T::Storage, T::BuildHasher, false>>>Destabilizer / Stabilizer tableau
- Entries 0..n are the destabilizers
- Entries n..2n are the stabilizers
Implementations§
Source§impl<T: Config> Tableau<T>
impl<T: Config> Tableau<T>
Sourcepub fn new_with_seed(n_qubits: usize, seed: u64) -> Self
pub fn new_with_seed(n_qubits: usize, seed: u64) -> Self
Same as Tableau::new, but seed the RNG deterministically.
pub fn reset_all(&mut self)
Sourcepub fn stabilizers(
&self,
) -> &[PhasedPauliWord<T::Storage, T::BuildHasher, PauliWord<T::Storage, T::BuildHasher, false>>]
pub fn stabilizers( &self, ) -> &[PhasedPauliWord<T::Storage, T::BuildHasher, PauliWord<T::Storage, T::BuildHasher, false>>]
View of the stabilizer rows (the upper half of the tableau).
Sourcepub fn stabilizers_mut(
&mut self,
) -> &mut [PhasedPauliWord<T::Storage, T::BuildHasher, PauliWord<T::Storage, T::BuildHasher, false>>]
pub fn stabilizers_mut( &mut self, ) -> &mut [PhasedPauliWord<T::Storage, T::BuildHasher, PauliWord<T::Storage, T::BuildHasher, false>>]
Mutable view of the stabilizer rows.
Sourcepub fn destabilizers(
&self,
) -> &[PhasedPauliWord<T::Storage, T::BuildHasher, PauliWord<T::Storage, T::BuildHasher, false>>]
pub fn destabilizers( &self, ) -> &[PhasedPauliWord<T::Storage, T::BuildHasher, PauliWord<T::Storage, T::BuildHasher, false>>]
View of the destabilizer rows (the lower half of the tableau).
Sourcepub fn destabilizers_mut(
&mut self,
) -> &mut [PhasedPauliWord<T::Storage, T::BuildHasher, PauliWord<T::Storage, T::BuildHasher, false>>]
pub fn destabilizers_mut( &mut self, ) -> &mut [PhasedPauliWord<T::Storage, T::BuildHasher, PauliWord<T::Storage, T::BuildHasher, false>>]
Mutable view of the destabilizer rows.
Sourcepub fn cz_block_pairs(&mut self, base: usize, offset: usize, count: usize)
pub fn cz_block_pairs(&mut self, base: usize, offset: usize, count: usize)
Apply CZ to N pairs with constant offset: (base+i, base+offset+i) for i in 0..count. All pairs must be in the same u64 word. This replaces N individual CZ calls with a single word-level shift+XOR operation per row.
§Preconditions
The fused kernel needs offset >= count, i.e. pairwise-disjoint
supports (pairs i != j collide iff |i - j| == offset, which needs
offset < count, or offset == 0). Both fused updates need it: the
single count_ones() & 1 phase reads the pre-update z plane for
every pair at once (Batch.lean::czSeq_phase proves it equal to the
sequential loop only under pairwise disjointness, and
czSeq_phase_needs_disjoint exhibits a counterexample), and the z
delta ORs the two shifted planes, so a z bit written by two pairs
is set once instead of XOR-cancelled.
Overlapping pairs (offset < count, including offset == 0) fall
back to the per-pair cz loop, so this method is safe in release.
§Panics
Debug-asserts that all bits are within the same word.
Sourcepub fn cz_block_pairs_cross_word(
&mut self,
word_c: usize,
base_bit_c: usize,
word_t: usize,
base_bit_t: usize,
count: usize,
)
pub fn cz_block_pairs_cross_word( &mut self, word_c: usize, base_bit_c: usize, word_t: usize, base_bit_t: usize, count: usize, )
Apply CZ to N pairs with constant offset across two different words. Controls at (word_c, base_bit_c+i) and targets at (word_t, base_bit_t+i) for i in 0..count. word_c and word_t must be different.
Trait Implementations§
Source§impl<T: Config> CliffordBatch for Tableau<T>
impl<T: Config> CliffordBatch for Tableau<T>
Source§fn x_many(&mut self, indices: &[usize])
fn x_many(&mut self, indices: &[usize])
X is bit-preserving: phase flips for each masked qubit where z=1.
Source§fn y_many(&mut self, indices: &[usize])
fn y_many(&mut self, indices: &[usize])
Y is bit-preserving: phase flips for each masked qubit where x⊕z=1.
Source§fn z_many(&mut self, indices: &[usize])
fn z_many(&mut self, indices: &[usize])
Z is bit-preserving: phase flips for each masked qubit where x=1.
Source§fn s_many(&mut self, indices: &[usize])
fn s_many(&mut self, indices: &[usize])
Forward S: phase flips where x&z=1, then z ^= x for masked qubits.
Source§fn cnot_many(&mut self, pairs: &[(usize, usize)])
fn cnot_many(&mut self, pairs: &[(usize, usize)])
Apply CNOT to many pairs, operating on raw storage words to avoid
per-bit bitvec addressing. Pairs are applied sequentially per row,
so semantics match the per-pair cnot loop exactly.
Source§impl<T: Config> CliffordExtensions for Tableau<T>
impl<T: Config> CliffordExtensions for Tableau<T>
Source§fn sqrt_x_dag(&mut self, index: usize)
fn sqrt_x_dag(&mut self, index: usize)
(√X)† to one qubit.Source§fn sqrt_y_dag(&mut self, index: usize)
fn sqrt_y_dag(&mut self, index: usize)
(√Y)† to one qubit.Source§impl<T: Config> CliffordExtensionsBatch for Tableau<T>
impl<T: Config> CliffordExtensionsBatch for Tableau<T>
Source§fn s_dag_many(&mut self, indices: &[usize])
fn s_dag_many(&mut self, indices: &[usize])
Backward S (i.e. S†): same bit mapping as S, phase rule differs.
Phase flips where x&!z=1, then z ^= x for masked qubits.
Source§fn cy_many(&mut self, pairs: &[(usize, usize)])
fn cy_many(&mut self, pairs: &[(usize, usize)])
Apply CY to many pairs on raw storage words. Pairs are applied
sequentially per row, so semantics match the per-pair cy loop exactly.
Source§fn sqrt_y_many(&mut self, indices: &[usize])
fn sqrt_y_many(&mut self, indices: &[usize])
Apply √Y to multiple qubits using combined bitmask operations.
All qubits targeting the same word are merged into a single mask,
reducing N individual operations to O(n_words) per row.
Source§fn sqrt_y_dag_many(&mut self, indices: &[usize])
fn sqrt_y_dag_many(&mut self, indices: &[usize])
Apply (√Y)† to multiple qubits using combined bitmask operations.
Source§fn sqrt_x_many(&mut self, indices: &[usize])
fn sqrt_x_many(&mut self, indices: &[usize])
Apply √X to multiple qubits using combined bitmask operations.
Source§fn sqrt_x_dag_many(&mut self, indices: &[usize])
fn sqrt_x_dag_many(&mut self, indices: &[usize])
Apply (√X)† to multiple qubits using combined bitmask operations.
Source§impl<T: Config> Depolarizing2<T> for Tableau<T>
impl<T: Config> Depolarizing2<T> for Tableau<T>
Source§impl<T: Config> Depolarizing<T> for Tableau<T>
impl<T: Config> Depolarizing<T> for Tableau<T>
Source§impl<T: Config> PauliError<T> for Tableau<T>
impl<T: Config> PauliError<T> for Tableau<T>
Source§fn pauli_error(&mut self, addr0: usize, p: [T::Coeff; 3])
fn pauli_error(&mut self, addr0: usize, p: [T::Coeff; 3])
[p_x, p_y, p_z] to one qubit.Source§fn x_error(&mut self, addr0: usize, p: <T as Config>::Coeff)
fn x_error(&mut self, addr0: usize, p: <T as Config>::Coeff)
X_ERROR(p) — apply X with probability p to one qubit.Source§fn y_error(&mut self, addr0: usize, p: <T as Config>::Coeff)
fn y_error(&mut self, addr0: usize, p: <T as Config>::Coeff)
Y_ERROR(p) — apply Y with probability p to one qubit.Source§fn z_error(&mut self, addr0: usize, p: <T as Config>::Coeff)
fn z_error(&mut self, addr0: usize, p: <T as Config>::Coeff)
Z_ERROR(p) — apply Z with probability p to one qubit.Source§fn pauli_error_many(&mut self, targets: &[usize], p: [<T as Config>::Coeff; 3])
fn pauli_error_many(&mut self, targets: &[usize], p: [<T as Config>::Coeff; 3])
Source§fn x_error_many(&mut self, targets: &[usize], p: <T as Config>::Coeff)
fn x_error_many(&mut self, targets: &[usize], p: <T as Config>::Coeff)
X_ERROR(p).Source§impl<T: Config> Reset for Tableau<T>
impl<T: Config> Reset for Tableau<T>
Source§fn reset_many(&mut self, targets: &[usize])
fn reset_many(&mut self, targets: &[usize])
|0⟩.Source§fn reset_z_many(&mut self, targets: &[usize])
fn reset_z_many(&mut self, targets: &[usize])
RZ alias.Source§fn reset_x_many(&mut self, targets: &[usize])
fn reset_x_many(&mut self, targets: &[usize])
RX.Source§fn reset_y_many(&mut self, targets: &[usize])
fn reset_y_many(&mut self, targets: &[usize])
RY.Source§impl<T: Config> TableauLike for Tableau<T>
impl<T: Config> TableauLike for Tableau<T>
Source§fn is_qubit_lost(&self, _addr: usize) -> bool
fn is_qubit_lost(&self, _addr: usize) -> bool
addr is inactive (lost or leaked), so the
Pauli noise channels skip it. Default: never inactive.Source§fn depolarize_impl(&mut self, addr0: usize, p: Self::Coeff)
fn depolarize_impl(&mut self, addr0: usize, p: Self::Coeff)
Source§fn pauli_error_impl(&mut self, addr0: usize, p: [Self::Coeff; 3])
fn pauli_error_impl(&mut self, addr0: usize, p: [Self::Coeff; 3])
Source§impl<T: Config> TwoQubitPauliError<T> for Tableau<T>
impl<T: Config> TwoQubitPauliError<T> for Tableau<T>
Auto Trait Implementations§
impl<T> Freeze for Tableau<T>where
Vec<PhasedPauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, PauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, false>>>: Freeze,
impl<T> RefUnwindSafe for Tableau<T>where
Vec<PhasedPauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, PauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, false>>>: RefUnwindSafe,
impl<T> Send for Tableau<T>where
Vec<PhasedPauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, PauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, false>>>: Send,
impl<T> Sync for Tableau<T>where
Vec<PhasedPauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, PauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, false>>>: Sync,
impl<T> Unpin for Tableau<T>where
Vec<PhasedPauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, PauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, false>>>: Unpin,
impl<T> UnsafeUnpin for Tableau<T>where
Vec<PhasedPauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, PauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, false>>>: UnsafeUnpin,
impl<T> UnwindSafe for Tableau<T>where
Vec<PhasedPauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, PauliWord<<T as Config>::Storage, <T as Config>::BuildHasher, false>>>: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.