quantrs2_core/characterization/
mod.rs1pub mod gate_characterizer;
14pub mod noise_characterizer;
15pub mod noise_model;
16pub mod quantum_volume;
17pub mod tomography;
18
19pub use gate_characterizer::{GateCharacterizer, GateEigenstructure, GateType};
20pub use noise_characterizer::{
21 MitigationResult, MitigationTechnique, NoiseCharacterizationResult, NoiseCharacterizer,
22 NoiseMitigator,
23};
24pub use noise_model::NoiseModel;
25pub use quantum_volume::{
26 QuantumVolumeConfig, QuantumVolumeMeasurement, QuantumVolumeResult, RandomGate,
27 RandomQuantumCircuit,
28};
29pub use tomography::{
30 ProcessBasis, ProcessTomography, ProcessTomographyConfig, ProcessTomographyResult,
31};
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36 use crate::gate::{single::*, GateOp};
37 use crate::qubit::QubitId;
38 use scirs2_core::Complex64 as Complex;
39 use std::f64::consts::PI;
40
41 #[test]
42 fn test_pauli_identification() {
43 let characterizer = GateCharacterizer::new(1e-10);
44
45 assert_eq!(
46 characterizer
47 .identify_gate_type(&PauliX { target: QubitId(0) })
48 .expect("identify PauliX failed"),
49 GateType::PauliX
50 );
51 assert_eq!(
52 characterizer
53 .identify_gate_type(&PauliY { target: QubitId(0) })
54 .expect("identify PauliY failed"),
55 GateType::PauliY
56 );
57 assert_eq!(
58 characterizer
59 .identify_gate_type(&PauliZ { target: QubitId(0) })
60 .expect("identify PauliZ failed"),
61 GateType::PauliZ
62 );
63 }
64
65 #[test]
66 fn test_rotation_decomposition() {
67 let characterizer = GateCharacterizer::new(1e-10);
68 let rx = RotationX {
69 target: QubitId(0),
70 theta: PI / 4.0,
71 };
72
73 let decomposition = characterizer
74 .decompose_to_rotations(&rx)
75 .expect("decompose to rotations failed");
76 assert_eq!(decomposition.len(), 3); }
78
79 #[test]
80 fn test_eigenphases() {
81 let characterizer = GateCharacterizer::new(1e-10);
82 let rz = RotationZ {
83 target: QubitId(0),
84 theta: PI / 2.0,
85 };
86
87 let eigen = characterizer
88 .eigenstructure(&rz)
89 .expect("eigenstructure failed");
90 let phases = eigen.eigenphases();
91
92 assert_eq!(phases.len(), 2);
93 assert!((phases[0] + phases[1]).abs() < 1e-10); }
95
96 #[test]
97 fn test_closest_clifford() {
98 let characterizer = GateCharacterizer::new(1e-10);
99
100 let t_like = RotationZ {
101 target: QubitId(0),
102 theta: PI / 4.0,
103 };
104 let closest = characterizer
105 .find_closest_clifford(&t_like)
106 .expect("find closest clifford failed");
107
108 let s_distance = characterizer
109 .gate_distance(&t_like, &Phase { target: QubitId(0) })
110 .expect("gate distance to S failed");
111 let actual_distance = characterizer
112 .gate_distance(&t_like, closest.as_ref())
113 .expect("gate distance to closest failed");
114
115 assert!(actual_distance <= s_distance + 1e-10);
116 }
117
118 #[test]
119 fn test_identity_check() {
120 let characterizer = GateCharacterizer::new(1e-10);
121
122 let identity_gate = RotationZ {
123 target: QubitId(0),
124 theta: 0.0,
125 };
126 assert!(characterizer.is_identity(&identity_gate, 1e-10));
127 assert!(!characterizer.is_identity(&PauliX { target: QubitId(0) }, 1e-10));
128
129 let x_squared_vec = vec![
130 Complex::new(1.0, 0.0),
131 Complex::new(0.0, 0.0),
132 Complex::new(0.0, 0.0),
133 Complex::new(1.0, 0.0),
134 ];
135
136 #[derive(Debug)]
137 struct CustomGate(Vec<Complex>);
138 impl GateOp for CustomGate {
139 fn name(&self) -> &'static str {
140 "X²"
141 }
142 fn qubits(&self) -> Vec<QubitId> {
143 vec![QubitId(0)]
144 }
145 fn matrix(&self) -> crate::error::QuantRS2Result<Vec<Complex>> {
146 Ok(self.0.clone())
147 }
148 fn as_any(&self) -> &dyn std::any::Any {
149 self
150 }
151 fn clone_gate(&self) -> Box<dyn GateOp> {
152 Box::new(CustomGate(self.0.clone()))
153 }
154 }
155
156 let x_squared_gate = CustomGate(x_squared_vec);
157 assert!(characterizer.is_identity(&x_squared_gate, 1e-10));
158 }
159
160 #[test]
161 fn test_global_phase() {
162 let characterizer = GateCharacterizer::new(1e-10);
163
164 let z_phase = characterizer
165 .global_phase(&PauliZ { target: QubitId(0) })
166 .expect("global phase of Z failed");
167 assert!((z_phase - PI / 2.0).abs() < 1e-10 || (z_phase + PI / 2.0).abs() < 1e-10);
168
169 let phase_gate = Phase { target: QubitId(0) };
170 let global_phase = characterizer
171 .global_phase(&phase_gate)
172 .expect("global phase of S failed");
173 assert!((global_phase - PI / 4.0).abs() < 1e-10);
174 }
175}