Skip to main content

ppvm_tableau/gates/
tgate.rs

1// SPDX-FileCopyrightText: 2026 The PPVM Authors
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::prelude::*;
5use bitvec::view::BitView;
6use num::PrimInt;
7use num::complex::{Complex, Complex64, ComplexFloat};
8use num::traits::{One, Zero};
9use std::ops::{BitAnd, Shl};
10
11const COS_PI_OVER_8_TIMES_EXPIPI8: Complex64 = Complex {
12    re: 0.8535533905932737,
13    im: 0.3535533905932738,
14}; // exp(im * pi / 8) * cos(pi/8)
15const ISIN_PI_OVER_8_TIMES_EXPIPI8: Complex64 = Complex {
16    re: 0.14644660940672624,
17    im: -0.3535533905932738,
18}; // -im * exp(im * pi / 8) * sin(pi/8)
19
20impl<T, I, C> TGate<T> for GeneralizedTableau<T, I, C>
21where
22    T: Config,
23    <<T as Config>::Storage as BitView>::Store: PrimInt,
24    C: SparseVector<Complex<T::Coeff>, I>,
25    T::Coeff: One + Zero + Clone + Send + Sync + num::Num + PartialOrd,
26    Complex<T::Coeff>: std::ops::Mul<Output = Complex<T::Coeff>>
27        + std::ops::AddAssign
28        + From<Complex64>
29        + ComplexFloat
30        + Copy,
31    I: TableauIndex + Send + Sync,
32    <I as BitAnd<<I as Shl<usize>>::Output>>::Output: PartialEq<I>,
33{
34    fn t(&mut self, index: usize) {
35        if self.is_inactive(index) {
36            return;
37        }
38
39        let complex_cos: Complex<T::Coeff> = COS_PI_OVER_8_TIMES_EXPIPI8.into();
40        let complex_sin: Complex<T::Coeff> = ISIN_PI_OVER_8_TIMES_EXPIPI8.into();
41        self.branch_with_coefficients(index, Pauli::Z, complex_cos, complex_sin);
42    }
43
44    fn t_dag(&mut self, index: usize) {
45        if self.is_inactive(index) {
46            return;
47        }
48
49        let complex_cos: Complex<T::Coeff> = COS_PI_OVER_8_TIMES_EXPIPI8.conj().into();
50        let complex_sin: Complex<T::Coeff> = ISIN_PI_OVER_8_TIMES_EXPIPI8.conj().into();
51        self.branch_with_coefficients(index, Pauli::Z, complex_cos, complex_sin);
52    }
53}