// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. pub mod bits; pub mod clifford; pub mod operations; pub mod outcome_specific_simulation; pub mod pauli; pub mod quantum_core; pub mod setwise; pub use operations::UnitaryOp; type Tuple2 = (T, T); type Tuple4 = (T, T, T, T); type Tuple8 = (T, T, T, T, T, T, T, T); type Tuple2x2 = Tuple2>; type Tuple4x2 = Tuple4>; pub trait NeutralElement { type NeutralElementType: 'static; fn neutral_element(&self) -> Self::NeutralElementType; fn default_size_neutral_element() -> Self::NeutralElementType; fn neutral_element_of_size(size: usize) -> Self::NeutralElementType; } use clifford::CliffordUnitary; use pauli::SparsePauli; use quantum_core::PositionedPauliObservable; pub trait Simulation { fn pauli_exp(&mut self, sparse_pauli: &[PositionedPauliObservable]); fn apply_unitary(&mut self, unitary_op: UnitaryOp, support: &[usize]); fn apply_clifford(&mut self, clifford: &CliffordUnitary, support: &[usize]); fn apply_permutation(&mut self, permutation: &[usize], support: &[usize]); fn controlled_pauli( &mut self, observable1: &[PositionedPauliObservable], observable2: &[PositionedPauliObservable], ); fn pauli(&mut self, observable: &[PositionedPauliObservable]); fn random_bit(&mut self) -> usize; fn measure(&mut self, observable: &[PositionedPauliObservable]) -> usize; fn measure_with_hint( &mut self, observable: &[PositionedPauliObservable], hint: &[PositionedPauliObservable], ) -> usize; fn measure_sparse(&mut self, pauli: &SparsePauli) -> usize; fn conditional_pauli( &mut self, observable: &[PositionedPauliObservable], outcomes: &[usize], parity: bool, ); fn assert_stabilizer(&self, observable: &[PositionedPauliObservable]); fn assert_stabilizer_up_to_sign(&self, observable: &[PositionedPauliObservable]); fn assert_anti_stabilizer(&self, observable: &[PositionedPauliObservable]); fn with_capacity(num_qubits: usize, num_outcomes: usize, num_random_outcomes: usize) -> Self; fn new() -> Self; fn num_random_outcomes(&self) -> usize; fn random_outcome_indicator(&self) -> &[bool]; } #[must_use] pub fn subscript_digits(number: usize) -> String { let mut res = String::new(); for char in number.to_string().chars() { let digit = char.to_digit(10).unwrap_or_default() as usize; res.push(SUB_CHARS[digit]); } res } pub const SUB_CHARS: [char; 10] = ['₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉'];