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<CVErrorCorrectionCode>,
37 outer_code: Box<CVErrorCorrectionCode>,
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, 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, 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, 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 .unwrap()
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.logical_state.as_ref().unwrap();
545 let mut measurements = Vec::new();
546
547 for mode in 0..logical_state.physical_modes.num_modes {
549 let x_measurement = self
551 .measure_periodic_stabilizer(mode, QuadratureType::Position, spacing)
552 .await?;
553 measurements.push(x_measurement);
554
555 let p_measurement = self
557 .measure_periodic_stabilizer(mode, QuadratureType::Momentum, spacing)
558 .await?;
559 measurements.push(p_measurement);
560 }
561
562 Ok(measurements)
563 }
564
565 async fn measure_periodic_stabilizer(
567 &self,
568 mode: usize,
569 quadrature_type: QuadratureType,
570 spacing: f64,
571 ) -> DeviceResult<SyndromeMeasurement> {
572 let logical_state = self.logical_state.as_ref().unwrap();
573 let config = CVDeviceConfig::default();
574
575 let phase = match quadrature_type {
576 QuadratureType::Position => 0.0,
577 QuadratureType::Momentum => PI / 2.0,
578 };
579
580 let mut temp_state = logical_state.physical_modes.clone();
582 let outcome = temp_state.homodyne_measurement(mode, phase, &config)?;
583
584 let syndrome_value = (outcome % spacing) / spacing;
586 let expected_value = 0.0; let uncertainty = self.config.error_model.displacement_std;
588
589 Ok(SyndromeMeasurement {
590 stabilizer_id: mode * 2
591 + if quadrature_type == QuadratureType::Position {
592 0
593 } else {
594 1
595 },
596 outcome: syndrome_value,
597 expected_value,
598 uncertainty,
599 })
600 }
601
602 async fn measure_coherent_state_stabilizers(
604 &self,
605 _amplitudes: &[Complex],
606 ) -> DeviceResult<Vec<SyndromeMeasurement>> {
607 let logical_state = self.logical_state.as_ref().unwrap();
609 let mut measurements = Vec::new();
610
611 for mode in 0..logical_state.physical_modes.num_modes {
612 let config = CVDeviceConfig::default();
613 let mut temp_state = logical_state.physical_modes.clone();
614
615 let outcome = temp_state.heterodyne_measurement(mode, &config)?;
616
617 measurements.push(SyndromeMeasurement {
618 stabilizer_id: mode,
619 outcome: outcome.magnitude(),
620 expected_value: 1.0, uncertainty: self.config.error_model.displacement_std,
622 });
623 }
624
625 Ok(measurements)
626 }
627
628 pub async fn apply_correction(
630 &mut self,
631 syndrome: &CVSyndrome,
632 ) -> DeviceResult<CorrectionResult> {
633 if self.logical_state.is_none() {
634 return Err(DeviceError::InvalidInput(
635 "No logical state to correct".to_string(),
636 ));
637 }
638
639 println!(
640 "Applying error correction for syndrome {}",
641 syndrome.syndrome_id
642 );
643
644 let correction_operations = self.decode_syndrome(syndrome).await?;
646
647 let mut correction_success = true;
649 let mut applied_operations = 0;
650
651 for operation in &correction_operations {
652 match self.apply_correction_operation(operation).await {
653 Ok(_) => applied_operations += 1,
654 Err(_) => {
655 correction_success = false;
656 break;
657 }
658 }
659 }
660
661 let fidelity = if correction_success {
663 0.95 - syndrome
664 .measurements
665 .iter()
666 .map(|m| (m.outcome - m.expected_value).abs())
667 .sum::<f64>()
668 * 0.1
669 } else {
670 0.5
671 };
672
673 if correction_success {
675 self.correction_stats.successful_corrections += 1;
676 } else {
677 self.correction_stats.failed_corrections += 1;
678 }
679
680 let total_corrections =
681 self.correction_stats.successful_corrections + self.correction_stats.failed_corrections;
682 self.correction_stats.average_fidelity =
683 (self.correction_stats.average_fidelity * (total_corrections - 1) as f64 + fidelity)
684 / total_corrections as f64;
685
686 Ok(CorrectionResult {
687 syndrome_id: syndrome.syndrome_id,
688 correction_operations,
689 success: correction_success,
690 fidelity,
691 applied_operations,
692 })
693 }
694
695 async fn decode_syndrome(
697 &self,
698 syndrome: &CVSyndrome,
699 ) -> DeviceResult<Vec<CorrectionOperation>> {
700 match self.config.decoder_config.decoder_type {
701 CVDecoderType::MaximumLikelihood => self.ml_decode(syndrome).await,
702 CVDecoderType::MinimumDistance => self.minimum_distance_decode(syndrome).await,
703 _ => Err(DeviceError::UnsupportedOperation(
704 "Decoder type not implemented".to_string(),
705 )),
706 }
707 }
708
709 async fn ml_decode(&self, syndrome: &CVSyndrome) -> DeviceResult<Vec<CorrectionOperation>> {
711 let mut corrections = Vec::new();
712
713 for measurement in &syndrome.measurements {
714 let deviation = (measurement.outcome - measurement.expected_value).abs();
715
716 if deviation > self.config.syndrome_threshold {
717 let mode = measurement.stabilizer_id / 2;
719 let is_position = measurement.stabilizer_id % 2 == 0;
720
721 let correction_amplitude = if is_position {
722 Complex::new(-measurement.outcome, 0.0)
723 } else {
724 Complex::new(0.0, -measurement.outcome)
725 };
726
727 corrections.push(CorrectionOperation {
728 operation_type: CorrectionOperationType::Displacement {
729 mode,
730 amplitude: correction_amplitude,
731 },
732 confidence: measurement.uncertainty,
733 });
734 }
735 }
736
737 Ok(corrections)
738 }
739
740 async fn minimum_distance_decode(
742 &self,
743 syndrome: &CVSyndrome,
744 ) -> DeviceResult<Vec<CorrectionOperation>> {
745 let mut corrections = Vec::new();
747
748 let mut min_distance = f64::INFINITY;
750 let mut best_correction = None;
751
752 for measurement in &syndrome.measurements {
753 let distance = (measurement.outcome - measurement.expected_value).abs();
754
755 if distance < min_distance && distance > self.config.syndrome_threshold {
756 min_distance = distance;
757
758 let mode = measurement.stabilizer_id / 2;
759 let is_position = measurement.stabilizer_id % 2 == 0;
760
761 let correction_amplitude = if is_position {
762 Complex::new(-measurement.outcome * 0.5, 0.0)
763 } else {
764 Complex::new(0.0, -measurement.outcome * 0.5)
765 };
766
767 best_correction = Some(CorrectionOperation {
768 operation_type: CorrectionOperationType::Displacement {
769 mode,
770 amplitude: correction_amplitude,
771 },
772 confidence: 1.0 / (1.0 + distance),
773 });
774 }
775 }
776
777 if let Some(correction) = best_correction {
778 corrections.push(correction);
779 }
780
781 Ok(corrections)
782 }
783
784 async fn apply_correction_operation(
786 &mut self,
787 operation: &CorrectionOperation,
788 ) -> DeviceResult<()> {
789 if let Some(logical_state) = &mut self.logical_state {
790 match &operation.operation_type {
791 CorrectionOperationType::Displacement { mode, amplitude } => {
792 logical_state
793 .physical_modes
794 .apply_displacement(*mode, *amplitude)?;
795 }
796 CorrectionOperationType::Squeezing {
797 mode,
798 parameter,
799 phase,
800 } => {
801 logical_state
802 .physical_modes
803 .apply_squeezing(*mode, *parameter, *phase)?;
804 }
805 CorrectionOperationType::PhaseRotation { mode, phase } => {
806 logical_state
807 .physical_modes
808 .apply_phase_rotation(*mode, *phase)?;
809 }
810 }
811 }
812 Ok(())
813 }
814
815 pub fn get_correction_statistics(&self) -> &CorrectionStatistics {
817 &self.correction_stats
818 }
819
820 pub fn get_logical_state(&self) -> Option<&CVLogicalState> {
822 self.logical_state.as_ref()
823 }
824
825 pub fn get_syndrome_history(&self) -> &[CVSyndrome] {
827 &self.syndrome_history
828 }
829}
830
831#[derive(Debug, Clone, Serialize, Deserialize)]
833pub struct CorrectionOperation {
834 pub operation_type: CorrectionOperationType,
836 pub confidence: f64,
838}
839
840#[derive(Debug, Clone, Serialize, Deserialize)]
842pub enum CorrectionOperationType {
843 Displacement { mode: usize, amplitude: Complex },
845 Squeezing {
847 mode: usize,
848 parameter: f64,
849 phase: f64,
850 },
851 PhaseRotation { mode: usize, phase: f64 },
853}
854
855#[derive(Debug, Clone, Serialize, Deserialize)]
857pub struct CorrectionResult {
858 pub syndrome_id: usize,
860 pub correction_operations: Vec<CorrectionOperation>,
862 pub success: bool,
864 pub fidelity: f64,
866 pub applied_operations: usize,
868}
869
870#[cfg(test)]
871mod tests {
872 use super::*;
873
874 #[tokio::test]
875 async fn test_cv_error_corrector_creation() {
876 let config = CVErrorCorrectionConfig::default();
877 let corrector = CVErrorCorrector::new(config);
878 assert!(corrector.logical_state.is_none());
879 assert_eq!(corrector.syndrome_history.len(), 0);
880 }
881
882 #[tokio::test]
883 async fn test_gkp_state_initialization() {
884 let config = CVErrorCorrectionConfig::default();
885 let mut corrector = CVErrorCorrector::new(config);
886
887 let initial_state = GaussianState::vacuum_state(2);
888 let logical_state = corrector
889 .initialize_logical_state(initial_state)
890 .await
891 .unwrap();
892
893 assert_eq!(logical_state.physical_modes.num_modes, 2);
894 assert_eq!(logical_state.logical_info.len(), 1);
895 }
896
897 #[tokio::test]
898 async fn test_syndrome_measurement() {
899 let config = CVErrorCorrectionConfig::default();
900 let mut corrector = CVErrorCorrector::new(config);
901
902 let initial_state = GaussianState::vacuum_state(1);
903 corrector
904 .initialize_logical_state(initial_state)
905 .await
906 .unwrap();
907
908 let syndrome = corrector.measure_syndrome().await.unwrap();
909 assert_eq!(syndrome.syndrome_id, 0);
910 assert!(!syndrome.measurements.is_empty());
911 assert_eq!(corrector.syndrome_history.len(), 1);
912 }
913
914 #[tokio::test]
915 async fn test_error_correction() {
916 let config = CVErrorCorrectionConfig::default();
917 let mut corrector = CVErrorCorrector::new(config);
918
919 let initial_state = GaussianState::vacuum_state(1);
920 corrector
921 .initialize_logical_state(initial_state)
922 .await
923 .unwrap();
924
925 let syndrome = corrector.measure_syndrome().await.unwrap();
926 let result = corrector.apply_correction(&syndrome).await.unwrap();
927
928 assert_eq!(result.syndrome_id, syndrome.syndrome_id);
929 assert!(result.fidelity >= 0.0 && result.fidelity <= 1.0);
930 }
931
932 #[test]
933 fn test_gkp_logical_operators() {
934 let config = CVErrorCorrectionConfig::default();
935 let corrector = CVErrorCorrector::new(config);
936
937 let operators = corrector.build_gkp_logical_operators(0, PI.sqrt());
938
939 assert_eq!(operators.logical_x.displacements.len(), 1);
941 assert_eq!(operators.logical_z.displacements.len(), 1);
942 assert_eq!(operators.logical_y.displacements.len(), 1);
943 }
944
945 #[test]
946 fn test_error_model_defaults() {
947 let error_model = CVErrorModel::default();
948 assert!(error_model.displacement_std > 0.0);
949 assert!(error_model.phase_std > 0.0);
950 assert!(error_model.loss_probability >= 0.0 && error_model.loss_probability <= 1.0);
951 assert!(error_model.detector_efficiency >= 0.0 && error_model.detector_efficiency <= 1.0);
952 }
953
954 #[test]
955 fn test_correction_statistics() {
956 let corrector = CVErrorCorrector::new(CVErrorCorrectionConfig::default());
957 let stats = corrector.get_correction_statistics();
958
959 assert_eq!(stats.total_syndromes, 0);
960 assert_eq!(stats.successful_corrections, 0);
961 assert_eq!(stats.failed_corrections, 0);
962 }
963}