use crate::prelude::*;
use num::Complex;
impl<T: Config, I, C: SparseVector<Complex<T::Coeff>, I>> U3Gate<T> for GeneralizedTableau<T, I, C>
where
GeneralizedTableau<T, I, C>: RotationOne<T>,
{
fn u3(&mut self, addr0: usize, theta: T::Coeff, phi: T::Coeff, lambda: T::Coeff) {
self.rz(addr0, lambda);
self.ry(addr0, theta);
self.rz(addr0, phi);
}
}
#[cfg(test)]
mod tests {
use super::*;
use ppvm_pauli_sum::config::fxhash::ByteF64;
use std::f64::consts::PI;
type TestConfig = ByteF64<1>;
type TestTableau = GeneralizedTableau<TestConfig>;
#[test]
fn test_u3_identity() {
let mut tab: TestTableau = GeneralizedTableau::new(1, 1e-12);
tab.u3(0, 0.0, 0.0, 0.0);
assert_eq!(tab.coefficients.len(), 1);
assert!(!tab.measure(0).unwrap());
}
#[test]
fn test_u3_x_gate() {
let mut tab: TestTableau = GeneralizedTableau::new(1, 1e-12);
tab.u3(0, PI, 0.0, 0.0);
assert_eq!(tab.coefficients.len(), 1);
assert!(tab.measure(0).unwrap());
}
#[test]
fn test_u3_superposition() {
let mut tab: TestTableau = GeneralizedTableau::new(1, 1e-12);
tab.u3(0, PI / 2.0, 0.0, 0.0);
assert_eq!(tab.coefficients.len(), 2);
}
#[test]
fn test_u3_matches_rz_ry_rz() {
let (theta, phi, lambda) = (0.34 * PI, 0.21 * PI, 0.46 * PI);
let mut tab_u3: TestTableau = GeneralizedTableau::new_with_seed(1, 1e-12, 0);
tab_u3.u3(0, theta, phi, lambda);
let mut tab_manual: TestTableau = GeneralizedTableau::new_with_seed(1, 1e-12, 0);
tab_manual.rz(0, lambda);
tab_manual.ry(0, theta);
tab_manual.rz(0, phi);
for seed in 0..200 {
let result_u3 = tab_u3.fork(Some(seed)).measure(0).unwrap();
let result_manual = tab_manual.fork(Some(seed)).measure(0).unwrap();
assert_eq!(result_u3, result_manual, "mismatch at seed {}", seed);
}
}
}