Skip to main content

quantrs2_core/characterization/
mod.rs

1//! Gate and quantum system characterization
2//!
3//! This module provides comprehensive tools for analyzing and characterizing quantum gates
4//! and quantum systems using their eigenstructure and other advanced techniques. This is useful for:
5//! - Gate synthesis and decomposition
6//! - Identifying gate types and parameters
7//! - Optimizing gate sequences
8//! - Verifying gate implementations
9//! - Quantum volume measurement
10//! - Quantum process tomography
11//! - Noise characterization and mitigation
12
13pub 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); // Rz-Ry-Rz decomposition
77    }
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); // Opposite phases
94    }
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}