1use ndarray::{Array1, Array2, Array3, Array4, Axis};
9use num_complex::Complex64;
10use serde::{Deserialize, Serialize};
11use std::collections::{HashMap, HashSet, VecDeque};
12use std::f64::consts::PI;
13use std::sync::{Arc, RwLock};
14
15use crate::error::{Result, SimulatorError};
16use crate::statevector::StateVectorSimulator;
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct TopologicalConfig {
21 pub lattice_type: LatticeType,
23 pub dimensions: Vec<usize>,
25 pub anyon_model: AnyonModel,
27 pub boundary_conditions: TopologicalBoundaryConditions,
29 pub temperature: f64,
31 pub magnetic_field: f64,
33 pub topological_protection: bool,
35 pub error_correction_code: TopologicalErrorCode,
37 pub enable_braiding: bool,
39}
40
41impl Default for TopologicalConfig {
42 fn default() -> Self {
43 Self {
44 lattice_type: LatticeType::SquareLattice,
45 dimensions: vec![8, 8],
46 anyon_model: AnyonModel::Abelian,
47 boundary_conditions: TopologicalBoundaryConditions::Periodic,
48 temperature: 0.0,
49 magnetic_field: 0.1,
50 topological_protection: true,
51 error_correction_code: TopologicalErrorCode::SurfaceCode,
52 enable_braiding: true,
53 }
54 }
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
59pub enum LatticeType {
60 SquareLattice,
62 TriangularLattice,
64 HexagonalLattice,
66 KagomeLattice,
68 HoneycombLattice,
70 CustomLattice,
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
76pub enum AnyonModel {
77 Abelian,
79 NonAbelian,
81 Fibonacci,
83 Ising,
85 Parafermion,
87 ChernSimons(u32), }
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
93pub enum TopologicalBoundaryConditions {
94 Periodic,
96 Open,
98 Twisted,
100 Antiperiodic,
102}
103
104#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
106pub enum TopologicalErrorCode {
107 SurfaceCode,
109 ColorCode,
111 HypergraphProductCode,
113 TopologicalLDPC,
115}
116
117#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
119pub struct AnyonType {
120 pub label: String,
122 pub quantum_dimension: f64,
124 pub topological_charge: i32,
126 pub fusion_rules: HashMap<String, Vec<String>>,
128 pub r_matrix: Complex64,
130 pub is_abelian: bool,
132}
133
134impl AnyonType {
135 pub fn vacuum() -> Self {
137 let mut fusion_rules = HashMap::new();
138 fusion_rules.insert("vacuum".to_string(), vec!["vacuum".to_string()]);
139
140 Self {
141 label: "vacuum".to_string(),
142 quantum_dimension: 1.0,
143 topological_charge: 0,
144 fusion_rules,
145 r_matrix: Complex64::new(1.0, 0.0),
146 is_abelian: true,
147 }
148 }
149
150 pub fn sigma() -> Self {
152 let mut fusion_rules = HashMap::new();
153 fusion_rules.insert(
154 "sigma".to_string(),
155 vec!["vacuum".to_string(), "psi".to_string()],
156 );
157 fusion_rules.insert("psi".to_string(), vec!["sigma".to_string()]);
158 fusion_rules.insert("vacuum".to_string(), vec!["sigma".to_string()]);
159
160 Self {
161 label: "sigma".to_string(),
162 quantum_dimension: 2.0_f64.sqrt(),
163 topological_charge: 1,
164 fusion_rules,
165 r_matrix: Complex64::new(0.0, 1.0) * (PI / 8.0).exp(), is_abelian: false,
167 }
168 }
169
170 pub fn tau() -> Self {
172 let golden_ratio = (1.0 + 5.0_f64.sqrt()) / 2.0;
173 let mut fusion_rules = HashMap::new();
174 fusion_rules.insert(
175 "tau".to_string(),
176 vec!["vacuum".to_string(), "tau".to_string()],
177 );
178 fusion_rules.insert("vacuum".to_string(), vec!["tau".to_string()]);
179
180 Self {
181 label: "tau".to_string(),
182 quantum_dimension: golden_ratio,
183 topological_charge: 1,
184 fusion_rules,
185 r_matrix: Complex64::new(0.0, 1.0) * (4.0 * PI / 5.0).exp(), is_abelian: false,
187 }
188 }
189}
190
191#[derive(Debug, Clone)]
193pub struct AnyonConfiguration {
194 pub anyons: Vec<(Vec<usize>, AnyonType)>,
196 pub worldlines: Vec<AnyonWorldline>,
198 pub fusion_tree: Option<FusionTree>,
200 pub total_charge: i32,
202}
203
204#[derive(Debug, Clone)]
206pub struct AnyonWorldline {
207 pub anyon_type: AnyonType,
209 pub path: Vec<Vec<usize>>,
211 pub time_stamps: Vec<f64>,
213 pub accumulated_phase: Complex64,
215}
216
217#[derive(Debug, Clone)]
219pub struct FusionTree {
220 pub tree_structure: Vec<FusionNode>,
222 pub total_dimension: f64,
224 pub basis_labels: Vec<String>,
226}
227
228#[derive(Debug, Clone)]
230pub struct FusionNode {
231 pub inputs: Vec<AnyonType>,
233 pub output: AnyonType,
235 pub f_matrix: Array2<Complex64>,
237 pub multiplicity: usize,
239}
240
241#[derive(Debug, Clone)]
243pub struct TopologicalState {
244 pub anyon_config: AnyonConfiguration,
246 pub amplitudes: Array1<Complex64>,
248 pub degeneracy: usize,
250 pub topological_invariants: TopologicalInvariants,
252 pub energy_gap: f64,
254}
255
256#[derive(Debug, Clone, Default, Serialize, Deserialize)]
258pub struct TopologicalInvariants {
259 pub chern_number: i32,
261 pub winding_number: i32,
263 pub z2_invariant: bool,
265 pub berry_phase: f64,
267 pub hall_conductivity: f64,
269 pub topological_entanglement_entropy: f64,
271}
272
273#[derive(Debug, Clone)]
275pub struct BraidingOperation {
276 pub anyon_indices: Vec<usize>,
278 pub braiding_type: BraidingType,
280 pub braiding_matrix: Array2<Complex64>,
282 pub execution_time: f64,
284}
285
286#[derive(Debug, Clone, Copy, PartialEq, Eq)]
288pub enum BraidingType {
289 Clockwise,
291 Counterclockwise,
293 Exchange,
295 Identity,
297}
298
299#[derive(Debug, Clone)]
301pub struct SurfaceCode {
302 pub distance: usize,
304 pub data_qubits: Vec<Vec<usize>>,
306 pub x_stabilizers: Vec<Vec<usize>>,
308 pub z_stabilizers: Vec<Vec<usize>>,
310 pub logical_operators: LogicalOperators,
312 pub syndrome_detectors: Vec<SyndromeDetector>,
314}
315
316#[derive(Debug, Clone)]
318pub struct LogicalOperators {
319 pub logical_x: Vec<Array1<bool>>,
321 pub logical_z: Vec<Array1<bool>>,
323 pub num_logical_qubits: usize,
325}
326
327#[derive(Debug, Clone)]
329pub struct SyndromeDetector {
330 pub stabilizer_type: StabilizerType,
332 pub measured_qubits: Vec<usize>,
334 pub threshold: f64,
336 pub correction_map: HashMap<Vec<bool>, Vec<usize>>,
338}
339
340#[derive(Debug, Clone, Copy, PartialEq, Eq)]
342pub enum StabilizerType {
343 PauliX,
345 PauliZ,
347 XZ,
349}
350
351pub struct TopologicalQuantumSimulator {
353 config: TopologicalConfig,
355 state: TopologicalState,
357 lattice: TopologicalLattice,
359 anyon_model: Box<dyn AnyonModelImplementation + Send + Sync>,
361 error_correction: Option<SurfaceCode>,
363 braiding_history: Vec<BraidingOperation>,
365 stats: TopologicalSimulationStats,
367}
368
369#[derive(Debug, Clone)]
371pub struct TopologicalLattice {
372 pub lattice_type: LatticeType,
374 pub dimensions: Vec<usize>,
376 pub sites: Vec<Vec<f64>>,
378 pub bonds: Vec<(usize, usize)>,
380 pub plaquettes: Vec<Vec<usize>>,
382 pub coordination_number: usize,
384}
385
386#[derive(Debug, Clone, Default, Serialize, Deserialize)]
388pub struct TopologicalSimulationStats {
389 pub braiding_operations: usize,
391 pub total_simulation_time_ms: f64,
393 pub avg_braiding_time_ms: f64,
395 pub error_corrections: usize,
397 pub average_fidelity: f64,
399 pub protection_effectiveness: f64,
401}
402
403pub trait AnyonModelImplementation {
405 fn get_anyon_types(&self) -> Vec<AnyonType>;
407
408 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64;
410
411 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64>;
413
414 fn f_matrix(
416 &self,
417 a: &AnyonType,
418 b: &AnyonType,
419 c: &AnyonType,
420 d: &AnyonType,
421 ) -> Array2<Complex64>;
422
423 fn is_abelian(&self) -> bool;
425
426 fn name(&self) -> &str;
428}
429
430impl TopologicalQuantumSimulator {
431 pub fn new(config: TopologicalConfig) -> Result<Self> {
433 let lattice = Self::create_lattice(&config)?;
434 let anyon_model = Self::create_anyon_model(&config.anyon_model)?;
435 let initial_state = Self::create_initial_topological_state(&config, &lattice)?;
436
437 let error_correction = if config.topological_protection {
438 Some(Self::create_surface_code(&config, &lattice)?)
439 } else {
440 None
441 };
442
443 Ok(Self {
444 config,
445 state: initial_state,
446 lattice,
447 anyon_model,
448 error_correction,
449 braiding_history: Vec::new(),
450 stats: TopologicalSimulationStats::default(),
451 })
452 }
453
454 fn create_lattice(config: &TopologicalConfig) -> Result<TopologicalLattice> {
456 match config.lattice_type {
457 LatticeType::SquareLattice => Self::create_square_lattice(&config.dimensions),
458 LatticeType::TriangularLattice => Self::create_triangular_lattice(&config.dimensions),
459 LatticeType::HexagonalLattice => Self::create_hexagonal_lattice(&config.dimensions),
460 LatticeType::HoneycombLattice => Self::create_honeycomb_lattice(&config.dimensions),
461 LatticeType::KagomeLattice => Self::create_kagome_lattice(&config.dimensions),
462 LatticeType::CustomLattice => Self::create_custom_lattice(&config.dimensions),
463 }
464 }
465
466 fn create_square_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
468 if dimensions.len() != 2 {
469 return Err(SimulatorError::InvalidInput(
470 "Square lattice requires 2D dimensions".to_string(),
471 ));
472 }
473
474 let (width, height) = (dimensions[0], dimensions[1]);
475 let mut sites = Vec::new();
476 let mut bonds = Vec::new();
477 let mut plaquettes = Vec::new();
478
479 for y in 0..height {
481 for x in 0..width {
482 sites.push(vec![x as f64, y as f64]);
483 }
484 }
485
486 for y in 0..height {
488 for x in 0..width {
489 let site = y * width + x;
490
491 if x < width - 1 {
493 bonds.push((site, site + 1));
494 }
495
496 if y < height - 1 {
498 bonds.push((site, site + width));
499 }
500 }
501 }
502
503 for y in 0..height - 1 {
505 for x in 0..width - 1 {
506 let plaquette = vec![
507 y * width + x, y * width + x + 1, (y + 1) * width + x, (y + 1) * width + x + 1, ];
512 plaquettes.push(plaquette);
513 }
514 }
515
516 Ok(TopologicalLattice {
517 lattice_type: LatticeType::SquareLattice,
518 dimensions: dimensions.to_vec(),
519 sites,
520 bonds,
521 plaquettes,
522 coordination_number: 4,
523 })
524 }
525
526 fn create_triangular_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
528 if dimensions.len() != 2 {
529 return Err(SimulatorError::InvalidInput(
530 "Triangular lattice requires 2D dimensions".to_string(),
531 ));
532 }
533
534 let (width, height) = (dimensions[0], dimensions[1]);
535 let mut sites = Vec::new();
536 let mut bonds = Vec::new();
537 let mut plaquettes = Vec::new();
538
539 for y in 0..height {
541 for x in 0..width {
542 let x_pos = x as f64 + if y % 2 == 1 { 0.5 } else { 0.0 };
543 let y_pos = y as f64 * 3.0_f64.sqrt() / 2.0;
544 sites.push(vec![x_pos, y_pos]);
545 }
546 }
547
548 for y in 0..height {
550 for x in 0..width {
551 let site = y * width + x;
552
553 if x < width - 1 {
555 bonds.push((site, site + 1));
556 }
557
558 if y < height - 1 {
560 bonds.push((site, site + width));
561
562 if y % 2 == 0 && x < width - 1 {
563 bonds.push((site, site + width + 1));
564 } else if y % 2 == 1 && x > 0 {
565 bonds.push((site, site + width - 1));
566 }
567 }
568 }
569 }
570
571 for y in 0..height - 1 {
573 for x in 0..width - 1 {
574 if y % 2 == 0 {
575 let plaquette = vec![y * width + x, y * width + x + 1, (y + 1) * width + x];
577 plaquettes.push(plaquette);
578 }
579 }
580 }
581
582 Ok(TopologicalLattice {
583 lattice_type: LatticeType::TriangularLattice,
584 dimensions: dimensions.to_vec(),
585 sites,
586 bonds,
587 plaquettes,
588 coordination_number: 6,
589 })
590 }
591
592 fn create_hexagonal_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
594 if dimensions.len() != 2 {
595 return Err(SimulatorError::InvalidInput(
596 "Hexagonal lattice requires 2D dimensions".to_string(),
597 ));
598 }
599
600 let (width, height) = (dimensions[0], dimensions[1]);
601 let mut sites = Vec::new();
602 let mut bonds = Vec::new();
603 let mut plaquettes = Vec::new();
604
605 for y in 0..height {
607 for x in 0..width {
608 let x_pos = x as f64 * 1.5;
609 let y_pos = y as f64 * 3.0_f64.sqrt()
610 + if x % 2 == 1 {
611 3.0_f64.sqrt() / 2.0
612 } else {
613 0.0
614 };
615 sites.push(vec![x_pos, y_pos]);
616 }
617 }
618
619 for y in 0..height {
621 for x in 0..width {
622 let site = y * width + x;
623
624 if x < width - 1 {
626 bonds.push((site, site + 1));
627 }
628
629 if y < height - 1 {
631 bonds.push((site, site + width));
632 }
633
634 if y > 0 {
635 bonds.push((site, site - width));
636 }
637 }
638 }
639
640 for y in 1..height - 1 {
642 for x in 1..width - 1 {
643 let plaquette = vec![
644 (y - 1) * width + x,
645 (y - 1) * width + x + 1,
646 y * width + x + 1,
647 (y + 1) * width + x + 1,
648 (y + 1) * width + x,
649 y * width + x,
650 ];
651 plaquettes.push(plaquette);
652 }
653 }
654
655 Ok(TopologicalLattice {
656 lattice_type: LatticeType::HexagonalLattice,
657 dimensions: dimensions.to_vec(),
658 sites,
659 bonds,
660 plaquettes,
661 coordination_number: 3,
662 })
663 }
664
665 fn create_honeycomb_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
667 if dimensions.len() != 2 {
668 return Err(SimulatorError::InvalidInput(
669 "Honeycomb lattice requires 2D dimensions".to_string(),
670 ));
671 }
672
673 let (width, height) = (dimensions[0], dimensions[1]);
674 let mut sites = Vec::new();
675 let mut bonds = Vec::new();
676 let mut plaquettes = Vec::new();
677
678 for y in 0..height {
680 for x in 0..width {
681 let x_a = x as f64 * 3.0 / 2.0;
683 let y_a = y as f64 * 3.0_f64.sqrt();
684 sites.push(vec![x_a, y_a]);
685
686 let x_b = x as f64 * 3.0 / 2.0 + 1.0;
688 let y_b = y as f64 * 3.0_f64.sqrt() + 3.0_f64.sqrt() / 3.0;
689 sites.push(vec![x_b, y_b]);
690 }
691 }
692
693 for y in 0..height {
695 for x in 0..width {
696 let a_site = 2 * (y * width + x);
697 let b_site = a_site + 1;
698
699 bonds.push((a_site, b_site));
701
702 if x < width - 1 {
704 bonds.push((b_site, a_site + 2));
705 }
706
707 if y < height - 1 {
708 bonds.push((b_site, a_site + 2 * width));
709 }
710 }
711 }
712
713 for y in 0..height - 1 {
715 for x in 0..width - 1 {
716 let plaquette = vec![
717 2 * (y * width + x), 2 * (y * width + x) + 1, 2 * (y * width + x + 1), 2 * (y * width + x + 1) + 1, 2 * ((y + 1) * width + x), 2 * ((y + 1) * width + x) + 1, ];
724 plaquettes.push(plaquette);
725 }
726 }
727
728 Ok(TopologicalLattice {
729 lattice_type: LatticeType::HoneycombLattice,
730 dimensions: dimensions.to_vec(),
731 sites,
732 bonds,
733 plaquettes,
734 coordination_number: 3,
735 })
736 }
737
738 fn create_kagome_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
740 if dimensions.len() != 2 {
741 return Err(SimulatorError::InvalidInput(
742 "Kagome lattice requires 2D dimensions".to_string(),
743 ));
744 }
745
746 let (width, height) = (dimensions[0], dimensions[1]);
747 let mut sites = Vec::new();
748 let mut bonds = Vec::new();
749 let mut plaquettes = Vec::new();
750
751 for y in 0..height {
753 for x in 0..width {
754 let base_x = x as f64 * 2.0;
755 let base_y = y as f64 * 3.0_f64.sqrt();
756
757 sites.push(vec![base_x, base_y]);
759 sites.push(vec![base_x + 1.0, base_y]);
760 sites.push(vec![base_x + 0.5, base_y + 3.0_f64.sqrt() / 2.0]);
761 }
762 }
763
764 for y in 0..height {
766 for x in 0..width {
767 let base_site = 3 * (y * width + x);
768
769 bonds.push((base_site, base_site + 1));
771 bonds.push((base_site + 1, base_site + 2));
772 bonds.push((base_site + 2, base_site));
773
774 if x < width - 1 {
776 bonds.push((base_site + 1, base_site + 3));
777 }
778
779 if y < height - 1 {
780 bonds.push((base_site + 2, base_site + 3 * width));
781 }
782 }
783 }
784
785 for y in 0..height {
787 for x in 0..width {
788 let base_site = 3 * (y * width + x);
789
790 let triangle = vec![base_site, base_site + 1, base_site + 2];
792 plaquettes.push(triangle);
793
794 if x < width - 1 && y < height - 1 {
796 let hexagon = vec![
797 base_site + 1,
798 base_site + 3,
799 base_site + 3 + 2,
800 base_site + 3 * width + 2,
801 base_site + 3 * width,
802 base_site + 2,
803 ];
804 plaquettes.push(hexagon);
805 }
806 }
807 }
808
809 Ok(TopologicalLattice {
810 lattice_type: LatticeType::KagomeLattice,
811 dimensions: dimensions.to_vec(),
812 sites,
813 bonds,
814 plaquettes,
815 coordination_number: 4,
816 })
817 }
818
819 fn create_custom_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
821 Self::create_square_lattice(dimensions)
823 }
824
825 fn create_anyon_model(
827 model: &AnyonModel,
828 ) -> Result<Box<dyn AnyonModelImplementation + Send + Sync>> {
829 match model {
830 AnyonModel::Abelian => Ok(Box::new(AbelianAnyons::new())),
831 AnyonModel::NonAbelian => Ok(Box::new(NonAbelianAnyons::new())),
832 AnyonModel::Fibonacci => Ok(Box::new(FibonacciAnyons::new())),
833 AnyonModel::Ising => Ok(Box::new(IsingAnyons::new())),
834 AnyonModel::Parafermion => Ok(Box::new(ParafermionAnyons::new())),
835 AnyonModel::ChernSimons(k) => Ok(Box::new(ChernSimonsAnyons::new(*k))),
836 }
837 }
838
839 fn create_initial_topological_state(
841 config: &TopologicalConfig,
842 lattice: &TopologicalLattice,
843 ) -> Result<TopologicalState> {
844 let anyon_config = AnyonConfiguration {
846 anyons: Vec::new(),
847 worldlines: Vec::new(),
848 fusion_tree: None,
849 total_charge: 0,
850 };
851
852 let degeneracy = Self::calculate_ground_state_degeneracy(config, lattice);
854 let amplitudes = Array1::zeros(degeneracy);
855
856 let topological_invariants = TopologicalInvariants::default();
857
858 Ok(TopologicalState {
859 anyon_config,
860 amplitudes,
861 degeneracy,
862 topological_invariants,
863 energy_gap: config.magnetic_field, })
865 }
866
867 fn calculate_ground_state_degeneracy(
869 config: &TopologicalConfig,
870 lattice: &TopologicalLattice,
871 ) -> usize {
872 match config.anyon_model {
873 AnyonModel::Abelian => {
874 let genus = Self::calculate_genus(lattice);
876 2_usize.pow(genus as u32)
877 }
878 AnyonModel::Fibonacci => {
879 let num_qubits = lattice.sites.len() / 2;
881 let golden_ratio = (1.0 + 5.0_f64.sqrt()) / 2.0;
882 (golden_ratio.powi(num_qubits as i32) / 5.0_f64.sqrt()).round() as usize
883 }
884 AnyonModel::Ising => {
885 let num_majoranas = lattice.sites.len();
887 2_usize.pow((num_majoranas / 2) as u32)
888 }
889 _ => 1, }
891 }
892
893 fn calculate_genus(lattice: &TopologicalLattice) -> usize {
895 let vertices = lattice.sites.len();
897 let edges = lattice.bonds.len();
898 let faces = lattice.plaquettes.len() + 1; let euler_characteristic = vertices as i32 - edges as i32 + faces as i32;
901 let genus = (2 - euler_characteristic) / 2;
902 genus.max(0) as usize
903 }
904
905 fn create_surface_code(
907 config: &TopologicalConfig,
908 lattice: &TopologicalLattice,
909 ) -> Result<SurfaceCode> {
910 match config.error_correction_code {
911 TopologicalErrorCode::SurfaceCode => {
912 Self::create_toric_surface_code(&config.dimensions)
913 }
914 TopologicalErrorCode::ColorCode => Self::create_color_code(&config.dimensions),
915 _ => {
916 Self::create_toric_surface_code(&config.dimensions)
918 }
919 }
920 }
921
922 fn create_toric_surface_code(dimensions: &[usize]) -> Result<SurfaceCode> {
924 if dimensions.len() != 2 {
925 return Err(SimulatorError::InvalidInput(
926 "Surface code requires 2D lattice".to_string(),
927 ));
928 }
929
930 let distance = dimensions[0].min(dimensions[1]);
931 let mut data_qubits = Vec::new();
932 let mut x_stabilizers = Vec::new();
933 let mut z_stabilizers = Vec::new();
934
935 for y in 0..distance {
937 for x in 0..distance {
938 data_qubits.push(vec![x, y, 0]); data_qubits.push(vec![x, y, 1]); }
943 }
944
945 for y in 0..distance {
947 for x in 0..distance {
948 let stabilizer_pos = vec![x, y];
949 x_stabilizers.push(stabilizer_pos);
950 }
951 }
952
953 for y in 0..distance - 1 {
955 for x in 0..distance - 1 {
956 let stabilizer_pos = vec![x, y];
957 z_stabilizers.push(stabilizer_pos);
958 }
959 }
960
961 let logical_x = vec![Array1::from_elem(distance, true)];
963 let logical_z = vec![Array1::from_elem(distance, true)];
964
965 let logical_operators = LogicalOperators {
966 logical_x,
967 logical_z,
968 num_logical_qubits: 1,
969 };
970
971 let mut syndrome_detectors = Vec::new();
973
974 for stabilizer in &x_stabilizers {
975 let detector = SyndromeDetector {
976 stabilizer_type: StabilizerType::PauliX,
977 measured_qubits: vec![0, 1, 2, 3], threshold: 0.5,
979 correction_map: HashMap::new(),
980 };
981 syndrome_detectors.push(detector);
982 }
983
984 for stabilizer in &z_stabilizers {
985 let detector = SyndromeDetector {
986 stabilizer_type: StabilizerType::PauliZ,
987 measured_qubits: vec![0, 1, 2, 3], threshold: 0.5,
989 correction_map: HashMap::new(),
990 };
991 syndrome_detectors.push(detector);
992 }
993
994 Ok(SurfaceCode {
995 distance,
996 data_qubits,
997 x_stabilizers,
998 z_stabilizers,
999 logical_operators,
1000 syndrome_detectors,
1001 })
1002 }
1003
1004 fn create_color_code(dimensions: &[usize]) -> Result<SurfaceCode> {
1006 Self::create_toric_surface_code(dimensions)
1008 }
1009
1010 pub fn place_anyon(&mut self, anyon_type: AnyonType, position: Vec<usize>) -> Result<usize> {
1012 if position.len() != self.config.dimensions.len() {
1014 return Err(SimulatorError::InvalidInput(
1015 "Position dimension mismatch".to_string(),
1016 ));
1017 }
1018
1019 for (i, &pos) in position.iter().enumerate() {
1020 if pos >= self.config.dimensions[i] {
1021 return Err(SimulatorError::InvalidInput(
1022 "Position out of bounds".to_string(),
1023 ));
1024 }
1025 }
1026
1027 let anyon_id = self.state.anyon_config.anyons.len();
1029 self.state
1030 .anyon_config
1031 .anyons
1032 .push((position.clone(), anyon_type.clone()));
1033
1034 self.state.anyon_config.total_charge += anyon_type.topological_charge;
1036
1037 let worldline = AnyonWorldline {
1039 anyon_type,
1040 path: vec![position],
1041 time_stamps: vec![0.0],
1042 accumulated_phase: Complex64::new(1.0, 0.0),
1043 };
1044 self.state.anyon_config.worldlines.push(worldline);
1045
1046 Ok(anyon_id)
1047 }
1048
1049 pub fn braid_anyons(
1051 &mut self,
1052 anyon_a: usize,
1053 anyon_b: usize,
1054 braiding_type: BraidingType,
1055 ) -> Result<Complex64> {
1056 let start_time = std::time::Instant::now();
1057
1058 if anyon_a >= self.state.anyon_config.anyons.len()
1059 || anyon_b >= self.state.anyon_config.anyons.len()
1060 {
1061 return Err(SimulatorError::InvalidInput(
1062 "Invalid anyon indices".to_string(),
1063 ));
1064 }
1065
1066 let (_, ref type_a) = &self.state.anyon_config.anyons[anyon_a];
1067 let (_, ref type_b) = &self.state.anyon_config.anyons[anyon_b];
1068
1069 let braiding_matrix = self.anyon_model.braiding_matrix(type_a, type_b);
1071
1072 let braiding_phase = match braiding_type {
1074 BraidingType::Clockwise => type_a.r_matrix * type_b.r_matrix.conj(),
1075 BraidingType::Counterclockwise => type_a.r_matrix.conj() * type_b.r_matrix,
1076 BraidingType::Exchange => type_a.r_matrix * type_b.r_matrix,
1077 BraidingType::Identity => Complex64::new(1.0, 0.0),
1078 };
1079
1080 let current_time = self.braiding_history.len() as f64;
1082 if anyon_a < self.state.anyon_config.worldlines.len() {
1083 self.state.anyon_config.worldlines[anyon_a]
1084 .time_stamps
1085 .push(current_time);
1086 self.state.anyon_config.worldlines[anyon_a].accumulated_phase *= braiding_phase;
1087 }
1088 if anyon_b < self.state.anyon_config.worldlines.len() {
1089 self.state.anyon_config.worldlines[anyon_b]
1090 .time_stamps
1091 .push(current_time);
1092 self.state.anyon_config.worldlines[anyon_b].accumulated_phase *= braiding_phase.conj();
1093 }
1094
1095 for amplitude in self.state.amplitudes.iter_mut() {
1097 *amplitude *= braiding_phase;
1098 }
1099
1100 let execution_time = start_time.elapsed().as_secs_f64() * 1000.0;
1101
1102 let braiding_op = BraidingOperation {
1104 anyon_indices: vec![anyon_a, anyon_b],
1105 braiding_type,
1106 braiding_matrix,
1107 execution_time,
1108 };
1109 self.braiding_history.push(braiding_op);
1110
1111 self.stats.braiding_operations += 1;
1113 self.stats.avg_braiding_time_ms = (self.stats.avg_braiding_time_ms
1114 * (self.stats.braiding_operations - 1) as f64
1115 + execution_time)
1116 / self.stats.braiding_operations as f64;
1117
1118 Ok(braiding_phase)
1119 }
1120
1121 pub fn move_anyon(&mut self, anyon_id: usize, new_position: Vec<usize>) -> Result<()> {
1123 if anyon_id >= self.state.anyon_config.anyons.len() {
1124 return Err(SimulatorError::InvalidInput("Invalid anyon ID".to_string()));
1125 }
1126
1127 for (i, &pos) in new_position.iter().enumerate() {
1129 if pos >= self.config.dimensions[i] {
1130 return Err(SimulatorError::InvalidInput(
1131 "New position out of bounds".to_string(),
1132 ));
1133 }
1134 }
1135
1136 self.state.anyon_config.anyons[anyon_id].0 = new_position.clone();
1138
1139 if anyon_id < self.state.anyon_config.worldlines.len() {
1141 self.state.anyon_config.worldlines[anyon_id]
1142 .path
1143 .push(new_position);
1144 let current_time = self.braiding_history.len() as f64;
1145 self.state.anyon_config.worldlines[anyon_id]
1146 .time_stamps
1147 .push(current_time);
1148 }
1149
1150 Ok(())
1151 }
1152
1153 pub fn fuse_anyons(&mut self, anyon_a: usize, anyon_b: usize) -> Result<Vec<AnyonType>> {
1155 if anyon_a >= self.state.anyon_config.anyons.len()
1156 || anyon_b >= self.state.anyon_config.anyons.len()
1157 {
1158 return Err(SimulatorError::InvalidInput(
1159 "Invalid anyon indices".to_string(),
1160 ));
1161 }
1162
1163 let type_a = &self.state.anyon_config.anyons[anyon_a].1;
1164 let type_b = &self.state.anyon_config.anyons[anyon_b].1;
1165
1166 let fusion_outcomes = if let Some(outcomes) = type_a.fusion_rules.get(&type_b.label) {
1168 outcomes.clone()
1169 } else {
1170 vec!["vacuum".to_string()] };
1172
1173 let outcome_types: Vec<AnyonType> = fusion_outcomes
1175 .iter()
1176 .map(|label| self.create_anyon_from_label(label))
1177 .collect::<Result<Vec<_>>>()?;
1178
1179 let mut indices_to_remove = vec![anyon_a, anyon_b];
1183 indices_to_remove.sort_by(|a, b| b.cmp(a)); for &index in &indices_to_remove {
1186 if index < self.state.anyon_config.anyons.len() {
1187 self.state.anyon_config.anyons.remove(index);
1188 }
1189 if index < self.state.anyon_config.worldlines.len() {
1190 self.state.anyon_config.worldlines.remove(index);
1191 }
1192 }
1193
1194 Ok(outcome_types)
1195 }
1196
1197 fn create_anyon_from_label(&self, label: &str) -> Result<AnyonType> {
1199 match label {
1200 "vacuum" => Ok(AnyonType::vacuum()),
1201 "sigma" => Ok(AnyonType::sigma()),
1202 "tau" => Ok(AnyonType::tau()),
1203 _ => {
1204 Ok(AnyonType {
1206 label: label.to_string(),
1207 quantum_dimension: 1.0,
1208 topological_charge: 0,
1209 fusion_rules: HashMap::new(),
1210 r_matrix: Complex64::new(1.0, 0.0),
1211 is_abelian: true,
1212 })
1213 }
1214 }
1215 }
1216
1217 pub fn calculate_topological_invariants(&mut self) -> Result<TopologicalInvariants> {
1219 let mut invariants = TopologicalInvariants::default();
1220
1221 invariants.chern_number = self.calculate_chern_number()?;
1223
1224 invariants.winding_number = self.calculate_winding_number()?;
1226
1227 invariants.z2_invariant = self.calculate_z2_invariant()?;
1229
1230 invariants.berry_phase = self.calculate_berry_phase()?;
1232
1233 invariants.hall_conductivity = invariants.chern_number as f64 * 2.0 * PI / 137.0; invariants.topological_entanglement_entropy =
1238 self.calculate_topological_entanglement_entropy()?;
1239
1240 self.state.topological_invariants = invariants.clone();
1241 Ok(invariants)
1242 }
1243
1244 fn calculate_chern_number(&self) -> Result<i32> {
1246 let magnetic_flux = self.config.magnetic_field * self.lattice.sites.len() as f64;
1249 let flux_quanta = (magnetic_flux / (2.0 * PI)).round() as i32;
1250 Ok(flux_quanta)
1251 }
1252
1253 fn calculate_winding_number(&self) -> Result<i32> {
1255 match self.config.dimensions.len() {
1257 1 => Ok(1), _ => Ok(0), }
1260 }
1261
1262 fn calculate_z2_invariant(&self) -> Result<bool> {
1264 let time_reversal_broken = self.config.magnetic_field.abs() > 1e-10;
1266 Ok(!time_reversal_broken)
1267 }
1268
1269 fn calculate_berry_phase(&self) -> Result<f64> {
1271 let total_braiding_phase: Complex64 = self
1273 .state
1274 .anyon_config
1275 .worldlines
1276 .iter()
1277 .map(|wl| wl.accumulated_phase)
1278 .fold(Complex64::new(1.0, 0.0), |acc, phase| acc * phase);
1279
1280 Ok(total_braiding_phase.arg())
1281 }
1282
1283 fn calculate_topological_entanglement_entropy(&self) -> Result<f64> {
1285 let total_quantum_dimension: f64 = self
1287 .anyon_model
1288 .get_anyon_types()
1289 .iter()
1290 .map(|anyon| anyon.quantum_dimension * anyon.quantum_dimension)
1291 .sum();
1292
1293 let gamma = match self.config.anyon_model {
1294 AnyonModel::Abelian => 0.0,
1295 AnyonModel::Fibonacci => 0.5 * (5.0_f64.sqrt() - 1.0) / 2.0, AnyonModel::Ising => 0.5,
1297 _ => 0.5, };
1299
1300 Ok(-gamma * total_quantum_dimension.ln())
1301 }
1302
1303 pub fn detect_and_correct_errors(&mut self) -> Result<Vec<bool>> {
1305 if let Some(ref surface_code) = self.error_correction {
1306 let mut syndrome = Vec::new();
1307
1308 for detector in &surface_code.syndrome_detectors {
1310 let measurement = self.measure_stabilizer(detector)?;
1311 syndrome.push(measurement);
1312 }
1313
1314 let corrections = self.decode_syndrome(&syndrome)?;
1316 self.apply_corrections(&corrections)?;
1317
1318 self.stats.error_corrections += 1;
1319 Ok(syndrome)
1320 } else {
1321 Ok(Vec::new())
1322 }
1323 }
1324
1325 fn measure_stabilizer(&self, detector: &SyndromeDetector) -> Result<bool> {
1327 let probability = match detector.stabilizer_type {
1330 StabilizerType::PauliX => 0.1, StabilizerType::PauliZ => 0.1,
1332 StabilizerType::XZ => 0.05,
1333 };
1334
1335 Ok(fastrand::f64() < probability)
1336 }
1337
1338 fn decode_syndrome(&self, syndrome: &[bool]) -> Result<Vec<usize>> {
1340 let mut corrections = Vec::new();
1343
1344 for (i, &error) in syndrome.iter().enumerate() {
1345 if error {
1346 corrections.push(i);
1347 }
1348 }
1349
1350 Ok(corrections)
1351 }
1352
1353 fn apply_corrections(&mut self, corrections: &[usize]) -> Result<()> {
1355 for &correction_site in corrections {
1357 if correction_site < self.state.amplitudes.len() {
1358 self.state.amplitudes[correction_site] *= Complex64::new(-1.0, 0.0);
1361 }
1362 }
1363
1364 Ok(())
1365 }
1366
1367 pub fn get_state(&self) -> &TopologicalState {
1369 &self.state
1370 }
1371
1372 pub fn get_braiding_history(&self) -> &[BraidingOperation] {
1374 &self.braiding_history
1375 }
1376
1377 pub fn get_stats(&self) -> &TopologicalSimulationStats {
1379 &self.stats
1380 }
1381
1382 pub fn reset(&mut self) -> Result<()> {
1384 self.state = Self::create_initial_topological_state(&self.config, &self.lattice)?;
1385 self.braiding_history.clear();
1386 self.stats = TopologicalSimulationStats::default();
1387 Ok(())
1388 }
1389}
1390
1391pub struct AbelianAnyons {
1395 anyon_types: Vec<AnyonType>,
1396}
1397
1398impl AbelianAnyons {
1399 pub fn new() -> Self {
1400 let anyon_types = vec![AnyonType::vacuum()];
1401 Self { anyon_types }
1402 }
1403}
1404
1405impl AnyonModelImplementation for AbelianAnyons {
1406 fn get_anyon_types(&self) -> Vec<AnyonType> {
1407 self.anyon_types.clone()
1408 }
1409
1410 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1411 if a.topological_charge + b.topological_charge == c.topological_charge {
1413 Complex64::new(1.0, 0.0)
1414 } else {
1415 Complex64::new(0.0, 0.0)
1416 }
1417 }
1418
1419 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1420 let phase = a.r_matrix * b.r_matrix.conj();
1421 Array2::from_shape_vec((1, 1), vec![phase]).unwrap()
1422 }
1423
1424 fn f_matrix(
1425 &self,
1426 _a: &AnyonType,
1427 _b: &AnyonType,
1428 _c: &AnyonType,
1429 _d: &AnyonType,
1430 ) -> Array2<Complex64> {
1431 Array2::eye(1)
1433 }
1434
1435 fn is_abelian(&self) -> bool {
1436 true
1437 }
1438
1439 fn name(&self) -> &str {
1440 "Abelian Anyons"
1441 }
1442}
1443
1444pub struct NonAbelianAnyons {
1446 anyon_types: Vec<AnyonType>,
1447}
1448
1449impl NonAbelianAnyons {
1450 pub fn new() -> Self {
1451 let anyon_types = vec![AnyonType::vacuum(), AnyonType::sigma()];
1452 Self { anyon_types }
1453 }
1454}
1455
1456impl AnyonModelImplementation for NonAbelianAnyons {
1457 fn get_anyon_types(&self) -> Vec<AnyonType> {
1458 self.anyon_types.clone()
1459 }
1460
1461 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1462 if let Some(outcomes) = a.fusion_rules.get(&b.label) {
1464 if outcomes.contains(&c.label) {
1465 Complex64::new(1.0, 0.0)
1466 } else {
1467 Complex64::new(0.0, 0.0)
1468 }
1469 } else {
1470 Complex64::new(0.0, 0.0)
1471 }
1472 }
1473
1474 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1475 let dim = (a.quantum_dimension * b.quantum_dimension) as usize;
1476 let mut matrix = Array2::eye(dim);
1477
1478 if !a.is_abelian || !b.is_abelian {
1480 let phase = a.r_matrix * b.r_matrix.conj();
1481 matrix[[0, 0]] = phase;
1482 if dim > 1 {
1483 matrix[[1, 1]] = phase.conj();
1484 }
1485 }
1486
1487 matrix
1488 }
1489
1490 fn f_matrix(
1491 &self,
1492 _a: &AnyonType,
1493 _b: &AnyonType,
1494 _c: &AnyonType,
1495 _d: &AnyonType,
1496 ) -> Array2<Complex64> {
1497 Array2::eye(2)
1499 }
1500
1501 fn is_abelian(&self) -> bool {
1502 false
1503 }
1504
1505 fn name(&self) -> &str {
1506 "Non-Abelian Anyons"
1507 }
1508}
1509
1510pub struct FibonacciAnyons {
1512 anyon_types: Vec<AnyonType>,
1513}
1514
1515impl FibonacciAnyons {
1516 pub fn new() -> Self {
1517 let anyon_types = vec![AnyonType::vacuum(), AnyonType::tau()];
1518 Self { anyon_types }
1519 }
1520}
1521
1522impl AnyonModelImplementation for FibonacciAnyons {
1523 fn get_anyon_types(&self) -> Vec<AnyonType> {
1524 self.anyon_types.clone()
1525 }
1526
1527 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1528 match (a.label.as_str(), b.label.as_str(), c.label.as_str()) {
1530 ("tau", "tau", "vacuum") | ("tau", "tau", "tau") => Complex64::new(1.0, 0.0),
1531 ("vacuum", _, label) | (_, "vacuum", label) if label == a.label || label == b.label => {
1532 Complex64::new(1.0, 0.0)
1533 }
1534 _ => Complex64::new(0.0, 0.0),
1535 }
1536 }
1537
1538 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1539 if a.label == "tau" && b.label == "tau" {
1540 let phi = (1.0 + 5.0_f64.sqrt()) / 2.0; let phase = Complex64::new(0.0, 1.0) * (4.0 * PI / 5.0).exp();
1542
1543 Array2::from_shape_vec(
1544 (2, 2),
1545 vec![
1546 phase,
1547 Complex64::new(0.0, 0.0),
1548 Complex64::new(0.0, 0.0),
1549 phase * Complex64::new(-1.0 / phi, 0.0),
1550 ],
1551 )
1552 .unwrap()
1553 } else {
1554 Array2::eye(1)
1555 }
1556 }
1557
1558 fn f_matrix(
1559 &self,
1560 _a: &AnyonType,
1561 _b: &AnyonType,
1562 _c: &AnyonType,
1563 _d: &AnyonType,
1564 ) -> Array2<Complex64> {
1565 let phi = (1.0 + 5.0_f64.sqrt()) / 2.0;
1567 let inv_phi = 1.0 / phi;
1568
1569 Array2::from_shape_vec(
1570 (2, 2),
1571 vec![
1572 Complex64::new(inv_phi, 0.0),
1573 Complex64::new(inv_phi.sqrt(), 0.0),
1574 Complex64::new(inv_phi.sqrt(), 0.0),
1575 Complex64::new(-inv_phi, 0.0),
1576 ],
1577 )
1578 .unwrap()
1579 }
1580
1581 fn is_abelian(&self) -> bool {
1582 false
1583 }
1584
1585 fn name(&self) -> &str {
1586 "Fibonacci Anyons"
1587 }
1588}
1589
1590pub struct IsingAnyons {
1592 anyon_types: Vec<AnyonType>,
1593}
1594
1595impl IsingAnyons {
1596 pub fn new() -> Self {
1597 let mut psi = AnyonType {
1598 label: "psi".to_string(),
1599 quantum_dimension: 1.0,
1600 topological_charge: 1,
1601 fusion_rules: HashMap::new(),
1602 r_matrix: Complex64::new(-1.0, 0.0),
1603 is_abelian: true,
1604 };
1605 psi.fusion_rules
1606 .insert("psi".to_string(), vec!["vacuum".to_string()]);
1607
1608 let anyon_types = vec![AnyonType::vacuum(), AnyonType::sigma(), psi];
1609 Self { anyon_types }
1610 }
1611}
1612
1613impl AnyonModelImplementation for IsingAnyons {
1614 fn get_anyon_types(&self) -> Vec<AnyonType> {
1615 self.anyon_types.clone()
1616 }
1617
1618 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1619 match (a.label.as_str(), b.label.as_str(), c.label.as_str()) {
1621 ("sigma", "sigma", "vacuum") | ("sigma", "sigma", "psi") => Complex64::new(1.0, 0.0),
1622 ("psi", "psi", "vacuum") => Complex64::new(1.0, 0.0),
1623 ("sigma", "psi", "sigma") | ("psi", "sigma", "sigma") => Complex64::new(1.0, 0.0),
1624 ("vacuum", _, label) | (_, "vacuum", label) if label == a.label || label == b.label => {
1625 Complex64::new(1.0, 0.0)
1626 }
1627 _ => Complex64::new(0.0, 0.0),
1628 }
1629 }
1630
1631 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1632 let phase = a.r_matrix * b.r_matrix.conj();
1633
1634 if a.label == "sigma" && b.label == "sigma" {
1635 Array2::from_shape_vec(
1637 (2, 2),
1638 vec![
1639 Complex64::new(0.0, 1.0) * (PI / 8.0).exp(),
1640 Complex64::new(0.0, 0.0),
1641 Complex64::new(0.0, 0.0),
1642 Complex64::new(0.0, -1.0) * (PI / 8.0).exp(),
1643 ],
1644 )
1645 .unwrap()
1646 } else {
1647 Array2::from_shape_vec((1, 1), vec![phase]).unwrap()
1648 }
1649 }
1650
1651 fn f_matrix(
1652 &self,
1653 _a: &AnyonType,
1654 _b: &AnyonType,
1655 _c: &AnyonType,
1656 _d: &AnyonType,
1657 ) -> Array2<Complex64> {
1658 let sqrt_2_inv = 1.0 / 2.0_f64.sqrt();
1660 Array2::from_shape_vec(
1661 (2, 2),
1662 vec![
1663 Complex64::new(sqrt_2_inv, 0.0),
1664 Complex64::new(sqrt_2_inv, 0.0),
1665 Complex64::new(sqrt_2_inv, 0.0),
1666 Complex64::new(-sqrt_2_inv, 0.0),
1667 ],
1668 )
1669 .unwrap()
1670 }
1671
1672 fn is_abelian(&self) -> bool {
1673 false
1674 }
1675
1676 fn name(&self) -> &str {
1677 "Ising Anyons"
1678 }
1679}
1680
1681pub struct ParafermionAnyons {
1683 anyon_types: Vec<AnyonType>,
1684}
1685
1686impl ParafermionAnyons {
1687 pub fn new() -> Self {
1688 Self {
1689 anyon_types: vec![AnyonType::vacuum()],
1690 }
1691 }
1692}
1693
1694impl AnyonModelImplementation for ParafermionAnyons {
1695 fn get_anyon_types(&self) -> Vec<AnyonType> {
1696 self.anyon_types.clone()
1697 }
1698 fn fusion_coefficients(&self, _a: &AnyonType, _b: &AnyonType, _c: &AnyonType) -> Complex64 {
1699 Complex64::new(1.0, 0.0)
1700 }
1701 fn braiding_matrix(&self, _a: &AnyonType, _b: &AnyonType) -> Array2<Complex64> {
1702 Array2::eye(1)
1703 }
1704 fn f_matrix(
1705 &self,
1706 _a: &AnyonType,
1707 _b: &AnyonType,
1708 _c: &AnyonType,
1709 _d: &AnyonType,
1710 ) -> Array2<Complex64> {
1711 Array2::eye(1)
1712 }
1713 fn is_abelian(&self) -> bool {
1714 false
1715 }
1716 fn name(&self) -> &str {
1717 "Parafermion Anyons"
1718 }
1719}
1720
1721pub struct ChernSimonsAnyons {
1722 level: u32,
1723 anyon_types: Vec<AnyonType>,
1724}
1725
1726impl ChernSimonsAnyons {
1727 pub fn new(level: u32) -> Self {
1728 Self {
1729 level,
1730 anyon_types: vec![AnyonType::vacuum()],
1731 }
1732 }
1733}
1734
1735impl AnyonModelImplementation for ChernSimonsAnyons {
1736 fn get_anyon_types(&self) -> Vec<AnyonType> {
1737 self.anyon_types.clone()
1738 }
1739 fn fusion_coefficients(&self, _a: &AnyonType, _b: &AnyonType, _c: &AnyonType) -> Complex64 {
1740 Complex64::new(1.0, 0.0)
1741 }
1742 fn braiding_matrix(&self, _a: &AnyonType, _b: &AnyonType) -> Array2<Complex64> {
1743 Array2::eye(1)
1744 }
1745 fn f_matrix(
1746 &self,
1747 _a: &AnyonType,
1748 _b: &AnyonType,
1749 _c: &AnyonType,
1750 _d: &AnyonType,
1751 ) -> Array2<Complex64> {
1752 Array2::eye(1)
1753 }
1754 fn is_abelian(&self) -> bool {
1755 self.level <= 2
1756 }
1757 fn name(&self) -> &str {
1758 "Chern-Simons Anyons"
1759 }
1760}
1761
1762pub struct TopologicalUtils;
1764
1765impl TopologicalUtils {
1766 pub fn create_predefined_config(config_type: &str, size: usize) -> TopologicalConfig {
1768 match config_type {
1769 "toric_code" => TopologicalConfig {
1770 lattice_type: LatticeType::SquareLattice,
1771 dimensions: vec![size, size],
1772 anyon_model: AnyonModel::Abelian,
1773 boundary_conditions: TopologicalBoundaryConditions::Periodic,
1774 error_correction_code: TopologicalErrorCode::SurfaceCode,
1775 topological_protection: true,
1776 enable_braiding: false,
1777 ..Default::default()
1778 },
1779 "fibonacci_system" => TopologicalConfig {
1780 lattice_type: LatticeType::TriangularLattice,
1781 dimensions: vec![size, size],
1782 anyon_model: AnyonModel::Fibonacci,
1783 boundary_conditions: TopologicalBoundaryConditions::Open,
1784 topological_protection: true,
1785 enable_braiding: true,
1786 ..Default::default()
1787 },
1788 "majorana_system" => TopologicalConfig {
1789 lattice_type: LatticeType::HoneycombLattice,
1790 dimensions: vec![size, size],
1791 anyon_model: AnyonModel::Ising,
1792 boundary_conditions: TopologicalBoundaryConditions::Open,
1793 topological_protection: true,
1794 enable_braiding: true,
1795 ..Default::default()
1796 },
1797 _ => TopologicalConfig::default(),
1798 }
1799 }
1800
1801 pub fn benchmark_topological_simulation() -> Result<TopologicalBenchmarkResults> {
1803 let mut results = TopologicalBenchmarkResults::default();
1804
1805 let configs = vec![
1806 (
1807 "toric_code",
1808 TopologicalUtils::create_predefined_config("toric_code", 4),
1809 ),
1810 (
1811 "fibonacci",
1812 TopologicalUtils::create_predefined_config("fibonacci_system", 3),
1813 ),
1814 (
1815 "majorana",
1816 TopologicalUtils::create_predefined_config("majorana_system", 3),
1817 ),
1818 ];
1819
1820 for (name, config) in configs {
1821 let mut simulator = TopologicalQuantumSimulator::new(config)?;
1822
1823 if simulator.config.enable_braiding {
1825 let vacuum = AnyonType::vacuum();
1826 simulator.place_anyon(vacuum.clone(), vec![0, 0])?;
1827 simulator.place_anyon(vacuum, vec![1, 1])?;
1828 }
1829
1830 let start = std::time::Instant::now();
1831
1832 if simulator.config.enable_braiding && simulator.state.anyon_config.anyons.len() >= 2 {
1834 simulator.braid_anyons(0, 1, BraidingType::Clockwise)?;
1835 }
1836
1837 simulator.calculate_topological_invariants()?;
1838
1839 let time = start.elapsed().as_secs_f64() * 1000.0;
1840
1841 results.benchmark_times.push((name.to_string(), time));
1842 results
1843 .simulation_stats
1844 .insert(name.to_string(), simulator.get_stats().clone());
1845 }
1846
1847 Ok(results)
1848 }
1849}
1850
1851#[derive(Debug, Clone, Default)]
1853pub struct TopologicalBenchmarkResults {
1854 pub benchmark_times: Vec<(String, f64)>,
1856 pub simulation_stats: HashMap<String, TopologicalSimulationStats>,
1858}
1859
1860#[cfg(test)]
1861mod tests {
1862 use super::*;
1863 use approx::assert_abs_diff_eq;
1864
1865 #[test]
1866 fn test_topological_config_default() {
1867 let config = TopologicalConfig::default();
1868 assert_eq!(config.lattice_type, LatticeType::SquareLattice);
1869 assert_eq!(config.dimensions, vec![8, 8]);
1870 assert!(config.topological_protection);
1871 }
1872
1873 #[test]
1874 fn test_anyon_type_creation() {
1875 let vacuum = AnyonType::vacuum();
1876 assert_eq!(vacuum.label, "vacuum");
1877 assert_eq!(vacuum.quantum_dimension, 1.0);
1878 assert!(vacuum.is_abelian);
1879
1880 let sigma = AnyonType::sigma();
1881 assert_eq!(sigma.label, "sigma");
1882 assert_abs_diff_eq!(sigma.quantum_dimension, 2.0_f64.sqrt(), epsilon = 1e-10);
1883 assert!(!sigma.is_abelian);
1884 }
1885
1886 #[test]
1887 fn test_topological_simulator_creation() {
1888 let config = TopologicalConfig::default();
1889 let simulator = TopologicalQuantumSimulator::new(config);
1890 assert!(simulator.is_ok());
1891 }
1892
1893 #[test]
1894 fn test_square_lattice_creation() {
1895 let dimensions = vec![3, 3];
1896 let lattice = TopologicalQuantumSimulator::create_square_lattice(&dimensions).unwrap();
1897
1898 assert_eq!(lattice.sites.len(), 9); assert_eq!(lattice.coordination_number, 4);
1900 assert!(!lattice.bonds.is_empty());
1901 assert!(!lattice.plaquettes.is_empty());
1902 }
1903
1904 #[test]
1905 fn test_anyon_placement() {
1906 let config = TopologicalConfig::default();
1907 let mut simulator = TopologicalQuantumSimulator::new(config).unwrap();
1908
1909 let vacuum = AnyonType::vacuum();
1910 let anyon_id = simulator.place_anyon(vacuum, vec![2, 3]).unwrap();
1911
1912 assert_eq!(anyon_id, 0);
1913 assert_eq!(simulator.state.anyon_config.anyons.len(), 1);
1914 assert_eq!(simulator.state.anyon_config.anyons[0].0, vec![2, 3]);
1915 }
1916
1917 #[test]
1918 fn test_braiding_operation() {
1919 let mut config = TopologicalConfig::default();
1920 config.enable_braiding = true;
1921 let mut simulator = TopologicalQuantumSimulator::new(config).unwrap();
1922
1923 let sigma = AnyonType::sigma();
1924 let anyon_a = simulator.place_anyon(sigma.clone(), vec![1, 1]).unwrap();
1925 let anyon_b = simulator.place_anyon(sigma, vec![2, 2]).unwrap();
1926
1927 let braiding_phase = simulator.braid_anyons(anyon_a, anyon_b, BraidingType::Clockwise);
1928 assert!(braiding_phase.is_ok());
1929 assert_eq!(simulator.braiding_history.len(), 1);
1930 assert_eq!(simulator.stats.braiding_operations, 1);
1931 }
1932
1933 #[test]
1934 fn test_anyon_fusion() {
1935 let config = TopologicalConfig::default();
1936 let mut simulator = TopologicalQuantumSimulator::new(config).unwrap();
1937
1938 let sigma = AnyonType::sigma();
1939 let anyon_a = simulator.place_anyon(sigma.clone(), vec![1, 1]).unwrap();
1940 let anyon_b = simulator.place_anyon(sigma, vec![1, 2]).unwrap();
1941
1942 let fusion_outcomes = simulator.fuse_anyons(anyon_a, anyon_b);
1943 assert!(fusion_outcomes.is_ok());
1944 }
1945
1946 #[test]
1947 fn test_fibonacci_anyons() {
1948 let fibonacci_model = FibonacciAnyons::new();
1949 let anyon_types = fibonacci_model.get_anyon_types();
1950
1951 assert_eq!(anyon_types.len(), 2); assert!(!fibonacci_model.is_abelian());
1953 assert_eq!(fibonacci_model.name(), "Fibonacci Anyons");
1954 }
1955
1956 #[test]
1957 fn test_ising_anyons() {
1958 let ising_model = IsingAnyons::new();
1959 let anyon_types = ising_model.get_anyon_types();
1960
1961 assert_eq!(anyon_types.len(), 3); assert!(!ising_model.is_abelian());
1963 assert_eq!(ising_model.name(), "Ising Anyons");
1964 }
1965
1966 #[test]
1967 fn test_surface_code_creation() {
1968 let dimensions = vec![4, 4];
1969 let surface_code =
1970 TopologicalQuantumSimulator::create_toric_surface_code(&dimensions).unwrap();
1971
1972 assert_eq!(surface_code.distance, 4);
1973 assert!(!surface_code.data_qubits.is_empty());
1974 assert!(!surface_code.x_stabilizers.is_empty());
1975 assert!(!surface_code.z_stabilizers.is_empty());
1976 }
1977
1978 #[test]
1979 fn test_topological_invariants() {
1980 let config = TopologicalConfig::default();
1981 let mut simulator = TopologicalQuantumSimulator::new(config).unwrap();
1982
1983 let invariants = simulator.calculate_topological_invariants();
1984 assert!(invariants.is_ok());
1985
1986 let inv = invariants.unwrap();
1987 assert!(inv.chern_number.abs() >= 0);
1988 assert!(inv.hall_conductivity.is_finite());
1989 }
1990
1991 #[test]
1992 fn test_triangular_lattice() {
1993 let dimensions = vec![3, 3];
1994 let lattice = TopologicalQuantumSimulator::create_triangular_lattice(&dimensions).unwrap();
1995
1996 assert_eq!(lattice.lattice_type, LatticeType::TriangularLattice);
1997 assert_eq!(lattice.sites.len(), 9);
1998 assert_eq!(lattice.coordination_number, 6);
1999 }
2000
2001 #[test]
2002 fn test_honeycomb_lattice() {
2003 let dimensions = vec![2, 2];
2004 let lattice = TopologicalQuantumSimulator::create_honeycomb_lattice(&dimensions).unwrap();
2005
2006 assert_eq!(lattice.lattice_type, LatticeType::HoneycombLattice);
2007 assert_eq!(lattice.coordination_number, 3);
2008 assert!(!lattice.bonds.is_empty());
2009 }
2010
2011 #[test]
2012 fn test_error_detection_and_correction() {
2013 let mut config = TopologicalConfig::default();
2014 config.topological_protection = true;
2015 let mut simulator = TopologicalQuantumSimulator::new(config).unwrap();
2016
2017 let syndrome = simulator.detect_and_correct_errors();
2018 assert!(syndrome.is_ok());
2019 }
2020
2021 #[test]
2022 fn test_predefined_configs() {
2023 let configs = vec!["toric_code", "fibonacci_system", "majorana_system"];
2024
2025 for config_type in configs {
2026 let config = TopologicalUtils::create_predefined_config(config_type, 4);
2027 let simulator = TopologicalQuantumSimulator::new(config);
2028 assert!(simulator.is_ok());
2029 }
2030 }
2031}