use scirs2_core::Complex64;
pub trait QuantumComplexExt {
fn probability(&self) -> f64;
fn normalize(&self) -> Complex64;
fn approx_eq(&self, other: &Complex64, tolerance: f64) -> bool;
fn fidelity(&self, other: &Complex64) -> f64;
}
impl QuantumComplexExt for Complex64 {
fn probability(&self) -> f64 {
self.norm_sqr()
}
fn normalize(&self) -> Complex64 {
let mag = self.norm();
if mag > 0.0 {
self / mag
} else {
Self::new(0.0, 0.0)
}
}
fn approx_eq(&self, other: &Complex64, tolerance: f64) -> bool {
(self - other).norm() < tolerance
}
fn fidelity(&self, other: &Complex64) -> f64 {
(self.conj() * other).norm()
}
}
pub mod quantum_states {
use super::*;
pub const fn zero_state() -> Complex64 {
Complex64::new(1.0, 0.0)
}
pub const fn one_state() -> Complex64 {
Complex64::new(0.0, 0.0)
}
pub fn plus_state_component() -> Complex64 {
Complex64::new(1.0 / std::f64::consts::SQRT_2, 0.0)
}
pub fn minus_state_component() -> Complex64 {
Complex64::new(1.0 / std::f64::consts::SQRT_2, 0.0)
}
pub fn phase_factor(theta: f64) -> Complex64 {
Complex64::new(theta.cos(), theta.sin())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_probability() {
let c = Complex64::new(0.6, 0.8);
assert!((c.probability() - 1.0).abs() < 1e-10);
}
#[test]
fn test_normalize() {
let c = Complex64::new(3.0, 4.0);
let normalized = c.normalize();
assert!((normalized.norm() - 1.0).abs() < 1e-10);
}
#[test]
fn test_approx_eq() {
let c1 = Complex64::new(1.0, 0.0);
let c2 = Complex64::new(1.0000001, 0.0);
assert!(c1.approx_eq(&c2, 1e-6));
assert!(!c1.approx_eq(&c2, 1e-8));
}
#[test]
fn test_phase_factor() {
use std::f64::consts::PI;
let phase = quantum_states::phase_factor(PI / 2.0);
assert!(phase.re.abs() < 1e-10);
assert!((phase.im - 1.0).abs() < 1e-10);
}
}