1mod adaptive_threshold;
15mod color_code;
16mod concatenated;
17mod decoders;
18mod hypergraph;
19mod ldpc;
20mod logical_gates;
21mod ml_decoder;
22mod pauli;
23mod pauli_frame;
24pub mod real_time;
25mod rotated_surface_code;
26mod stabilizer;
27mod surface_code;
28mod toric_code;
29
30pub use adaptive_threshold::*;
31pub use color_code::*;
32pub use concatenated::*;
33pub use decoders::*;
34pub use hypergraph::*;
35pub use ldpc::*;
36pub use logical_gates::*;
37pub use ml_decoder::*;
38pub use pauli::*;
39pub use pauli_frame::PauliFrame;
40pub use rotated_surface_code::RotatedSurfaceCode;
41pub use stabilizer::*;
42pub use surface_code::*;
43pub use toric_code::*;
44
45use crate::error::QuantRS2Result;
46
47pub trait SyndromeDecoder {
49 fn decode(&self, syndrome: &[bool]) -> QuantRS2Result<PauliString>;
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56 use scirs2_core::ndarray::Array2;
57 use scirs2_core::Complex64;
58
59 #[test]
60 fn test_pauli_multiplication() {
61 let (phase, result) = Pauli::X.multiply(&Pauli::Y);
62 assert_eq!(result, Pauli::Z);
63 assert_eq!(phase, Complex64::new(0.0, 1.0));
64 }
65
66 #[test]
67 fn test_pauli_string_commutation() {
68 let ps1 = PauliString::new(vec![Pauli::X, Pauli::I]);
69 let ps2 = PauliString::new(vec![Pauli::Z, Pauli::I]);
70 assert!(!ps1
71 .commutes_with(&ps2)
72 .expect("Commutation check should succeed"));
73
74 let ps3 = PauliString::new(vec![Pauli::X, Pauli::I]);
75 let ps4 = PauliString::new(vec![Pauli::I, Pauli::Z]);
76 assert!(ps3
77 .commutes_with(&ps4)
78 .expect("Commutation check should succeed"));
79 }
80
81 #[test]
82 fn test_repetition_code() {
83 let code = StabilizerCode::repetition_code();
84 assert_eq!(code.n, 3);
85 assert_eq!(code.k, 1);
86 assert_eq!(code.d, 1);
87
88 let error = PauliString::new(vec![Pauli::X, Pauli::I, Pauli::I]);
90 let syndrome = code
91 .syndrome(&error)
92 .expect("Syndrome extraction should succeed");
93 assert_eq!(syndrome, vec![true, false]);
95 }
96
97 #[test]
98 fn test_steane_code() {
99 let code = StabilizerCode::steane_code();
100 assert_eq!(code.n, 7);
101 assert_eq!(code.k, 1);
102 assert_eq!(code.d, 3);
103
104 for i in 0..code.stabilizers.len() {
106 for j in i + 1..code.stabilizers.len() {
107 assert!(code.stabilizers[i]
108 .commutes_with(&code.stabilizers[j])
109 .expect("Stabilizer commutation check should succeed"));
110 }
111 }
112 }
113
114 #[test]
115 fn test_surface_code() {
116 let surface = SurfaceCode::new(3, 3);
117 assert_eq!(surface.distance(), 3);
118
119 let code = surface
120 .to_stabilizer_code()
121 .expect("Surface code conversion should succeed");
122 assert_eq!(code.n, 9);
123 assert_eq!(code.stabilizers.len(), 4);
125 }
126
127 #[test]
128 fn test_lookup_decoder() {
129 let code = StabilizerCode::repetition_code();
130 let decoder = LookupDecoder::new(&code).expect("Lookup decoder creation should succeed");
131
132 let trivial_syndrome = vec![false, false];
134 let decoded = decoder
135 .decode(&trivial_syndrome)
136 .expect("Decoding trivial syndrome should succeed");
137 assert_eq!(decoded.weight(), 0); let error = PauliString::new(vec![Pauli::X, Pauli::I, Pauli::I]);
141 let syndrome = code
142 .syndrome(&error)
143 .expect("Syndrome extraction should succeed");
144
145 if let Ok(decoded_error) = decoder.decode(&syndrome) {
147 assert!(decoded_error.weight() <= 1);
149 }
150 }
151
152 #[test]
153 fn test_concatenated_codes() {
154 let inner_code = StabilizerCode::repetition_code();
155 let outer_code = StabilizerCode::repetition_code();
156 let concat_code = ConcatenatedCode::new(inner_code, outer_code);
157
158 assert_eq!(concat_code.total_qubits(), 9); assert_eq!(concat_code.logical_qubits(), 1);
160 assert_eq!(concat_code.distance(), 1); let logical_state = vec![Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)];
164 let encoded = concat_code
165 .encode(&logical_state)
166 .expect("Encoding should succeed");
167 assert_eq!(encoded.len(), 512); let error = PauliString::new(vec![
171 Pauli::X,
172 Pauli::I,
173 Pauli::I,
174 Pauli::I,
175 Pauli::I,
176 Pauli::I,
177 Pauli::I,
178 Pauli::I,
179 Pauli::I,
180 ]);
181 let corrected = concat_code
182 .correct_error(&encoded, &error)
183 .expect("Error correction should succeed");
184
185 assert_eq!(corrected.len(), 512);
187 }
188
189 #[test]
190 fn test_hypergraph_product_codes() {
191 let h1 = Array2::from_shape_vec((2, 3), vec![1, 1, 0, 0, 1, 1])
193 .expect("Array creation for h1 should succeed");
194 let h2 = Array2::from_shape_vec((2, 3), vec![1, 0, 1, 1, 1, 0])
195 .expect("Array creation for h2 should succeed");
196
197 let hpc = HypergraphProductCode::new(h1, h2);
198
199 assert_eq!(hpc.n, 12); assert_eq!(hpc.k, 1); let stab_code = hpc
204 .to_stabilizer_code()
205 .expect("Hypergraph product code conversion should succeed");
206 assert!(!stab_code.stabilizers.is_empty());
207 }
208
209 #[test]
210 fn test_quantum_ldpc_codes() {
211 let qldpc = QuantumLDPCCode::bicycle_code(3, 4);
212 assert_eq!(qldpc.n, 24); assert_eq!(qldpc.k, 2);
214
215 let stab_code = qldpc
216 .to_stabilizer_code()
217 .expect("Quantum LDPC code conversion should succeed");
218 assert!(!stab_code.stabilizers.is_empty());
219
220 for stabilizer in &stab_code.stabilizers {
222 assert!(stabilizer.weight() <= qldpc.max_weight);
223 }
224 }
225
226 #[test]
227 fn test_topological_codes() {
228 let toric = ToricCode::new(2, 2);
229 assert_eq!(toric.logical_qubits(), 2);
230 assert_eq!(toric.distance(), 2);
231
232 let stab_code = toric
233 .to_stabilizer_code()
234 .expect("Toric code conversion should succeed");
235 assert_eq!(stab_code.n, 8); assert_eq!(stab_code.k, 2);
237
238 for i in 0..stab_code.stabilizers.len() {
240 for j in i + 1..stab_code.stabilizers.len() {
241 assert!(stab_code.stabilizers[i]
242 .commutes_with(&stab_code.stabilizers[j])
243 .expect("Stabilizer commutation check should succeed"));
244 }
245 }
246 }
247
248 #[test]
249 fn test_ml_decoder() {
250 let surface = SurfaceCode::new(3, 3);
251 let decoder = MLDecoder::new(
252 surface
253 .to_stabilizer_code()
254 .expect("Surface code conversion should succeed"),
255 );
256
257 let syndrome = vec![true, false, true, false];
259 let decoded = decoder.decode(&syndrome);
260
261 assert!(decoded.is_ok() || syndrome.iter().filter(|&&x| x).count() % 2 == 1);
263 }
264
265 #[test]
266 fn test_real_time_mock_hardware() {
267 use crate::error_correction::real_time::*;
268 use std::time::Duration;
269
270 let hardware = MockQuantumHardware::new(0.01, Duration::from_micros(10), 4);
271
272 let syndrome = hardware
274 .measure_syndromes()
275 .expect("Syndrome measurement should succeed");
276 assert_eq!(syndrome.len(), 4);
277
278 let characteristics = hardware
280 .get_error_characteristics()
281 .expect("Getting error characteristics should succeed");
282 assert_eq!(characteristics.single_qubit_error_rates.len(), 4);
283
284 let stats = hardware
286 .get_latency_stats()
287 .expect("Getting latency stats should succeed");
288 assert!(stats.throughput_hz > 0.0);
289
290 assert!(hardware.is_ready());
291 }
292
293 #[test]
294 fn test_real_time_performance_monitor() {
295 use crate::error_correction::real_time::*;
296 use std::time::Duration;
297
298 let mut monitor = PerformanceMonitor::new();
299
300 monitor.record_cycle(Duration::from_micros(10), true);
302 monitor.record_cycle(Duration::from_micros(20), false);
303 monitor.record_cycle(Duration::from_micros(15), true);
304
305 assert_eq!(monitor.cycles_processed, 3);
306 assert_eq!(monitor.errors_corrected, 2);
307 assert_eq!(monitor.error_correction_rate(), 2.0 / 3.0);
308 assert!(monitor.average_latency().as_micros() > 10);
309 assert!(monitor.current_throughput() > 0.0);
310 }
311
312 #[test]
313 fn test_real_time_adaptive_decoder() {
314 use crate::error_correction::real_time::*;
315 use std::sync::Arc;
316
317 let code = StabilizerCode::repetition_code();
318 let base_decoder =
319 Arc::new(LookupDecoder::new(&code).expect("Lookup decoder creation should succeed"));
320 let characteristics = HardwareErrorCharacteristics {
321 single_qubit_error_rates: vec![0.01; 3],
322 two_qubit_error_rates: vec![0.1; 1],
323 measurement_error_rates: vec![0.001; 3],
324 correlated_errors: Vec::new(),
325 temporal_variation: 0.01,
326 };
327
328 let mut adaptive_decoder = AdaptiveThresholdDecoder::new(base_decoder, characteristics);
329
330 let initial_threshold = adaptive_decoder.current_threshold();
332 assert_eq!(initial_threshold, 1.0); adaptive_decoder.adapt_thresholds(&[false, false], true); let new_threshold = adaptive_decoder.current_threshold();
338 assert!(new_threshold != initial_threshold); let syndrome = vec![false, false]; let result = adaptive_decoder.decode(&syndrome);
343 assert!(result.is_ok(), "Decoding failed: {:?}", result.err());
344 }
345
346 #[test]
347 fn test_real_time_parallel_decoder() {
348 use crate::error_correction::real_time::*;
349 use std::sync::Arc;
350
351 let code = StabilizerCode::repetition_code();
352 let base_decoder =
353 Arc::new(LookupDecoder::new(&code).expect("Lookup decoder creation should succeed"));
354 let parallel_decoder = ParallelSyndromeDecoder::new(base_decoder, 2);
355
356 let syndrome = vec![false, false]; let result = parallel_decoder.decode(&syndrome);
359 assert!(result.is_ok(), "Decoding failed: {:?}", result.err());
360
361 let syndromes = vec![
363 vec![false, false], vec![false, false],
365 vec![false, false],
366 vec![false, false],
367 ];
368
369 let results = parallel_decoder.decode_batch(&syndromes);
370 assert!(results.is_ok());
371 let corrections = results.expect("Batch decoding should succeed");
372 assert_eq!(corrections.len(), 4);
373 }
374
375 #[test]
376 fn test_real_time_syndrome_stream_processor() {
377 use crate::error_correction::real_time::*;
378 use std::sync::Arc;
379 use std::time::Duration;
380
381 let code = StabilizerCode::repetition_code();
382 let decoder =
383 Arc::new(LookupDecoder::new(&code).expect("Lookup decoder creation should succeed"));
384 let hardware = Arc::new(MockQuantumHardware::new(0.01, Duration::from_micros(1), 3));
385 let config = RealTimeConfig {
386 max_latency: Duration::from_millis(1),
387 buffer_size: 10,
388 parallel_workers: 1,
389 adaptive_threshold: false,
390 hardware_feedback: false,
391 performance_logging: true,
392 };
393
394 let processor = SyndromeStreamProcessor::new(decoder, hardware, config);
395
396 let (current, max) = processor.get_buffer_status();
398 assert_eq!(current, 0);
399 assert_eq!(max, 10);
400
401 let stats = processor.get_performance_stats();
403 assert_eq!(stats.cycles_processed, 0);
404 assert_eq!(stats.errors_corrected, 0);
405 }
406
407 #[test]
408 fn test_logical_gate_synthesizer() {
409 use crate::error_correction::logical_gates::*;
410
411 let code = StabilizerCode::repetition_code();
412 let synthesizer = LogicalGateSynthesizer::new(0.01);
413
414 let logical_x = synthesizer.synthesize_logical_x(&code, 0);
416 assert!(logical_x.is_ok());
417
418 let x_gate = logical_x.expect("Logical X synthesis should succeed");
419 assert_eq!(x_gate.logical_qubits, vec![0]);
420 assert_eq!(x_gate.physical_operations.len(), 1);
421 assert!(!x_gate.error_propagation.single_qubit_propagation.is_empty());
422
423 let logical_z = synthesizer.synthesize_logical_z(&code, 0);
425 assert!(logical_z.is_ok());
426
427 let z_gate = logical_z.expect("Logical Z synthesis should succeed");
428 assert_eq!(z_gate.logical_qubits, vec![0]);
429 assert_eq!(z_gate.physical_operations.len(), 1);
430
431 let logical_h = synthesizer.synthesize_logical_h(&code, 0);
433 assert!(logical_h.is_ok());
434
435 let h_gate = logical_h.expect("Logical H synthesis should succeed");
436 assert_eq!(h_gate.logical_qubits, vec![0]);
437 assert_eq!(h_gate.physical_operations.len(), 1);
438 assert_eq!(h_gate.physical_operations[0].error_correction_rounds, 2);
439
440 let invalid_gate = synthesizer.synthesize_logical_x(&code, 5);
442 assert!(invalid_gate.is_err());
443 }
444
445 #[test]
446 fn test_logical_circuit_synthesizer() {
447 use crate::error_correction::logical_gates::*;
448
449 let code = StabilizerCode::repetition_code();
450 let synthesizer = LogicalCircuitSynthesizer::new(0.01);
451
452 let gate_sequence = vec![("x", vec![0]), ("h", vec![0]), ("z", vec![0])];
454
455 let circuit = synthesizer.synthesize_circuit(&code, &gate_sequence);
456 assert!(circuit.is_ok());
457
458 let logical_circuit = circuit.expect("Circuit synthesis should succeed");
459 assert_eq!(logical_circuit.len(), 3);
460
461 let resources = synthesizer.estimate_resources(&logical_circuit);
463 assert!(resources.total_physical_operations > 0);
464 assert!(resources.total_error_correction_rounds > 0);
465 assert_eq!(resources.estimated_depth, 3);
466
467 let invalid_sequence = vec![("invalid_gate", vec![0])];
469 let invalid_circuit = synthesizer.synthesize_circuit(&code, &invalid_sequence);
470 assert!(invalid_circuit.is_err());
471
472 let wrong_cnot = vec![("cnot", vec![0])]; let wrong_circuit = synthesizer.synthesize_circuit(&code, &wrong_cnot);
475 assert!(wrong_circuit.is_err());
476 }
477
478 #[test]
479 fn test_logical_t_gate_synthesis() {
480 use crate::error_correction::logical_gates::*;
481
482 let code = StabilizerCode::repetition_code();
483 let synthesizer = LogicalGateSynthesizer::new(0.01);
484
485 let logical_t = synthesizer.synthesize_logical_t(&code, 0);
487 assert!(logical_t.is_ok());
488
489 let t_gate = logical_t.expect("Logical T synthesis should succeed");
490 assert_eq!(t_gate.logical_qubits, vec![0]);
491 assert_eq!(t_gate.physical_operations.len(), 2); assert!(t_gate.physical_operations[0].error_correction_rounds >= 5);
495 }
496
497 #[test]
498 fn test_error_propagation_analysis() {
499 use crate::error_correction::logical_gates::*;
500
501 let code = StabilizerCode::repetition_code();
502 let synthesizer = LogicalGateSynthesizer::new(0.01);
503
504 let logical_x = synthesizer
505 .synthesize_logical_x(&code, 0)
506 .expect("Logical X synthesis should succeed");
507
508 let analysis = &logical_x.error_propagation;
510 assert!(!analysis.single_qubit_propagation.is_empty());
511 assert_eq!(analysis.fault_tolerance_threshold, 0.01);
513
514 let correctable_count = analysis
516 .single_qubit_propagation
517 .iter()
518 .filter(|path| path.correctable)
519 .count();
520 assert!(correctable_count > 0);
521 }
522
523 #[test]
524 fn test_pauli_string_weight() {
525 let identity_string = PauliString::new(vec![Pauli::I, Pauli::I, Pauli::I]);
526 assert_eq!(identity_string.weight(), 0);
527
528 let single_error = PauliString::new(vec![Pauli::X, Pauli::I, Pauli::I]);
529 assert_eq!(single_error.weight(), 1);
530
531 let multi_error = PauliString::new(vec![Pauli::X, Pauli::Y, Pauli::Z]);
532 assert_eq!(multi_error.weight(), 3);
533 }
534
535 #[test]
536 fn test_logical_circuit_with_multiple_gates() {
537 use crate::error_correction::logical_gates::*;
538
539 let code = StabilizerCode::repetition_code();
540 let synthesizer = LogicalCircuitSynthesizer::new(0.01);
541
542 let gate_sequence = vec![
544 ("h", vec![0]), ("x", vec![0]), ("z", vec![0]), ("h", vec![0]), ];
549
550 let circuit = synthesizer.synthesize_circuit(&code, &gate_sequence);
551 assert!(circuit.is_ok());
552
553 let logical_circuit = circuit.expect("Circuit synthesis should succeed");
554 assert_eq!(logical_circuit.len(), 4);
555
556 for gate in &logical_circuit {
558 assert_eq!(gate.logical_qubits, vec![0]);
559 }
560
561 let resources = synthesizer.estimate_resources(&logical_circuit);
563 assert_eq!(resources.estimated_depth, 4);
564 assert!(resources.total_error_correction_rounds >= 4); }
566
567 #[test]
568 fn test_adaptive_threshold_estimator() {
569 use crate::error_correction::adaptive_threshold::*;
570
571 let noise_model = NoiseModel::default();
572 let algorithm = ThresholdEstimationAlgorithm::Bayesian {
573 prior_strength: 1.0,
574 update_rate: 0.1,
575 };
576 let config = AdaptiveConfig::default();
577
578 let mut estimator = AdaptiveThresholdEstimator::new(noise_model, algorithm, config);
579
580 let syndrome = vec![true, false];
582 let env = EnvironmentalConditions::default();
583 let threshold = estimator.estimate_threshold(&syndrome, &env);
584 assert!(threshold > 0.0);
585 assert!(threshold < 1.0);
586
587 let observation = ErrorObservation {
589 syndrome: syndrome.clone(),
590 correction: PauliString::new(vec![Pauli::X, Pauli::I]),
591 success: true,
592 observed_error_rate: 0.01,
593 timestamp: std::time::Instant::now(),
594 environment: env.clone(),
595 };
596
597 estimator.add_observation(observation);
598
599 let recommendation = estimator.get_threshold_recommendation(&syndrome);
601 assert!(recommendation.threshold > 0.0);
602 assert!(recommendation.confidence >= 0.0 && recommendation.confidence <= 1.0);
603 assert!(recommendation.predicted_error_rate >= 0.0);
604 }
605
606 #[test]
607 fn test_performance_tracker() {
608 use crate::error_correction::adaptive_threshold::*;
609
610 let mut tracker = PerformanceTracker::new();
611
612 assert_eq!(tracker.successful_corrections, 0);
614 assert_eq!(tracker.failed_corrections, 0);
615 assert_eq!(tracker.precision(), 1.0); assert_eq!(tracker.recall(), 1.0);
617 assert_eq!(tracker.f1_score(), 1.0); tracker.successful_corrections = 8;
621 tracker.failed_corrections = 2;
622 tracker.false_positives = 1;
623 tracker.false_negatives = 1;
624
625 assert_eq!(tracker.precision(), 8.0 / 9.0); assert_eq!(tracker.recall(), 8.0 / 9.0); assert!(tracker.f1_score() > 0.0);
629 }
630
631 #[test]
632 fn test_environmental_conditions() {
633 use crate::error_correction::adaptive_threshold::*;
634
635 let mut env = EnvironmentalConditions::default();
636 assert_eq!(env.temperature, 300.0); assert_eq!(env.magnetic_field, 0.0);
638
639 env.temperature = 310.0; env.vibration_level = 0.1;
642
643 let noise_model = NoiseModel::default();
644 let algorithm = ThresholdEstimationAlgorithm::ExponentialAverage { alpha: 0.5 };
645 let config = AdaptiveConfig::default();
646
647 let estimator = AdaptiveThresholdEstimator::new(noise_model, algorithm, config);
648
649 let syndrome = vec![false, false];
651 let threshold_normal =
652 estimator.estimate_threshold(&syndrome, &EnvironmentalConditions::default());
653 let threshold_hot = estimator.estimate_threshold(&syndrome, &env);
654
655 assert!(threshold_normal >= 0.0);
657 assert!(threshold_hot >= 0.0);
658 }
659
660 #[test]
661 fn test_different_threshold_algorithms() {
662 use crate::error_correction::adaptive_threshold::*;
663
664 let noise_model = NoiseModel::default();
665 let config = AdaptiveConfig::default();
666
667 let bayesian_alg = ThresholdEstimationAlgorithm::Bayesian {
669 prior_strength: 1.0,
670 update_rate: 0.1,
671 };
672 let bayesian_estimator =
673 AdaptiveThresholdEstimator::new(noise_model.clone(), bayesian_alg, config.clone());
674
675 let kalman_alg = ThresholdEstimationAlgorithm::KalmanFilter {
677 process_noise: 0.01,
678 measurement_noise: 0.1,
679 };
680 let kalman_estimator =
681 AdaptiveThresholdEstimator::new(noise_model.clone(), kalman_alg, config.clone());
682
683 let exp_alg = ThresholdEstimationAlgorithm::ExponentialAverage { alpha: 0.3 };
685 let exp_estimator =
686 AdaptiveThresholdEstimator::new(noise_model.clone(), exp_alg, config.clone());
687
688 let ml_alg = ThresholdEstimationAlgorithm::MachineLearning {
690 model_type: MLModelType::LinearRegression,
691 training_window: 50,
692 };
693 let ml_estimator = AdaptiveThresholdEstimator::new(noise_model, ml_alg, config);
694
695 let syndrome = vec![true, false];
696 let env = EnvironmentalConditions::default();
697
698 let bayesian_threshold = bayesian_estimator.estimate_threshold(&syndrome, &env);
700 let kalman_threshold = kalman_estimator.estimate_threshold(&syndrome, &env);
701 let exp_threshold = exp_estimator.estimate_threshold(&syndrome, &env);
702 let ml_threshold = ml_estimator.estimate_threshold(&syndrome, &env);
703
704 assert!(bayesian_threshold > 0.0);
705 assert!(kalman_threshold > 0.0);
706 assert!(exp_threshold > 0.0);
707 assert!(ml_threshold > 0.0);
708 }
709
710 #[test]
711 fn test_noise_model_updates() {
712 use crate::error_correction::adaptive_threshold::*;
713
714 let noise_model = NoiseModel::default();
715 let algorithm = ThresholdEstimationAlgorithm::Bayesian {
716 prior_strength: 1.0,
717 update_rate: 0.1,
718 };
719 let config = AdaptiveConfig {
720 min_observations: 2, real_time_adaptation: true,
722 ..AdaptiveConfig::default()
723 };
724
725 let mut estimator = AdaptiveThresholdEstimator::new(noise_model, algorithm, config);
726
727 for i in 0..5 {
729 let observation = ErrorObservation {
730 syndrome: vec![i % 2 == 0, i % 3 == 0],
731 correction: PauliString::new(vec![Pauli::X, Pauli::I]),
732 success: i % 4 != 0, observed_error_rate: 0.01,
734 timestamp: std::time::Instant::now(),
735 environment: EnvironmentalConditions::default(),
736 };
737 estimator.add_observation(observation);
738 }
739
740 let recommendation = estimator.get_threshold_recommendation(&[true, false]);
742 assert!(recommendation.confidence > 0.0);
743 assert!(recommendation.recommendation_quality > 0.0);
744 }
745}