1use super::{CVDeviceConfig, Complex, GaussianState};
7use crate::{DeviceError, DeviceResult};
8use serde::{Deserialize, Serialize};
9use std::f64::consts::PI;
10
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub enum CVErrorCorrectionCode {
14 GKP {
16 spacing: f64,
18 logical_qubits: usize,
20 },
21 CoherentState {
23 alphabet_size: usize,
25 amplitudes: Vec<Complex>,
27 },
28 SqueezeStabilizer {
30 stabilizers: Vec<CVStabilizer>,
32 },
33 Concatenated {
35 inner_code: Box<Self>,
37 outer_code: Box<Self>,
39 },
40}
41
42#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
44pub struct CVStabilizer {
45 pub operators: Vec<(f64, usize, QuadratureType)>,
47 pub eigenvalue: f64,
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53pub enum QuadratureType {
54 Position,
56 Momentum,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct CVErrorCorrectionConfig {
63 pub code_type: CVErrorCorrectionCode,
65 pub error_model: CVErrorModel,
67 pub syndrome_threshold: f64,
69 pub max_correction_attempts: usize,
71 pub real_time_correction: bool,
73 pub decoder_config: CVDecoderConfig,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct CVErrorModel {
80 pub displacement_std: f64,
82 pub phase_std: f64,
84 pub loss_probability: f64,
86 pub thermal_photons: f64,
88 pub detector_efficiency: f64,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct CVDecoderConfig {
95 pub decoder_type: CVDecoderType,
97 pub ml_threshold: f64,
99 pub lookup_table_size: usize,
101 pub enable_ml_enhancement: bool,
103}
104
105#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
107pub enum CVDecoderType {
108 MaximumLikelihood,
110 MinimumDistance,
112 NeuralNetwork,
114 LookupTable,
116}
117
118impl Default for CVErrorCorrectionConfig {
119 fn default() -> Self {
120 Self {
121 code_type: CVErrorCorrectionCode::GKP {
122 spacing: (PI).sqrt(),
123 logical_qubits: 1,
124 },
125 error_model: CVErrorModel::default(),
126 syndrome_threshold: 0.1,
127 max_correction_attempts: 3,
128 real_time_correction: true,
129 decoder_config: CVDecoderConfig::default(),
130 }
131 }
132}
133
134impl Default for CVErrorModel {
135 fn default() -> Self {
136 Self {
137 displacement_std: 0.1,
138 phase_std: 0.05,
139 loss_probability: 0.01,
140 thermal_photons: 0.1,
141 detector_efficiency: 0.95,
142 }
143 }
144}
145
146impl Default for CVDecoderConfig {
147 fn default() -> Self {
148 Self {
149 decoder_type: CVDecoderType::MaximumLikelihood,
150 ml_threshold: 0.8,
151 lookup_table_size: 10000,
152 enable_ml_enhancement: false,
153 }
154 }
155}
156
157pub struct CVErrorCorrector {
159 config: CVErrorCorrectionConfig,
161 logical_state: Option<CVLogicalState>,
163 syndrome_history: Vec<CVSyndrome>,
165 correction_stats: CorrectionStatistics,
167}
168
169#[derive(Debug, Clone, Serialize, Deserialize)]
171pub struct CVLogicalState {
172 pub physical_modes: GaussianState,
174 pub logical_info: Vec<LogicalQubitInfo>,
176 pub code_parameters: CodeParameters,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
182pub struct LogicalQubitInfo {
183 pub qubit_id: usize,
185 pub physical_modes: Vec<usize>,
187 pub logical_operators: LogicalOperators,
189}
190
191#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct LogicalOperators {
194 pub logical_x: CVOperator,
196 pub logical_z: CVOperator,
198 pub logical_y: CVOperator,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize)]
204pub struct CVOperator {
205 pub displacements: Vec<Complex>,
207 pub squeezings: Vec<(f64, f64)>, pub couplings: Vec<ModeCoupling>,
211}
212
213#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct ModeCoupling {
216 pub modes: (usize, usize),
218 pub strength: f64,
220 pub coupling_type: CouplingType,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
226pub enum CouplingType {
227 Beamsplitter,
229 TwoModeSqueezing,
231 CrossKerr,
233}
234
235#[derive(Debug, Clone, Serialize, Deserialize)]
237pub struct CodeParameters {
238 pub distance: usize,
240 pub num_physical_modes: usize,
242 pub num_logical_qubits: usize,
244 pub error_threshold: f64,
246}
247
248#[derive(Debug, Clone, Serialize, Deserialize)]
250pub struct CVSyndrome {
251 pub syndrome_id: usize,
253 pub measurements: Vec<SyndromeMeasurement>,
255 pub timestamp: f64,
257 pub confidence: f64,
259}
260
261#[derive(Debug, Clone, Serialize, Deserialize)]
263pub struct SyndromeMeasurement {
264 pub stabilizer_id: usize,
266 pub outcome: f64,
268 pub expected_value: f64,
270 pub uncertainty: f64,
272}
273
274#[derive(Debug, Clone, Serialize, Deserialize)]
276pub struct CorrectionStatistics {
277 pub total_syndromes: usize,
279 pub successful_corrections: usize,
281 pub failed_corrections: usize,
283 pub average_fidelity: f64,
285 pub logical_error_rate: f64,
287}
288
289impl Default for CorrectionStatistics {
290 fn default() -> Self {
291 Self {
292 total_syndromes: 0,
293 successful_corrections: 0,
294 failed_corrections: 0,
295 average_fidelity: 0.0,
296 logical_error_rate: 0.0,
297 }
298 }
299}
300
301impl CVErrorCorrector {
302 pub fn new(config: CVErrorCorrectionConfig) -> Self {
304 Self {
305 config,
306 logical_state: None,
307 syndrome_history: Vec::new(),
308 correction_stats: CorrectionStatistics::default(),
309 }
310 }
311
312 pub async fn initialize_logical_state(
314 &mut self,
315 initial_state: GaussianState,
316 ) -> DeviceResult<CVLogicalState> {
317 println!("Initializing CV logical state...");
318
319 let logical_state = match &self.config.code_type {
320 CVErrorCorrectionCode::GKP {
321 spacing,
322 logical_qubits,
323 } => {
324 self.initialize_gkp_state(initial_state, *spacing, *logical_qubits)
325 .await?
326 }
327 CVErrorCorrectionCode::CoherentState {
328 alphabet_size,
329 amplitudes,
330 } => {
331 self.initialize_coherent_state_code(initial_state, *alphabet_size, amplitudes)
332 .await?
333 }
334 _ => {
335 return Err(DeviceError::UnsupportedOperation(
336 "Code type not yet implemented".to_string(),
337 ));
338 }
339 };
340
341 self.logical_state = Some(logical_state.clone());
342 println!("Logical state initialized successfully");
343 Ok(logical_state)
344 }
345
346 async fn initialize_gkp_state(
348 &self,
349 mut physical_state: GaussianState,
350 spacing: f64,
351 num_logical_qubits: usize,
352 ) -> DeviceResult<CVLogicalState> {
353 let num_physical_modes = physical_state.num_modes;
357
358 for mode in 0..num_physical_modes.min(num_logical_qubits) {
360 for i in 0..10 {
362 let phase = 2.0 * PI * i as f64 / 10.0;
363 let squeezing_param = 0.5 * (spacing / PI.sqrt()).ln();
364 physical_state.apply_squeezing(mode, squeezing_param, phase)?;
365 }
366 }
367
368 let mut logical_info = Vec::new();
370 for qubit_id in 0..num_logical_qubits {
371 let logical_operators = self.build_gkp_logical_operators(qubit_id, spacing);
372 logical_info.push(LogicalQubitInfo {
373 qubit_id,
374 physical_modes: vec![qubit_id], logical_operators,
376 });
377 }
378
379 let code_parameters = CodeParameters {
380 distance: 1, num_physical_modes,
382 num_logical_qubits,
383 error_threshold: 0.5 * spacing,
384 };
385
386 Ok(CVLogicalState {
387 physical_modes: physical_state,
388 logical_info,
389 code_parameters,
390 })
391 }
392
393 fn build_gkp_logical_operators(&self, qubit_id: usize, spacing: f64) -> LogicalOperators {
395 let logical_x = CVOperator {
397 displacements: vec![Complex::new(spacing, 0.0)],
398 squeezings: Vec::new(),
399 couplings: Vec::new(),
400 };
401
402 let logical_z = CVOperator {
404 displacements: vec![Complex::new(0.0, spacing)],
405 squeezings: Vec::new(),
406 couplings: Vec::new(),
407 };
408
409 let logical_y = CVOperator {
411 displacements: vec![Complex::new(
412 spacing / (2.0_f64).sqrt(),
413 spacing / (2.0_f64).sqrt(),
414 )],
415 squeezings: Vec::new(),
416 couplings: Vec::new(),
417 };
418
419 LogicalOperators {
420 logical_x,
421 logical_z,
422 logical_y,
423 }
424 }
425
426 async fn initialize_coherent_state_code(
428 &self,
429 physical_state: GaussianState,
430 alphabet_size: usize,
431 amplitudes: &[Complex],
432 ) -> DeviceResult<CVLogicalState> {
433 if amplitudes.len() != alphabet_size {
434 return Err(DeviceError::InvalidInput(
435 "Number of amplitudes must match alphabet size".to_string(),
436 ));
437 }
438
439 let num_physical_modes = physical_state.num_modes;
441 let num_logical_qubits = 1; let logical_info = vec![LogicalQubitInfo {
444 qubit_id: 0,
445 physical_modes: (0..num_physical_modes).collect(),
446 logical_operators: self.build_coherent_state_logical_operators(amplitudes),
447 }];
448
449 let code_parameters = CodeParameters {
450 distance: alphabet_size / 2, num_physical_modes,
452 num_logical_qubits,
453 error_threshold: amplitudes.iter().map(|a| a.magnitude()).sum::<f64>()
454 / alphabet_size as f64
455 * 0.5,
456 };
457
458 Ok(CVLogicalState {
459 physical_modes: physical_state,
460 logical_info,
461 code_parameters,
462 })
463 }
464
465 fn build_coherent_state_logical_operators(&self, amplitudes: &[Complex]) -> LogicalOperators {
467 let avg_amplitude = amplitudes.iter().fold(Complex::zero(), |acc, &a| acc + a)
469 * (1.0 / amplitudes.len() as f64);
470
471 LogicalOperators {
472 logical_x: CVOperator {
473 displacements: vec![avg_amplitude],
474 squeezings: Vec::new(),
475 couplings: Vec::new(),
476 },
477 logical_z: CVOperator {
478 displacements: vec![Complex::new(0.0, avg_amplitude.magnitude())],
479 squeezings: Vec::new(),
480 couplings: Vec::new(),
481 },
482 logical_y: CVOperator {
483 displacements: vec![Complex::new(avg_amplitude.real, avg_amplitude.magnitude())],
484 squeezings: Vec::new(),
485 couplings: Vec::new(),
486 },
487 }
488 }
489
490 pub async fn measure_syndrome(&mut self) -> DeviceResult<CVSyndrome> {
492 if self.logical_state.is_none() {
493 return Err(DeviceError::InvalidInput(
494 "No logical state initialized".to_string(),
495 ));
496 }
497
498 let syndrome_id = self.syndrome_history.len();
499 let mut measurements = Vec::new();
500
501 match &self.config.code_type {
503 CVErrorCorrectionCode::GKP { spacing, .. } => {
504 measurements = self.measure_gkp_stabilizers(*spacing).await?;
505 }
506 CVErrorCorrectionCode::CoherentState { amplitudes, .. } => {
507 measurements = self.measure_coherent_state_stabilizers(amplitudes).await?;
508 }
509 _ => {
510 return Err(DeviceError::UnsupportedOperation(
511 "Syndrome measurement not implemented for this code type".to_string(),
512 ));
513 }
514 }
515
516 let confidence = measurements
518 .iter()
519 .map(|m| 1.0 / (1.0 + m.uncertainty))
520 .sum::<f64>()
521 / measurements.len() as f64;
522
523 let syndrome = CVSyndrome {
524 syndrome_id,
525 measurements,
526 timestamp: std::time::SystemTime::now()
527 .duration_since(std::time::UNIX_EPOCH)
528 .expect("System time should be after UNIX epoch")
529 .as_secs_f64(),
530 confidence,
531 };
532
533 self.syndrome_history.push(syndrome.clone());
534 self.correction_stats.total_syndromes += 1;
535
536 Ok(syndrome)
537 }
538
539 async fn measure_gkp_stabilizers(
541 &self,
542 spacing: f64,
543 ) -> DeviceResult<Vec<SyndromeMeasurement>> {
544 let logical_state = self
545 .logical_state
546 .as_ref()
547 .ok_or_else(|| DeviceError::InvalidInput("No logical state initialized".to_string()))?;
548 let mut measurements = Vec::new();
549
550 for mode in 0..logical_state.physical_modes.num_modes {
552 let x_measurement = self
554 .measure_periodic_stabilizer(mode, QuadratureType::Position, spacing)
555 .await?;
556 measurements.push(x_measurement);
557
558 let p_measurement = self
560 .measure_periodic_stabilizer(mode, QuadratureType::Momentum, spacing)
561 .await?;
562 measurements.push(p_measurement);
563 }
564
565 Ok(measurements)
566 }
567
568 async fn measure_periodic_stabilizer(
570 &self,
571 mode: usize,
572 quadrature_type: QuadratureType,
573 spacing: f64,
574 ) -> DeviceResult<SyndromeMeasurement> {
575 let logical_state = self
576 .logical_state
577 .as_ref()
578 .ok_or_else(|| DeviceError::InvalidInput("No logical state initialized".to_string()))?;
579 let config = CVDeviceConfig::default();
580
581 let phase = match quadrature_type {
582 QuadratureType::Position => 0.0,
583 QuadratureType::Momentum => PI / 2.0,
584 };
585
586 let mut temp_state = logical_state.physical_modes.clone();
588 let outcome = temp_state.homodyne_measurement(mode, phase, &config)?;
589
590 let syndrome_value = (outcome % spacing) / spacing;
592 let expected_value = 0.0; let uncertainty = self.config.error_model.displacement_std;
594
595 Ok(SyndromeMeasurement {
596 stabilizer_id: mode * 2 + usize::from(quadrature_type != QuadratureType::Position),
597 outcome: syndrome_value,
598 expected_value,
599 uncertainty,
600 })
601 }
602
603 async fn measure_coherent_state_stabilizers(
605 &self,
606 _amplitudes: &[Complex],
607 ) -> DeviceResult<Vec<SyndromeMeasurement>> {
608 let logical_state = self
610 .logical_state
611 .as_ref()
612 .ok_or_else(|| DeviceError::InvalidInput("No logical state initialized".to_string()))?;
613 let mut measurements = Vec::new();
614
615 for mode in 0..logical_state.physical_modes.num_modes {
616 let config = CVDeviceConfig::default();
617 let mut temp_state = logical_state.physical_modes.clone();
618
619 let outcome = temp_state.heterodyne_measurement(mode, &config)?;
620
621 measurements.push(SyndromeMeasurement {
622 stabilizer_id: mode,
623 outcome: outcome.magnitude(),
624 expected_value: 1.0, uncertainty: self.config.error_model.displacement_std,
626 });
627 }
628
629 Ok(measurements)
630 }
631
632 pub async fn apply_correction(
634 &mut self,
635 syndrome: &CVSyndrome,
636 ) -> DeviceResult<CorrectionResult> {
637 if self.logical_state.is_none() {
638 return Err(DeviceError::InvalidInput(
639 "No logical state to correct".to_string(),
640 ));
641 }
642
643 println!(
644 "Applying error correction for syndrome {}",
645 syndrome.syndrome_id
646 );
647
648 let correction_operations = self.decode_syndrome(syndrome).await?;
650
651 let mut correction_success = true;
653 let mut applied_operations = 0;
654
655 for operation in &correction_operations {
656 match self.apply_correction_operation(operation).await {
657 Ok(()) => applied_operations += 1,
658 Err(_) => {
659 correction_success = false;
660 break;
661 }
662 }
663 }
664
665 let fidelity = if correction_success {
667 syndrome
668 .measurements
669 .iter()
670 .map(|m| (m.outcome - m.expected_value).abs())
671 .sum::<f64>()
672 .mul_add(-0.1, 0.95)
673 } else {
674 0.5
675 };
676
677 if correction_success {
679 self.correction_stats.successful_corrections += 1;
680 } else {
681 self.correction_stats.failed_corrections += 1;
682 }
683
684 let total_corrections =
685 self.correction_stats.successful_corrections + self.correction_stats.failed_corrections;
686 self.correction_stats.average_fidelity = self
687 .correction_stats
688 .average_fidelity
689 .mul_add((total_corrections - 1) as f64, fidelity)
690 / total_corrections as f64;
691
692 Ok(CorrectionResult {
693 syndrome_id: syndrome.syndrome_id,
694 correction_operations,
695 success: correction_success,
696 fidelity,
697 applied_operations,
698 })
699 }
700
701 async fn decode_syndrome(
703 &self,
704 syndrome: &CVSyndrome,
705 ) -> DeviceResult<Vec<CorrectionOperation>> {
706 match self.config.decoder_config.decoder_type {
707 CVDecoderType::MaximumLikelihood => self.ml_decode(syndrome).await,
708 CVDecoderType::MinimumDistance => self.minimum_distance_decode(syndrome).await,
709 _ => Err(DeviceError::UnsupportedOperation(
710 "Decoder type not implemented".to_string(),
711 )),
712 }
713 }
714
715 async fn ml_decode(&self, syndrome: &CVSyndrome) -> DeviceResult<Vec<CorrectionOperation>> {
717 let mut corrections = Vec::new();
718
719 for measurement in &syndrome.measurements {
720 let deviation = (measurement.outcome - measurement.expected_value).abs();
721
722 if deviation > self.config.syndrome_threshold {
723 let mode = measurement.stabilizer_id / 2;
725 let is_position = measurement.stabilizer_id % 2 == 0;
726
727 let correction_amplitude = if is_position {
728 Complex::new(-measurement.outcome, 0.0)
729 } else {
730 Complex::new(0.0, -measurement.outcome)
731 };
732
733 corrections.push(CorrectionOperation {
734 operation_type: CorrectionOperationType::Displacement {
735 mode,
736 amplitude: correction_amplitude,
737 },
738 confidence: measurement.uncertainty,
739 });
740 }
741 }
742
743 Ok(corrections)
744 }
745
746 async fn minimum_distance_decode(
748 &self,
749 syndrome: &CVSyndrome,
750 ) -> DeviceResult<Vec<CorrectionOperation>> {
751 let mut corrections = Vec::new();
753
754 let mut min_distance = f64::INFINITY;
756 let mut best_correction = None;
757
758 for measurement in &syndrome.measurements {
759 let distance = (measurement.outcome - measurement.expected_value).abs();
760
761 if distance < min_distance && distance > self.config.syndrome_threshold {
762 min_distance = distance;
763
764 let mode = measurement.stabilizer_id / 2;
765 let is_position = measurement.stabilizer_id % 2 == 0;
766
767 let correction_amplitude = if is_position {
768 Complex::new(-measurement.outcome * 0.5, 0.0)
769 } else {
770 Complex::new(0.0, -measurement.outcome * 0.5)
771 };
772
773 best_correction = Some(CorrectionOperation {
774 operation_type: CorrectionOperationType::Displacement {
775 mode,
776 amplitude: correction_amplitude,
777 },
778 confidence: 1.0 / (1.0 + distance),
779 });
780 }
781 }
782
783 if let Some(correction) = best_correction {
784 corrections.push(correction);
785 }
786
787 Ok(corrections)
788 }
789
790 async fn apply_correction_operation(
792 &mut self,
793 operation: &CorrectionOperation,
794 ) -> DeviceResult<()> {
795 if let Some(logical_state) = &mut self.logical_state {
796 match &operation.operation_type {
797 CorrectionOperationType::Displacement { mode, amplitude } => {
798 logical_state
799 .physical_modes
800 .apply_displacement(*mode, *amplitude)?;
801 }
802 CorrectionOperationType::Squeezing {
803 mode,
804 parameter,
805 phase,
806 } => {
807 logical_state
808 .physical_modes
809 .apply_squeezing(*mode, *parameter, *phase)?;
810 }
811 CorrectionOperationType::PhaseRotation { mode, phase } => {
812 logical_state
813 .physical_modes
814 .apply_phase_rotation(*mode, *phase)?;
815 }
816 }
817 }
818 Ok(())
819 }
820
821 pub const fn get_correction_statistics(&self) -> &CorrectionStatistics {
823 &self.correction_stats
824 }
825
826 pub const fn get_logical_state(&self) -> Option<&CVLogicalState> {
828 self.logical_state.as_ref()
829 }
830
831 pub fn get_syndrome_history(&self) -> &[CVSyndrome] {
833 &self.syndrome_history
834 }
835}
836
837#[derive(Debug, Clone, Serialize, Deserialize)]
839pub struct CorrectionOperation {
840 pub operation_type: CorrectionOperationType,
842 pub confidence: f64,
844}
845
846#[derive(Debug, Clone, Serialize, Deserialize)]
848pub enum CorrectionOperationType {
849 Displacement { mode: usize, amplitude: Complex },
851 Squeezing {
853 mode: usize,
854 parameter: f64,
855 phase: f64,
856 },
857 PhaseRotation { mode: usize, phase: f64 },
859}
860
861#[derive(Debug, Clone, Serialize, Deserialize)]
863pub struct CorrectionResult {
864 pub syndrome_id: usize,
866 pub correction_operations: Vec<CorrectionOperation>,
868 pub success: bool,
870 pub fidelity: f64,
872 pub applied_operations: usize,
874}
875
876#[cfg(test)]
877mod tests {
878 use super::*;
879
880 #[tokio::test]
881 async fn test_cv_error_corrector_creation() {
882 let config = CVErrorCorrectionConfig::default();
883 let corrector = CVErrorCorrector::new(config);
884 assert!(corrector.logical_state.is_none());
885 assert_eq!(corrector.syndrome_history.len(), 0);
886 }
887
888 #[tokio::test]
889 async fn test_gkp_state_initialization() {
890 let config = CVErrorCorrectionConfig::default();
891 let mut corrector = CVErrorCorrector::new(config);
892
893 let initial_state = GaussianState::vacuum_state(2);
894 let logical_state = corrector
895 .initialize_logical_state(initial_state)
896 .await
897 .expect("Logical state initialization should succeed");
898
899 assert_eq!(logical_state.physical_modes.num_modes, 2);
900 assert_eq!(logical_state.logical_info.len(), 1);
901 }
902
903 #[tokio::test]
904 async fn test_syndrome_measurement() {
905 let config = CVErrorCorrectionConfig::default();
906 let mut corrector = CVErrorCorrector::new(config);
907
908 let initial_state = GaussianState::vacuum_state(1);
909 corrector
910 .initialize_logical_state(initial_state)
911 .await
912 .expect("Logical state initialization should succeed");
913
914 let syndrome = corrector
915 .measure_syndrome()
916 .await
917 .expect("Syndrome measurement should succeed");
918 assert_eq!(syndrome.syndrome_id, 0);
919 assert!(!syndrome.measurements.is_empty());
920 assert_eq!(corrector.syndrome_history.len(), 1);
921 }
922
923 #[tokio::test]
924 async fn test_error_correction() {
925 let config = CVErrorCorrectionConfig::default();
926 let mut corrector = CVErrorCorrector::new(config);
927
928 let initial_state = GaussianState::vacuum_state(1);
929 corrector
930 .initialize_logical_state(initial_state)
931 .await
932 .expect("Logical state initialization should succeed");
933
934 let syndrome = corrector
935 .measure_syndrome()
936 .await
937 .expect("Syndrome measurement should succeed");
938 let result = corrector
939 .apply_correction(&syndrome)
940 .await
941 .expect("Error correction should succeed");
942
943 assert_eq!(result.syndrome_id, syndrome.syndrome_id);
944 assert!(result.fidelity >= 0.0 && result.fidelity <= 1.0);
945 }
946
947 #[test]
948 fn test_gkp_logical_operators() {
949 let config = CVErrorCorrectionConfig::default();
950 let corrector = CVErrorCorrector::new(config);
951
952 let operators = corrector.build_gkp_logical_operators(0, PI.sqrt());
953
954 assert_eq!(operators.logical_x.displacements.len(), 1);
956 assert_eq!(operators.logical_z.displacements.len(), 1);
957 assert_eq!(operators.logical_y.displacements.len(), 1);
958 }
959
960 #[test]
961 fn test_error_model_defaults() {
962 let error_model = CVErrorModel::default();
963 assert!(error_model.displacement_std > 0.0);
964 assert!(error_model.phase_std > 0.0);
965 assert!(error_model.loss_probability >= 0.0 && error_model.loss_probability <= 1.0);
966 assert!(error_model.detector_efficiency >= 0.0 && error_model.detector_efficiency <= 1.0);
967 }
968
969 #[test]
970 fn test_correction_statistics() {
971 let corrector = CVErrorCorrector::new(CVErrorCorrectionConfig::default());
972 let stats = corrector.get_correction_statistics();
973
974 assert_eq!(stats.total_syndromes, 0);
975 assert_eq!(stats.successful_corrections, 0);
976 assert_eq!(stats.failed_corrections, 0);
977 }
978}