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