1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::f64::consts::PI;
9use std::time::Duration;
10use thiserror::Error;
11
12use crate::{CircuitExecutor, DeviceError, DeviceResult, QuantumDevice};
13use scirs2_core::random::prelude::*;
14
15pub mod anyons;
16pub mod braiding;
17pub mod device;
18pub mod error_correction;
19pub mod fusion;
20pub mod topological_codes;
21
22#[derive(Error, Debug)]
24pub enum TopologicalError {
25 #[error("Anyon creation failed: {0}")]
26 AnyonCreationFailed(String),
27 #[error("Invalid braiding operation: {0}")]
28 InvalidBraiding(String),
29 #[error("Fusion operation failed: {0}")]
30 FusionFailed(String),
31 #[error("Topological charge mismatch: expected {expected}, got {actual}")]
32 TopologicalChargeMismatch { expected: String, actual: String },
33 #[error("Insufficient anyons: needed {needed}, available {available}")]
34 InsufficientAnyons { needed: usize, available: usize },
35 #[error("Invalid worldline configuration: {0}")]
36 InvalidWorldline(String),
37 #[error("Invalid input: {0}")]
38 InvalidInput(String),
39}
40
41pub type TopologicalResult<T> = Result<T, TopologicalError>;
42
43#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
45pub enum TopologicalSystemType {
46 Majorana {
48 wire_count: usize,
49 coupling_strength: f64,
50 },
51 Abelian {
53 filling_factor: f64,
54 braiding_group: String,
55 },
56 NonAbelian {
58 anyon_type: NonAbelianAnyonType,
59 fusion_rules: FusionRuleSet,
60 },
61 Parafermion {
63 order: usize,
64 symmetry_group: String,
65 },
66}
67
68#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
70pub enum NonAbelianAnyonType {
71 Fibonacci,
73 Ising,
75 SU2 { level: usize },
77 Metaplectic,
79 JonesKauffman,
81}
82
83#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
85pub struct TopologicalCharge {
86 pub label: String,
88 pub quantum_dimension: String, pub scaling_dimension: f64,
92}
93
94impl Eq for TopologicalCharge {}
95
96impl std::hash::Hash for TopologicalCharge {
97 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
98 self.label.hash(state);
99 self.quantum_dimension.hash(state);
100 self.scaling_dimension.to_bits().hash(state);
102 }
103}
104
105impl TopologicalCharge {
106 pub fn identity() -> Self {
108 Self {
109 label: "I".to_string(),
110 quantum_dimension: "1".to_string(),
111 scaling_dimension: 0.0,
112 }
113 }
114
115 pub fn fibonacci_tau() -> Self {
117 Self {
118 label: "τ".to_string(),
119 quantum_dimension: "φ".to_string(), scaling_dimension: 2.0 / 5.0,
121 }
122 }
123
124 pub fn ising_sigma() -> Self {
126 Self {
127 label: "σ".to_string(),
128 quantum_dimension: "√2".to_string(),
129 scaling_dimension: 1.0 / 16.0,
130 }
131 }
132
133 pub fn ising_psi() -> Self {
135 Self {
136 label: "ψ".to_string(),
137 quantum_dimension: "1".to_string(),
138 scaling_dimension: 1.0 / 2.0,
139 }
140 }
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
145pub struct Anyon {
146 pub anyon_id: usize,
148 pub charge: TopologicalCharge,
150 pub position: (f64, f64),
152 pub is_qubit_part: bool,
154 pub qubit_id: Option<usize>,
156 pub creation_time: f64,
158}
159
160#[derive(Debug, Clone, Serialize, Deserialize)]
162pub struct TopologicalQubit {
163 pub qubit_id: usize,
165 pub anyons: Vec<usize>, pub state: TopologicalQubitState,
169 pub fusion_channel: Option<String>,
171 pub braiding_history: Vec<BraidingOperation>,
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct TopologicalQubitState {
178 pub amplitude_0: f64,
180 pub amplitude_1: f64,
182 pub phase: f64,
184 pub protection_factor: f64,
186}
187
188impl TopologicalQubitState {
189 pub const fn zero() -> Self {
191 Self {
192 amplitude_0: 1.0,
193 amplitude_1: 0.0,
194 phase: 0.0,
195 protection_factor: 1.0,
196 }
197 }
198
199 pub const fn one() -> Self {
201 Self {
202 amplitude_0: 0.0,
203 amplitude_1: 1.0,
204 phase: 0.0,
205 protection_factor: 1.0,
206 }
207 }
208
209 pub fn plus() -> Self {
211 Self {
212 amplitude_0: 1.0 / (2.0_f64).sqrt(),
213 amplitude_1: 1.0 / (2.0_f64).sqrt(),
214 phase: 0.0,
215 protection_factor: 1.0,
216 }
217 }
218
219 pub fn prob_zero(&self) -> f64 {
221 self.amplitude_0 * self.amplitude_0
222 }
223
224 pub fn prob_one(&self) -> f64 {
226 self.amplitude_1 * self.amplitude_1
227 }
228}
229
230#[derive(Debug, Clone, Serialize, Deserialize)]
232pub struct BraidingOperation {
233 pub operation_id: usize,
235 pub anyon1: usize,
237 pub anyon2: usize,
239 pub direction: BraidingDirection,
241 pub braid_count: usize,
243 pub result: BraidingResult,
245 pub timestamp: f64,
247}
248
249#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
251pub enum BraidingDirection {
252 Clockwise,
253 Counterclockwise,
254}
255
256#[derive(Debug, Clone, Serialize, Deserialize)]
258pub enum BraidingResult {
259 Phase(f64),
261 FusionChannel(String),
263 UnitaryMatrix(Vec<Vec<f64>>),
265}
266
267#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
269pub struct FusionRuleSet {
270 pub anyon_type: NonAbelianAnyonType,
272 pub rules: HashMap<(String, String), Vec<String>>,
274 pub f_symbols: HashMap<String, f64>,
276 pub r_symbols: HashMap<String, Vec<Vec<f64>>>,
278}
279
280impl FusionRuleSet {
281 pub fn fibonacci() -> Self {
283 let mut rules = HashMap::new();
284 rules.insert(("I".to_string(), "I".to_string()), vec!["I".to_string()]);
285 rules.insert(("I".to_string(), "τ".to_string()), vec!["τ".to_string()]);
286 rules.insert(("τ".to_string(), "I".to_string()), vec!["τ".to_string()]);
287 rules.insert(
288 ("τ".to_string(), "τ".to_string()),
289 vec!["I".to_string(), "τ".to_string()],
290 );
291
292 Self {
293 anyon_type: NonAbelianAnyonType::Fibonacci,
294 rules,
295 f_symbols: HashMap::new(), r_symbols: HashMap::new(), }
298 }
299
300 pub fn ising() -> Self {
302 let mut rules = HashMap::new();
303 rules.insert(("I".to_string(), "I".to_string()), vec!["I".to_string()]);
304 rules.insert(("I".to_string(), "σ".to_string()), vec!["σ".to_string()]);
305 rules.insert(("I".to_string(), "ψ".to_string()), vec!["ψ".to_string()]);
306 rules.insert(("σ".to_string(), "I".to_string()), vec!["σ".to_string()]);
307 rules.insert(
308 ("σ".to_string(), "σ".to_string()),
309 vec!["I".to_string(), "ψ".to_string()],
310 );
311 rules.insert(("σ".to_string(), "ψ".to_string()), vec!["σ".to_string()]);
312 rules.insert(("ψ".to_string(), "I".to_string()), vec!["ψ".to_string()]);
313 rules.insert(("ψ".to_string(), "σ".to_string()), vec!["σ".to_string()]);
314 rules.insert(("ψ".to_string(), "ψ".to_string()), vec!["I".to_string()]);
315
316 Self {
317 anyon_type: NonAbelianAnyonType::Ising,
318 rules,
319 f_symbols: HashMap::new(),
320 r_symbols: HashMap::new(),
321 }
322 }
323}
324
325#[derive(Debug)]
327pub struct TopologicalDevice {
328 pub system_type: TopologicalSystemType,
330 pub fusion_rules: FusionRuleSet,
332 pub anyons: HashMap<usize, Anyon>,
334 pub qubits: HashMap<usize, TopologicalQubit>,
336 pub capabilities: TopologicalCapabilities,
338 pub next_anyon_id: usize,
340 pub next_qubit_id: usize,
341 pub current_time: f64,
343}
344
345#[derive(Debug, Clone, Serialize, Deserialize)]
347pub struct TopologicalCapabilities {
348 pub max_anyons: usize,
350 pub max_qubits: usize,
352 pub supported_anyons: Vec<TopologicalCharge>,
354 pub available_operations: Vec<TopologicalOperation>,
356 pub braiding_fidelity: f64,
358 pub fusion_fidelity: f64,
360 pub topological_gap: f64,
362 pub coherence_length: f64,
364}
365
366#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
368pub enum TopologicalOperation {
369 AnyonCreation { charge_type: String },
371 Braiding { direction: BraidingDirection },
373 Fusion,
375 Measurement,
377 AnyonTransport,
379}
380
381impl TopologicalDevice {
382 pub fn new(
384 system_type: TopologicalSystemType,
385 fusion_rules: FusionRuleSet,
386 capabilities: TopologicalCapabilities,
387 ) -> Self {
388 Self {
389 system_type,
390 fusion_rules,
391 anyons: HashMap::new(),
392 qubits: HashMap::new(),
393 capabilities,
394 next_anyon_id: 0,
395 next_qubit_id: 0,
396 current_time: 0.0,
397 }
398 }
399
400 pub fn create_anyon_pair(
402 &mut self,
403 charge: TopologicalCharge,
404 positions: [(f64, f64); 2],
405 ) -> TopologicalResult<(usize, usize)> {
406 if self.anyons.len() + 2 > self.capabilities.max_anyons {
407 return Err(TopologicalError::InsufficientAnyons {
408 needed: 2,
409 available: self.capabilities.max_anyons - self.anyons.len(),
410 });
411 }
412
413 let anyon1_id = self.next_anyon_id;
414 self.next_anyon_id += 1;
415 let anyon2_id = self.next_anyon_id;
416 self.next_anyon_id += 1;
417
418 let anyon1 = Anyon {
419 anyon_id: anyon1_id,
420 charge: charge.clone(),
421 position: positions[0],
422 is_qubit_part: false,
423 qubit_id: None,
424 creation_time: self.current_time,
425 };
426
427 let anyon2 = Anyon {
429 anyon_id: anyon2_id,
430 charge,
431 position: positions[1],
432 is_qubit_part: false,
433 qubit_id: None,
434 creation_time: self.current_time,
435 };
436
437 self.anyons.insert(anyon1_id, anyon1);
438 self.anyons.insert(anyon2_id, anyon2);
439
440 Ok((anyon1_id, anyon2_id))
441 }
442
443 pub fn create_topological_qubit(&mut self, anyon_ids: Vec<usize>) -> TopologicalResult<usize> {
445 if self.qubits.len() >= self.capabilities.max_qubits {
446 return Err(TopologicalError::InsufficientAnyons {
447 needed: 1,
448 available: self.capabilities.max_qubits - self.qubits.len(),
449 });
450 }
451
452 for &anyon_id in &anyon_ids {
454 if let Some(anyon) = self.anyons.get(&anyon_id) {
455 if anyon.is_qubit_part {
456 return Err(TopologicalError::AnyonCreationFailed(format!(
457 "Anyon {anyon_id} is already part of a qubit"
458 )));
459 }
460 } else {
461 return Err(TopologicalError::AnyonCreationFailed(format!(
462 "Anyon {anyon_id} not found"
463 )));
464 }
465 }
466
467 let qubit_id = self.next_qubit_id;
468 self.next_qubit_id += 1;
469
470 for &anyon_id in &anyon_ids {
472 if let Some(anyon) = self.anyons.get_mut(&anyon_id) {
473 anyon.is_qubit_part = true;
474 anyon.qubit_id = Some(qubit_id);
475 }
476 }
477
478 let qubit = TopologicalQubit {
479 qubit_id,
480 anyons: anyon_ids,
481 state: TopologicalQubitState::zero(),
482 fusion_channel: None,
483 braiding_history: Vec::new(),
484 };
485
486 self.qubits.insert(qubit_id, qubit);
487 Ok(qubit_id)
488 }
489
490 pub fn braid_anyons(
492 &mut self,
493 anyon1_id: usize,
494 anyon2_id: usize,
495 direction: BraidingDirection,
496 braid_count: usize,
497 ) -> TopologicalResult<BraidingResult> {
498 let anyon1 = self.anyons.get(&anyon1_id).ok_or_else(|| {
500 TopologicalError::InvalidBraiding(format!("Anyon {anyon1_id} not found"))
501 })?;
502 let anyon2 = self.anyons.get(&anyon2_id).ok_or_else(|| {
503 TopologicalError::InvalidBraiding(format!("Anyon {anyon2_id} not found"))
504 })?;
505
506 let result = self.calculate_braiding_result(
508 &anyon1.charge,
509 &anyon2.charge,
510 &direction,
511 braid_count,
512 )?;
513
514 let operation = BraidingOperation {
516 operation_id: self.anyons.len(), anyon1: anyon1_id,
518 anyon2: anyon2_id,
519 direction,
520 braid_count,
521 result: result.clone(),
522 timestamp: self.current_time,
523 };
524
525 if let (Some(qubit1_id), Some(qubit2_id)) = (anyon1.qubit_id, anyon2.qubit_id) {
527 if qubit1_id == qubit2_id {
528 if let Some(qubit) = self.qubits.get_mut(&qubit1_id) {
530 qubit.braiding_history.push(operation);
531 Self::apply_braiding_to_qubit_state_static(qubit, &result)?;
532 }
533 }
534 }
535
536 self.current_time += 1.0;
537 Ok(result)
538 }
539
540 fn calculate_braiding_result(
542 &self,
543 charge1: &TopologicalCharge,
544 charge2: &TopologicalCharge,
545 direction: &BraidingDirection,
546 braid_count: usize,
547 ) -> TopologicalResult<BraidingResult> {
548 match self.fusion_rules.anyon_type {
549 NonAbelianAnyonType::Fibonacci => {
550 if charge1.label == "τ" && charge2.label == "τ" {
552 let phase = match direction {
553 BraidingDirection::Clockwise => -4.0 * PI / 5.0,
554 BraidingDirection::Counterclockwise => 4.0 * PI / 5.0,
555 } * braid_count as f64;
556 Ok(BraidingResult::Phase(phase))
557 } else {
558 Ok(BraidingResult::Phase(0.0))
559 }
560 }
561 NonAbelianAnyonType::Ising => {
562 if charge1.label == "σ" && charge2.label == "σ" {
564 let phase = match direction {
565 BraidingDirection::Clockwise => PI / 8.0,
566 BraidingDirection::Counterclockwise => -PI / 8.0,
567 } * braid_count as f64;
568 Ok(BraidingResult::Phase(phase))
569 } else {
570 Ok(BraidingResult::Phase(0.0))
571 }
572 }
573 _ => {
574 Ok(BraidingResult::Phase(0.0))
576 }
577 }
578 }
579
580 fn apply_braiding_to_qubit_state(
582 &self,
583 qubit: &mut TopologicalQubit,
584 result: &BraidingResult,
585 ) -> TopologicalResult<()> {
586 match result {
587 BraidingResult::Phase(phase) => {
588 qubit.state.phase += phase;
589 qubit.state.protection_factor *= 0.9999;
591 }
592 BraidingResult::FusionChannel(channel) => {
593 qubit.fusion_channel = Some(channel.clone());
594 }
595 BraidingResult::UnitaryMatrix(matrix) => {
596 qubit.state.protection_factor *= 0.9999;
599 }
600 }
601 Ok(())
602 }
603
604 fn apply_braiding_to_qubit_state_static(
606 qubit: &mut TopologicalQubit,
607 result: &BraidingResult,
608 ) -> TopologicalResult<()> {
609 match result {
610 BraidingResult::Phase(phase) => {
611 qubit.state.phase += phase;
612 qubit.state.protection_factor *= 0.9999;
614 }
615 BraidingResult::FusionChannel(channel) => {
616 qubit.fusion_channel = Some(channel.clone());
617 }
618 BraidingResult::UnitaryMatrix(matrix) => {
619 qubit.state.protection_factor *= 0.9999;
622 }
623 }
624 Ok(())
625 }
626
627 pub fn fuse_anyons(
629 &mut self,
630 anyon1_id: usize,
631 anyon2_id: usize,
632 ) -> TopologicalResult<Vec<String>> {
633 let anyon1 = self
634 .anyons
635 .get(&anyon1_id)
636 .ok_or_else(|| TopologicalError::FusionFailed(format!("Anyon {anyon1_id} not found")))?
637 .clone();
638 let anyon2 = self
639 .anyons
640 .get(&anyon2_id)
641 .ok_or_else(|| TopologicalError::FusionFailed(format!("Anyon {anyon2_id} not found")))?
642 .clone();
643
644 let fusion_key = (anyon1.charge.label.clone(), anyon2.charge.label.clone());
646 let fusion_products = self.fusion_rules.rules.get(&fusion_key).ok_or_else(|| {
647 TopologicalError::FusionFailed(format!("No fusion rule found for {fusion_key:?}"))
648 })?;
649
650 if let Some(product_charge) = fusion_products.first() {
653 self.anyons.remove(&anyon1_id);
655 self.anyons.remove(&anyon2_id);
656
657 let new_position = (
659 f64::midpoint(anyon1.position.0, anyon2.position.0),
660 f64::midpoint(anyon1.position.1, anyon2.position.1),
661 );
662
663 let product_anyon = Anyon {
664 anyon_id: self.next_anyon_id,
665 charge: TopologicalCharge {
666 label: product_charge.clone(),
667 quantum_dimension: "1".to_string(), scaling_dimension: 0.0,
669 },
670 position: new_position,
671 is_qubit_part: false,
672 qubit_id: None,
673 creation_time: self.current_time,
674 };
675
676 self.anyons.insert(self.next_anyon_id, product_anyon);
677 self.next_anyon_id += 1;
678 }
679
680 Ok(fusion_products.clone())
681 }
682
683 pub fn measure_qubit(&mut self, qubit_id: usize) -> TopologicalResult<bool> {
685 let qubit = self.qubits.get_mut(&qubit_id).ok_or_else(|| {
686 TopologicalError::InvalidBraiding(format!("Qubit {qubit_id} not found"))
687 })?;
688
689 let prob_zero = qubit.state.prob_zero();
690
691 let measured_zero = if prob_zero >= 0.9999 {
693 true } else if prob_zero <= 0.0001 {
695 false } else {
697 thread_rng().gen::<f64>() < prob_zero
698 };
699
700 if measured_zero {
702 qubit.state = TopologicalQubitState::zero();
703 } else {
704 qubit.state = TopologicalQubitState::one();
705 }
706
707 let final_result = if prob_zero >= 0.9999 || prob_zero <= 0.0001 {
709 measured_zero } else {
711 let measurement_fidelity = 0.999;
713 if thread_rng().gen::<f64>() < measurement_fidelity {
714 measured_zero
715 } else {
716 !measured_zero
717 }
718 };
719
720 Ok(!final_result) }
722
723 pub fn get_system_status(&self) -> TopologicalSystemStatus {
725 TopologicalSystemStatus {
726 total_anyons: self.anyons.len(),
727 total_qubits: self.qubits.len(),
728 system_type: self.system_type.clone(),
729 topological_gap: self.capabilities.topological_gap,
730 average_protection: self.calculate_average_protection(),
731 current_time: self.current_time,
732 }
733 }
734
735 fn calculate_average_protection(&self) -> f64 {
737 if self.qubits.is_empty() {
738 return 1.0;
739 }
740
741 let total_protection: f64 = self
742 .qubits
743 .values()
744 .map(|q| q.state.protection_factor)
745 .sum();
746
747 total_protection / self.qubits.len() as f64
748 }
749
750 pub fn evolve(&mut self, time_step: f64) -> TopologicalResult<()> {
752 self.current_time += time_step;
753
754 for qubit in self.qubits.values_mut() {
757 let gap_protection = (-time_step / self.capabilities.topological_gap).exp();
758 qubit.state.protection_factor *= gap_protection;
759 }
760
761 Ok(())
762 }
763}
764
765#[derive(Debug, Clone, Serialize, Deserialize)]
767pub struct TopologicalSystemStatus {
768 pub total_anyons: usize,
769 pub total_qubits: usize,
770 pub system_type: TopologicalSystemType,
771 pub topological_gap: f64,
772 pub average_protection: f64,
773 pub current_time: f64,
774}
775
776#[cfg(test)]
777mod tests {
778 use super::*;
779
780 #[test]
781 fn test_topological_charges() {
782 let identity = TopologicalCharge::identity();
783 assert_eq!(identity.label, "I");
784 assert_eq!(identity.quantum_dimension, "1");
785
786 let fibonacci_tau = TopologicalCharge::fibonacci_tau();
787 assert_eq!(fibonacci_tau.label, "τ");
788 assert_eq!(fibonacci_tau.quantum_dimension, "φ");
789 }
790
791 #[test]
792 fn test_qubit_state_creation() {
793 let zero = TopologicalQubitState::zero();
794 assert_eq!(zero.prob_zero(), 1.0);
795 assert_eq!(zero.prob_one(), 0.0);
796
797 let one = TopologicalQubitState::one();
798 assert_eq!(one.prob_zero(), 0.0);
799 assert_eq!(one.prob_one(), 1.0);
800
801 let plus = TopologicalQubitState::plus();
802 assert!((plus.prob_zero() - 0.5).abs() < 1e-10);
803 assert!((plus.prob_one() - 0.5).abs() < 1e-10);
804 }
805
806 #[test]
807 fn test_fusion_rules() {
808 let fibonacci_rules = FusionRuleSet::fibonacci();
809
810 let tau_tau_fusion = fibonacci_rules
811 .rules
812 .get(&("τ".to_string(), "τ".to_string()))
813 .expect("Fibonacci fusion rules should contain tau-tau fusion");
814 assert!(tau_tau_fusion.contains(&"I".to_string()));
815 assert!(tau_tau_fusion.contains(&"τ".to_string()));
816
817 let ising_rules = FusionRuleSet::ising();
818 let sigma_sigma_fusion = ising_rules
819 .rules
820 .get(&("σ".to_string(), "σ".to_string()))
821 .expect("Ising fusion rules should contain sigma-sigma fusion");
822 assert!(sigma_sigma_fusion.contains(&"I".to_string()));
823 assert!(sigma_sigma_fusion.contains(&"ψ".to_string()));
824 }
825
826 #[test]
827 fn test_topological_device_creation() {
828 let system_type = TopologicalSystemType::NonAbelian {
829 anyon_type: NonAbelianAnyonType::Fibonacci,
830 fusion_rules: FusionRuleSet::fibonacci(),
831 };
832
833 let capabilities = TopologicalCapabilities {
834 max_anyons: 100,
835 max_qubits: 10,
836 supported_anyons: vec![
837 TopologicalCharge::identity(),
838 TopologicalCharge::fibonacci_tau(),
839 ],
840 available_operations: vec![
841 TopologicalOperation::AnyonCreation {
842 charge_type: "τ".to_string(),
843 },
844 TopologicalOperation::Braiding {
845 direction: BraidingDirection::Clockwise,
846 },
847 ],
848 braiding_fidelity: 0.9999,
849 fusion_fidelity: 0.999,
850 topological_gap: 1.0,
851 coherence_length: 100.0,
852 };
853
854 let device = TopologicalDevice::new(system_type, FusionRuleSet::fibonacci(), capabilities);
855
856 assert_eq!(device.anyons.len(), 0);
857 assert_eq!(device.qubits.len(), 0);
858 assert_eq!(device.next_anyon_id, 0);
859 }
860
861 #[test]
862 fn test_anyon_creation() {
863 let system_type = TopologicalSystemType::NonAbelian {
864 anyon_type: NonAbelianAnyonType::Fibonacci,
865 fusion_rules: FusionRuleSet::fibonacci(),
866 };
867
868 let capabilities = TopologicalCapabilities {
869 max_anyons: 10,
870 max_qubits: 5,
871 supported_anyons: vec![TopologicalCharge::fibonacci_tau()],
872 available_operations: vec![],
873 braiding_fidelity: 0.9999,
874 fusion_fidelity: 0.999,
875 topological_gap: 1.0,
876 coherence_length: 100.0,
877 };
878
879 let mut device =
880 TopologicalDevice::new(system_type, FusionRuleSet::fibonacci(), capabilities);
881
882 let (anyon1_id, anyon2_id) = device
883 .create_anyon_pair(TopologicalCharge::fibonacci_tau(), [(0.0, 0.0), (1.0, 0.0)])
884 .expect("Anyon pair creation should succeed");
885
886 assert_eq!(device.anyons.len(), 2);
887 assert_eq!(anyon1_id, 0);
888 assert_eq!(anyon2_id, 1);
889 }
890
891 #[test]
892 fn test_topological_qubit_creation() {
893 let system_type = TopologicalSystemType::NonAbelian {
894 anyon_type: NonAbelianAnyonType::Fibonacci,
895 fusion_rules: FusionRuleSet::fibonacci(),
896 };
897
898 let capabilities = TopologicalCapabilities {
899 max_anyons: 10,
900 max_qubits: 5,
901 supported_anyons: vec![TopologicalCharge::fibonacci_tau()],
902 available_operations: vec![],
903 braiding_fidelity: 0.9999,
904 fusion_fidelity: 0.999,
905 topological_gap: 1.0,
906 coherence_length: 100.0,
907 };
908
909 let mut device =
910 TopologicalDevice::new(system_type, FusionRuleSet::fibonacci(), capabilities);
911
912 let (anyon1_id, anyon2_id) = device
914 .create_anyon_pair(TopologicalCharge::fibonacci_tau(), [(0.0, 0.0), (1.0, 0.0)])
915 .expect("First anyon pair creation should succeed");
916
917 let (anyon3_id, anyon4_id) = device
918 .create_anyon_pair(TopologicalCharge::fibonacci_tau(), [(2.0, 0.0), (3.0, 0.0)])
919 .expect("Second anyon pair creation should succeed");
920
921 let qubit_id = device
923 .create_topological_qubit(vec![anyon1_id, anyon2_id, anyon3_id, anyon4_id])
924 .expect("Topological qubit creation should succeed");
925
926 assert_eq!(device.qubits.len(), 1);
927 assert_eq!(qubit_id, 0);
928
929 let qubit = device
930 .qubits
931 .get(&qubit_id)
932 .expect("Qubit should exist after creation");
933 assert_eq!(qubit.anyons.len(), 4);
934 assert_eq!(qubit.state.prob_zero(), 1.0);
935 }
936
937 #[test]
938 fn test_braiding_operation() {
939 let system_type = TopologicalSystemType::NonAbelian {
940 anyon_type: NonAbelianAnyonType::Fibonacci,
941 fusion_rules: FusionRuleSet::fibonacci(),
942 };
943
944 let capabilities = TopologicalCapabilities {
945 max_anyons: 10,
946 max_qubits: 5,
947 supported_anyons: vec![TopologicalCharge::fibonacci_tau()],
948 available_operations: vec![],
949 braiding_fidelity: 0.9999,
950 fusion_fidelity: 0.999,
951 topological_gap: 1.0,
952 coherence_length: 100.0,
953 };
954
955 let mut device =
956 TopologicalDevice::new(system_type, FusionRuleSet::fibonacci(), capabilities);
957
958 let (anyon1_id, anyon2_id) = device
960 .create_anyon_pair(TopologicalCharge::fibonacci_tau(), [(0.0, 0.0), (1.0, 0.0)])
961 .expect("Anyon pair creation should succeed");
962
963 let result = device
965 .braid_anyons(anyon1_id, anyon2_id, BraidingDirection::Clockwise, 1)
966 .expect("Braiding operation should succeed");
967
968 match result {
969 BraidingResult::Phase(phase) => {
970 assert!((phase - (-4.0 * PI / 5.0)).abs() < 1e-10);
971 }
972 _ => panic!("Expected phase result for Fibonacci braiding"),
973 }
974 }
975
976 #[test]
977 fn test_measurement() {
978 let system_type = TopologicalSystemType::NonAbelian {
979 anyon_type: NonAbelianAnyonType::Fibonacci,
980 fusion_rules: FusionRuleSet::fibonacci(),
981 };
982
983 let capabilities = TopologicalCapabilities {
984 max_anyons: 10,
985 max_qubits: 5,
986 supported_anyons: vec![TopologicalCharge::fibonacci_tau()],
987 available_operations: vec![],
988 braiding_fidelity: 0.9999,
989 fusion_fidelity: 0.999,
990 topological_gap: 1.0,
991 coherence_length: 100.0,
992 };
993
994 let mut device =
995 TopologicalDevice::new(system_type, FusionRuleSet::fibonacci(), capabilities);
996
997 let (anyon1_id, anyon2_id) = device
999 .create_anyon_pair(TopologicalCharge::fibonacci_tau(), [(0.0, 0.0), (1.0, 0.0)])
1000 .expect("Anyon pair creation should succeed");
1001
1002 let qubit_id = device
1003 .create_topological_qubit(vec![anyon1_id, anyon2_id])
1004 .expect("Topological qubit creation should succeed");
1005
1006 let result = device
1008 .measure_qubit(qubit_id)
1009 .expect("Qubit measurement should succeed");
1010
1011 assert_eq!(result, false);
1013
1014 let qubit = device
1016 .qubits
1017 .get(&qubit_id)
1018 .expect("Qubit should exist after measurement");
1019 assert_eq!(qubit.state.prob_zero(), 1.0);
1020 }
1021}