quantrs2_core/
complex_ext.rs1use num_complex::Complex64;
7
8pub trait QuantumComplexExt {
10 fn probability(&self) -> f64;
12
13 fn normalize(&self) -> Complex64;
15
16 fn approx_eq(&self, other: &Complex64, tolerance: f64) -> bool;
18
19 fn fidelity(&self, other: &Complex64) -> f64;
21}
22
23impl QuantumComplexExt for Complex64 {
24 fn probability(&self) -> f64 {
25 self.norm_sqr()
26 }
27
28 fn normalize(&self) -> Complex64 {
29 let mag = self.norm();
30 if mag > 0.0 {
31 self / mag
32 } else {
33 Complex64::new(0.0, 0.0)
34 }
35 }
36
37 fn approx_eq(&self, other: &Complex64, tolerance: f64) -> bool {
38 (self - other).norm() < tolerance
39 }
40
41 fn fidelity(&self, other: &Complex64) -> f64 {
42 (self.conj() * other).norm()
43 }
44}
45
46pub mod quantum_states {
48 use super::*;
49
50 pub fn zero_state() -> Complex64 {
52 Complex64::new(1.0, 0.0)
53 }
54
55 pub fn one_state() -> Complex64 {
57 Complex64::new(0.0, 0.0)
58 }
59
60 pub fn plus_state_component() -> Complex64 {
62 Complex64::new(1.0 / std::f64::consts::SQRT_2, 0.0)
63 }
64
65 pub fn minus_state_component() -> Complex64 {
67 Complex64::new(1.0 / std::f64::consts::SQRT_2, 0.0)
68 }
69
70 pub fn phase_factor(theta: f64) -> Complex64 {
72 Complex64::new(theta.cos(), theta.sin())
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn test_probability() {
82 let c = Complex64::new(0.6, 0.8);
83 assert!((c.probability() - 1.0).abs() < 1e-10);
84 }
85
86 #[test]
87 fn test_normalize() {
88 let c = Complex64::new(3.0, 4.0);
89 let normalized = c.normalize();
90 assert!((normalized.norm() - 1.0).abs() < 1e-10);
91 }
92
93 #[test]
94 fn test_approx_eq() {
95 let c1 = Complex64::new(1.0, 0.0);
96 let c2 = Complex64::new(1.0000001, 0.0);
97 assert!(c1.approx_eq(&c2, 1e-6));
98 assert!(!c1.approx_eq(&c2, 1e-8));
99 }
100
101 #[test]
102 fn test_phase_factor() {
103 use std::f64::consts::PI;
104 let phase = quantum_states::phase_factor(PI / 2.0);
105 assert!(phase.re.abs() < 1e-10);
106 assert!((phase.im - 1.0).abs() < 1e-10);
107 }
108}