1use scirs2_core::ndarray::{Array1, Array2, Array3, Array4, Axis};
9use scirs2_core::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 = f64::midpoint(1.0, 5.0_f64.sqrt());
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).mul_add(
610 3.0_f64.sqrt(),
611 if x % 2 == 1 {
612 3.0_f64.sqrt() / 2.0
613 } else {
614 0.0
615 },
616 );
617 sites.push(vec![x_pos, y_pos]);
618 }
619 }
620
621 for y in 0..height {
623 for x in 0..width {
624 let site = y * width + x;
625
626 if x < width - 1 {
628 bonds.push((site, site + 1));
629 }
630
631 if y < height - 1 {
633 bonds.push((site, site + width));
634 }
635
636 if y > 0 {
637 bonds.push((site, site - width));
638 }
639 }
640 }
641
642 for y in 1..height - 1 {
644 for x in 1..width - 1 {
645 let plaquette = vec![
646 (y - 1) * width + x,
647 (y - 1) * width + x + 1,
648 y * width + x + 1,
649 (y + 1) * width + x + 1,
650 (y + 1) * width + x,
651 y * width + x,
652 ];
653 plaquettes.push(plaquette);
654 }
655 }
656
657 Ok(TopologicalLattice {
658 lattice_type: LatticeType::HexagonalLattice,
659 dimensions: dimensions.to_vec(),
660 sites,
661 bonds,
662 plaquettes,
663 coordination_number: 3,
664 })
665 }
666
667 fn create_honeycomb_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
669 if dimensions.len() != 2 {
670 return Err(SimulatorError::InvalidInput(
671 "Honeycomb lattice requires 2D dimensions".to_string(),
672 ));
673 }
674
675 let (width, height) = (dimensions[0], dimensions[1]);
676 let mut sites = Vec::new();
677 let mut bonds = Vec::new();
678 let mut plaquettes = Vec::new();
679
680 for y in 0..height {
682 for x in 0..width {
683 let x_a = x as f64 * 3.0 / 2.0;
685 let y_a = y as f64 * 3.0_f64.sqrt();
686 sites.push(vec![x_a, y_a]);
687
688 let x_b = x as f64 * 3.0 / 2.0 + 1.0;
690 let y_b = (y as f64).mul_add(3.0_f64.sqrt(), 3.0_f64.sqrt() / 3.0);
691 sites.push(vec![x_b, y_b]);
692 }
693 }
694
695 for y in 0..height {
697 for x in 0..width {
698 let a_site = 2 * (y * width + x);
699 let b_site = a_site + 1;
700
701 bonds.push((a_site, b_site));
703
704 if x < width - 1 {
706 bonds.push((b_site, a_site + 2));
707 }
708
709 if y < height - 1 {
710 bonds.push((b_site, a_site + 2 * width));
711 }
712 }
713 }
714
715 for y in 0..height - 1 {
717 for x in 0..width - 1 {
718 let plaquette = vec![
719 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, ];
726 plaquettes.push(plaquette);
727 }
728 }
729
730 Ok(TopologicalLattice {
731 lattice_type: LatticeType::HoneycombLattice,
732 dimensions: dimensions.to_vec(),
733 sites,
734 bonds,
735 plaquettes,
736 coordination_number: 3,
737 })
738 }
739
740 fn create_kagome_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
742 if dimensions.len() != 2 {
743 return Err(SimulatorError::InvalidInput(
744 "Kagome lattice requires 2D dimensions".to_string(),
745 ));
746 }
747
748 let (width, height) = (dimensions[0], dimensions[1]);
749 let mut sites = Vec::new();
750 let mut bonds = Vec::new();
751 let mut plaquettes = Vec::new();
752
753 for y in 0..height {
755 for x in 0..width {
756 let base_x = x as f64 * 2.0;
757 let base_y = y as f64 * 3.0_f64.sqrt();
758
759 sites.push(vec![base_x, base_y]);
761 sites.push(vec![base_x + 1.0, base_y]);
762 sites.push(vec![base_x + 0.5, base_y + 3.0_f64.sqrt() / 2.0]);
763 }
764 }
765
766 for y in 0..height {
768 for x in 0..width {
769 let base_site = 3 * (y * width + x);
770
771 bonds.push((base_site, base_site + 1));
773 bonds.push((base_site + 1, base_site + 2));
774 bonds.push((base_site + 2, base_site));
775
776 if x < width - 1 {
778 bonds.push((base_site + 1, base_site + 3));
779 }
780
781 if y < height - 1 {
782 bonds.push((base_site + 2, base_site + 3 * width));
783 }
784 }
785 }
786
787 for y in 0..height {
789 for x in 0..width {
790 let base_site = 3 * (y * width + x);
791
792 let triangle = vec![base_site, base_site + 1, base_site + 2];
794 plaquettes.push(triangle);
795
796 if x < width - 1 && y < height - 1 {
798 let hexagon = vec![
799 base_site + 1,
800 base_site + 3,
801 base_site + 3 + 2,
802 base_site + 3 * width + 2,
803 base_site + 3 * width,
804 base_site + 2,
805 ];
806 plaquettes.push(hexagon);
807 }
808 }
809 }
810
811 Ok(TopologicalLattice {
812 lattice_type: LatticeType::KagomeLattice,
813 dimensions: dimensions.to_vec(),
814 sites,
815 bonds,
816 plaquettes,
817 coordination_number: 4,
818 })
819 }
820
821 fn create_custom_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
823 Self::create_square_lattice(dimensions)
825 }
826
827 fn create_anyon_model(
829 model: &AnyonModel,
830 ) -> Result<Box<dyn AnyonModelImplementation + Send + Sync>> {
831 match model {
832 AnyonModel::Abelian => Ok(Box::new(AbelianAnyons::new())),
833 AnyonModel::NonAbelian => Ok(Box::new(NonAbelianAnyons::new())),
834 AnyonModel::Fibonacci => Ok(Box::new(FibonacciAnyons::new())),
835 AnyonModel::Ising => Ok(Box::new(IsingAnyons::new())),
836 AnyonModel::Parafermion => Ok(Box::new(ParafermionAnyons::new())),
837 AnyonModel::ChernSimons(k) => Ok(Box::new(ChernSimonsAnyons::new(*k))),
838 }
839 }
840
841 fn create_initial_topological_state(
843 config: &TopologicalConfig,
844 lattice: &TopologicalLattice,
845 ) -> Result<TopologicalState> {
846 let anyon_config = AnyonConfiguration {
848 anyons: Vec::new(),
849 worldlines: Vec::new(),
850 fusion_tree: None,
851 total_charge: 0,
852 };
853
854 let degeneracy = Self::calculate_ground_state_degeneracy(config, lattice);
856 let amplitudes = Array1::zeros(degeneracy);
857
858 let topological_invariants = TopologicalInvariants::default();
859
860 Ok(TopologicalState {
861 anyon_config,
862 amplitudes,
863 degeneracy,
864 topological_invariants,
865 energy_gap: config.magnetic_field, })
867 }
868
869 fn calculate_ground_state_degeneracy(
871 config: &TopologicalConfig,
872 lattice: &TopologicalLattice,
873 ) -> usize {
874 match config.anyon_model {
875 AnyonModel::Abelian => {
876 let genus = Self::calculate_genus(lattice);
878 2_usize.pow(genus as u32)
879 }
880 AnyonModel::Fibonacci => {
881 let num_qubits = lattice.sites.len() / 2;
883 let golden_ratio = f64::midpoint(1.0, 5.0_f64.sqrt());
884 (golden_ratio.powi(num_qubits as i32) / 5.0_f64.sqrt()).round() as usize
885 }
886 AnyonModel::Ising => {
887 let num_majoranas = lattice.sites.len();
889 2_usize.pow((num_majoranas / 2) as u32)
890 }
891 _ => 1, }
893 }
894
895 fn calculate_genus(lattice: &TopologicalLattice) -> usize {
897 let vertices = lattice.sites.len();
899 let edges = lattice.bonds.len();
900 let faces = lattice.plaquettes.len() + 1; let euler_characteristic = vertices as i32 - edges as i32 + faces as i32;
903 let genus = (2 - euler_characteristic) / 2;
904 genus.max(0) as usize
905 }
906
907 fn create_surface_code(
909 config: &TopologicalConfig,
910 lattice: &TopologicalLattice,
911 ) -> Result<SurfaceCode> {
912 match config.error_correction_code {
913 TopologicalErrorCode::SurfaceCode => {
914 Self::create_toric_surface_code(&config.dimensions)
915 }
916 TopologicalErrorCode::ColorCode => Self::create_color_code(&config.dimensions),
917 _ => {
918 Self::create_toric_surface_code(&config.dimensions)
920 }
921 }
922 }
923
924 fn create_toric_surface_code(dimensions: &[usize]) -> Result<SurfaceCode> {
926 if dimensions.len() != 2 {
927 return Err(SimulatorError::InvalidInput(
928 "Surface code requires 2D lattice".to_string(),
929 ));
930 }
931
932 let distance = dimensions[0].min(dimensions[1]);
933 let mut data_qubits = Vec::new();
934 let mut x_stabilizers = Vec::new();
935 let mut z_stabilizers = Vec::new();
936
937 for y in 0..distance {
939 for x in 0..distance {
940 data_qubits.push(vec![x, y, 0]); data_qubits.push(vec![x, y, 1]); }
945 }
946
947 for y in 0..distance {
949 for x in 0..distance {
950 let stabilizer_pos = vec![x, y];
951 x_stabilizers.push(stabilizer_pos);
952 }
953 }
954
955 for y in 0..distance - 1 {
957 for x in 0..distance - 1 {
958 let stabilizer_pos = vec![x, y];
959 z_stabilizers.push(stabilizer_pos);
960 }
961 }
962
963 let logical_x = vec![Array1::from_elem(distance, true)];
965 let logical_z = vec![Array1::from_elem(distance, true)];
966
967 let logical_operators = LogicalOperators {
968 logical_x,
969 logical_z,
970 num_logical_qubits: 1,
971 };
972
973 let mut syndrome_detectors = Vec::new();
975
976 for stabilizer in &x_stabilizers {
977 let detector = SyndromeDetector {
978 stabilizer_type: StabilizerType::PauliX,
979 measured_qubits: vec![0, 1, 2, 3], threshold: 0.5,
981 correction_map: HashMap::new(),
982 };
983 syndrome_detectors.push(detector);
984 }
985
986 for stabilizer in &z_stabilizers {
987 let detector = SyndromeDetector {
988 stabilizer_type: StabilizerType::PauliZ,
989 measured_qubits: vec![0, 1, 2, 3], threshold: 0.5,
991 correction_map: HashMap::new(),
992 };
993 syndrome_detectors.push(detector);
994 }
995
996 Ok(SurfaceCode {
997 distance,
998 data_qubits,
999 x_stabilizers,
1000 z_stabilizers,
1001 logical_operators,
1002 syndrome_detectors,
1003 })
1004 }
1005
1006 fn create_color_code(dimensions: &[usize]) -> Result<SurfaceCode> {
1008 Self::create_toric_surface_code(dimensions)
1010 }
1011
1012 pub fn place_anyon(&mut self, anyon_type: AnyonType, position: Vec<usize>) -> Result<usize> {
1014 if position.len() != self.config.dimensions.len() {
1016 return Err(SimulatorError::InvalidInput(
1017 "Position dimension mismatch".to_string(),
1018 ));
1019 }
1020
1021 for (i, &pos) in position.iter().enumerate() {
1022 if pos >= self.config.dimensions[i] {
1023 return Err(SimulatorError::InvalidInput(
1024 "Position out of bounds".to_string(),
1025 ));
1026 }
1027 }
1028
1029 let anyon_id = self.state.anyon_config.anyons.len();
1031 self.state
1032 .anyon_config
1033 .anyons
1034 .push((position.clone(), anyon_type.clone()));
1035
1036 self.state.anyon_config.total_charge += anyon_type.topological_charge;
1038
1039 let worldline = AnyonWorldline {
1041 anyon_type,
1042 path: vec![position],
1043 time_stamps: vec![0.0],
1044 accumulated_phase: Complex64::new(1.0, 0.0),
1045 };
1046 self.state.anyon_config.worldlines.push(worldline);
1047
1048 Ok(anyon_id)
1049 }
1050
1051 pub fn braid_anyons(
1053 &mut self,
1054 anyon_a: usize,
1055 anyon_b: usize,
1056 braiding_type: BraidingType,
1057 ) -> Result<Complex64> {
1058 let start_time = std::time::Instant::now();
1059
1060 if anyon_a >= self.state.anyon_config.anyons.len()
1061 || anyon_b >= self.state.anyon_config.anyons.len()
1062 {
1063 return Err(SimulatorError::InvalidInput(
1064 "Invalid anyon indices".to_string(),
1065 ));
1066 }
1067
1068 let (_, ref type_a) = &self.state.anyon_config.anyons[anyon_a];
1069 let (_, ref type_b) = &self.state.anyon_config.anyons[anyon_b];
1070
1071 let braiding_matrix = self.anyon_model.braiding_matrix(type_a, type_b);
1073
1074 let braiding_phase = match braiding_type {
1076 BraidingType::Clockwise => type_a.r_matrix * type_b.r_matrix.conj(),
1077 BraidingType::Counterclockwise => type_a.r_matrix.conj() * type_b.r_matrix,
1078 BraidingType::Exchange => type_a.r_matrix * type_b.r_matrix,
1079 BraidingType::Identity => Complex64::new(1.0, 0.0),
1080 };
1081
1082 let current_time = self.braiding_history.len() as f64;
1084 if anyon_a < self.state.anyon_config.worldlines.len() {
1085 self.state.anyon_config.worldlines[anyon_a]
1086 .time_stamps
1087 .push(current_time);
1088 self.state.anyon_config.worldlines[anyon_a].accumulated_phase *= braiding_phase;
1089 }
1090 if anyon_b < self.state.anyon_config.worldlines.len() {
1091 self.state.anyon_config.worldlines[anyon_b]
1092 .time_stamps
1093 .push(current_time);
1094 self.state.anyon_config.worldlines[anyon_b].accumulated_phase *= braiding_phase.conj();
1095 }
1096
1097 for amplitude in &mut self.state.amplitudes {
1099 *amplitude *= braiding_phase;
1100 }
1101
1102 let execution_time = start_time.elapsed().as_secs_f64() * 1000.0;
1103
1104 let braiding_op = BraidingOperation {
1106 anyon_indices: vec![anyon_a, anyon_b],
1107 braiding_type,
1108 braiding_matrix,
1109 execution_time,
1110 };
1111 self.braiding_history.push(braiding_op);
1112
1113 self.stats.braiding_operations += 1;
1115 self.stats.avg_braiding_time_ms = self
1116 .stats
1117 .avg_braiding_time_ms
1118 .mul_add((self.stats.braiding_operations - 1) as f64, execution_time)
1119 / self.stats.braiding_operations as f64;
1120
1121 Ok(braiding_phase)
1122 }
1123
1124 pub fn move_anyon(&mut self, anyon_id: usize, new_position: Vec<usize>) -> Result<()> {
1126 if anyon_id >= self.state.anyon_config.anyons.len() {
1127 return Err(SimulatorError::InvalidInput("Invalid anyon ID".to_string()));
1128 }
1129
1130 for (i, &pos) in new_position.iter().enumerate() {
1132 if pos >= self.config.dimensions[i] {
1133 return Err(SimulatorError::InvalidInput(
1134 "New position out of bounds".to_string(),
1135 ));
1136 }
1137 }
1138
1139 self.state.anyon_config.anyons[anyon_id].0 = new_position.clone();
1141
1142 if anyon_id < self.state.anyon_config.worldlines.len() {
1144 self.state.anyon_config.worldlines[anyon_id]
1145 .path
1146 .push(new_position);
1147 let current_time = self.braiding_history.len() as f64;
1148 self.state.anyon_config.worldlines[anyon_id]
1149 .time_stamps
1150 .push(current_time);
1151 }
1152
1153 Ok(())
1154 }
1155
1156 pub fn fuse_anyons(&mut self, anyon_a: usize, anyon_b: usize) -> Result<Vec<AnyonType>> {
1158 if anyon_a >= self.state.anyon_config.anyons.len()
1159 || anyon_b >= self.state.anyon_config.anyons.len()
1160 {
1161 return Err(SimulatorError::InvalidInput(
1162 "Invalid anyon indices".to_string(),
1163 ));
1164 }
1165
1166 let type_a = &self.state.anyon_config.anyons[anyon_a].1;
1167 let type_b = &self.state.anyon_config.anyons[anyon_b].1;
1168
1169 let fusion_outcomes = if let Some(outcomes) = type_a.fusion_rules.get(&type_b.label) {
1171 outcomes.clone()
1172 } else {
1173 vec!["vacuum".to_string()] };
1175
1176 let outcome_types: Vec<AnyonType> = fusion_outcomes
1178 .iter()
1179 .map(|label| self.create_anyon_from_label(label))
1180 .collect::<Result<Vec<_>>>()?;
1181
1182 let mut indices_to_remove = vec![anyon_a, anyon_b];
1186 indices_to_remove.sort_by(|a, b| b.cmp(a)); for &index in &indices_to_remove {
1189 if index < self.state.anyon_config.anyons.len() {
1190 self.state.anyon_config.anyons.remove(index);
1191 }
1192 if index < self.state.anyon_config.worldlines.len() {
1193 self.state.anyon_config.worldlines.remove(index);
1194 }
1195 }
1196
1197 Ok(outcome_types)
1198 }
1199
1200 fn create_anyon_from_label(&self, label: &str) -> Result<AnyonType> {
1202 match label {
1203 "vacuum" => Ok(AnyonType::vacuum()),
1204 "sigma" => Ok(AnyonType::sigma()),
1205 "tau" => Ok(AnyonType::tau()),
1206 _ => {
1207 Ok(AnyonType {
1209 label: label.to_string(),
1210 quantum_dimension: 1.0,
1211 topological_charge: 0,
1212 fusion_rules: HashMap::new(),
1213 r_matrix: Complex64::new(1.0, 0.0),
1214 is_abelian: true,
1215 })
1216 }
1217 }
1218 }
1219
1220 pub fn calculate_topological_invariants(&mut self) -> Result<TopologicalInvariants> {
1222 let mut invariants = TopologicalInvariants::default();
1223
1224 invariants.chern_number = self.calculate_chern_number()?;
1226
1227 invariants.winding_number = self.calculate_winding_number()?;
1229
1230 invariants.z2_invariant = self.calculate_z2_invariant()?;
1232
1233 invariants.berry_phase = self.calculate_berry_phase()?;
1235
1236 invariants.hall_conductivity = invariants.chern_number as f64 * 2.0 * PI / 137.0; invariants.topological_entanglement_entropy =
1241 self.calculate_topological_entanglement_entropy()?;
1242
1243 self.state.topological_invariants = invariants.clone();
1244 Ok(invariants)
1245 }
1246
1247 fn calculate_chern_number(&self) -> Result<i32> {
1249 let magnetic_flux = self.config.magnetic_field * self.lattice.sites.len() as f64;
1252 let flux_quanta = (magnetic_flux / (2.0 * PI)).round() as i32;
1253 Ok(flux_quanta)
1254 }
1255
1256 fn calculate_winding_number(&self) -> Result<i32> {
1258 match self.config.dimensions.len() {
1260 1 => Ok(1), _ => Ok(0), }
1263 }
1264
1265 fn calculate_z2_invariant(&self) -> Result<bool> {
1267 let time_reversal_broken = self.config.magnetic_field.abs() > 1e-10;
1269 Ok(!time_reversal_broken)
1270 }
1271
1272 fn calculate_berry_phase(&self) -> Result<f64> {
1274 let total_braiding_phase: Complex64 = self
1276 .state
1277 .anyon_config
1278 .worldlines
1279 .iter()
1280 .map(|wl| wl.accumulated_phase)
1281 .fold(Complex64::new(1.0, 0.0), |acc, phase| acc * phase);
1282
1283 Ok(total_braiding_phase.arg())
1284 }
1285
1286 fn calculate_topological_entanglement_entropy(&self) -> Result<f64> {
1288 let total_quantum_dimension: f64 = self
1290 .anyon_model
1291 .get_anyon_types()
1292 .iter()
1293 .map(|anyon| anyon.quantum_dimension * anyon.quantum_dimension)
1294 .sum();
1295
1296 let gamma = match self.config.anyon_model {
1297 AnyonModel::Abelian => 0.0,
1298 AnyonModel::Fibonacci => 0.5 * (5.0_f64.sqrt() - 1.0) / 2.0, AnyonModel::Ising => 0.5,
1300 _ => 0.5, };
1302
1303 Ok(-gamma * total_quantum_dimension.ln())
1304 }
1305
1306 pub fn detect_and_correct_errors(&mut self) -> Result<Vec<bool>> {
1308 if let Some(ref surface_code) = self.error_correction {
1309 let mut syndrome = Vec::new();
1310
1311 for detector in &surface_code.syndrome_detectors {
1313 let measurement = self.measure_stabilizer(detector)?;
1314 syndrome.push(measurement);
1315 }
1316
1317 let corrections = self.decode_syndrome(&syndrome)?;
1319 self.apply_corrections(&corrections)?;
1320
1321 self.stats.error_corrections += 1;
1322 Ok(syndrome)
1323 } else {
1324 Ok(Vec::new())
1325 }
1326 }
1327
1328 fn measure_stabilizer(&self, detector: &SyndromeDetector) -> Result<bool> {
1330 let probability = match detector.stabilizer_type {
1333 StabilizerType::PauliX => 0.1, StabilizerType::PauliZ => 0.1,
1335 StabilizerType::XZ => 0.05,
1336 };
1337
1338 Ok(fastrand::f64() < probability)
1339 }
1340
1341 fn decode_syndrome(&self, syndrome: &[bool]) -> Result<Vec<usize>> {
1343 let mut corrections = Vec::new();
1346
1347 for (i, &error) in syndrome.iter().enumerate() {
1348 if error {
1349 corrections.push(i);
1350 }
1351 }
1352
1353 Ok(corrections)
1354 }
1355
1356 fn apply_corrections(&mut self, corrections: &[usize]) -> Result<()> {
1358 for &correction_site in corrections {
1360 if correction_site < self.state.amplitudes.len() {
1361 self.state.amplitudes[correction_site] *= Complex64::new(-1.0, 0.0);
1364 }
1365 }
1366
1367 Ok(())
1368 }
1369
1370 pub const fn get_state(&self) -> &TopologicalState {
1372 &self.state
1373 }
1374
1375 pub fn get_braiding_history(&self) -> &[BraidingOperation] {
1377 &self.braiding_history
1378 }
1379
1380 pub const fn get_stats(&self) -> &TopologicalSimulationStats {
1382 &self.stats
1383 }
1384
1385 pub fn reset(&mut self) -> Result<()> {
1387 self.state = Self::create_initial_topological_state(&self.config, &self.lattice)?;
1388 self.braiding_history.clear();
1389 self.stats = TopologicalSimulationStats::default();
1390 Ok(())
1391 }
1392}
1393
1394pub struct AbelianAnyons {
1398 anyon_types: Vec<AnyonType>,
1399}
1400
1401impl Default for AbelianAnyons {
1402 fn default() -> Self {
1403 Self::new()
1404 }
1405}
1406
1407impl AbelianAnyons {
1408 pub fn new() -> Self {
1409 let anyon_types = vec![AnyonType::vacuum()];
1410 Self { anyon_types }
1411 }
1412}
1413
1414impl AnyonModelImplementation for AbelianAnyons {
1415 fn get_anyon_types(&self) -> Vec<AnyonType> {
1416 self.anyon_types.clone()
1417 }
1418
1419 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1420 if a.topological_charge + b.topological_charge == c.topological_charge {
1422 Complex64::new(1.0, 0.0)
1423 } else {
1424 Complex64::new(0.0, 0.0)
1425 }
1426 }
1427
1428 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1429 let phase = a.r_matrix * b.r_matrix.conj();
1430 Array2::from_shape_vec((1, 1), vec![phase]).unwrap()
1431 }
1432
1433 fn f_matrix(
1434 &self,
1435 _a: &AnyonType,
1436 _b: &AnyonType,
1437 _c: &AnyonType,
1438 _d: &AnyonType,
1439 ) -> Array2<Complex64> {
1440 Array2::eye(1)
1442 }
1443
1444 fn is_abelian(&self) -> bool {
1445 true
1446 }
1447
1448 fn name(&self) -> &'static str {
1449 "Abelian Anyons"
1450 }
1451}
1452
1453pub struct NonAbelianAnyons {
1455 anyon_types: Vec<AnyonType>,
1456}
1457
1458impl Default for NonAbelianAnyons {
1459 fn default() -> Self {
1460 Self::new()
1461 }
1462}
1463
1464impl NonAbelianAnyons {
1465 pub fn new() -> Self {
1466 let anyon_types = vec![AnyonType::vacuum(), AnyonType::sigma()];
1467 Self { anyon_types }
1468 }
1469}
1470
1471impl AnyonModelImplementation for NonAbelianAnyons {
1472 fn get_anyon_types(&self) -> Vec<AnyonType> {
1473 self.anyon_types.clone()
1474 }
1475
1476 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1477 if let Some(outcomes) = a.fusion_rules.get(&b.label) {
1479 if outcomes.contains(&c.label) {
1480 Complex64::new(1.0, 0.0)
1481 } else {
1482 Complex64::new(0.0, 0.0)
1483 }
1484 } else {
1485 Complex64::new(0.0, 0.0)
1486 }
1487 }
1488
1489 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1490 let dim = (a.quantum_dimension * b.quantum_dimension) as usize;
1491 let mut matrix = Array2::eye(dim);
1492
1493 if !a.is_abelian || !b.is_abelian {
1495 let phase = a.r_matrix * b.r_matrix.conj();
1496 matrix[[0, 0]] = phase;
1497 if dim > 1 {
1498 matrix[[1, 1]] = phase.conj();
1499 }
1500 }
1501
1502 matrix
1503 }
1504
1505 fn f_matrix(
1506 &self,
1507 _a: &AnyonType,
1508 _b: &AnyonType,
1509 _c: &AnyonType,
1510 _d: &AnyonType,
1511 ) -> Array2<Complex64> {
1512 Array2::eye(2)
1514 }
1515
1516 fn is_abelian(&self) -> bool {
1517 false
1518 }
1519
1520 fn name(&self) -> &'static str {
1521 "Non-Abelian Anyons"
1522 }
1523}
1524
1525pub struct FibonacciAnyons {
1527 anyon_types: Vec<AnyonType>,
1528}
1529
1530impl Default for FibonacciAnyons {
1531 fn default() -> Self {
1532 Self::new()
1533 }
1534}
1535
1536impl FibonacciAnyons {
1537 pub fn new() -> Self {
1538 let anyon_types = vec![AnyonType::vacuum(), AnyonType::tau()];
1539 Self { anyon_types }
1540 }
1541}
1542
1543impl AnyonModelImplementation for FibonacciAnyons {
1544 fn get_anyon_types(&self) -> Vec<AnyonType> {
1545 self.anyon_types.clone()
1546 }
1547
1548 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1549 match (a.label.as_str(), b.label.as_str(), c.label.as_str()) {
1551 ("tau", "tau", "vacuum" | "tau") => Complex64::new(1.0, 0.0),
1552 ("vacuum", _, label) | (_, "vacuum", label) if label == a.label || label == b.label => {
1553 Complex64::new(1.0, 0.0)
1554 }
1555 _ => Complex64::new(0.0, 0.0),
1556 }
1557 }
1558
1559 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1560 if a.label == "tau" && b.label == "tau" {
1561 let phi = f64::midpoint(1.0, 5.0_f64.sqrt()); let phase = Complex64::new(0.0, 1.0) * (4.0 * PI / 5.0).exp();
1563
1564 Array2::from_shape_vec(
1565 (2, 2),
1566 vec![
1567 phase,
1568 Complex64::new(0.0, 0.0),
1569 Complex64::new(0.0, 0.0),
1570 phase * Complex64::new(-1.0 / phi, 0.0),
1571 ],
1572 )
1573 .unwrap()
1574 } else {
1575 Array2::eye(1)
1576 }
1577 }
1578
1579 fn f_matrix(
1580 &self,
1581 _a: &AnyonType,
1582 _b: &AnyonType,
1583 _c: &AnyonType,
1584 _d: &AnyonType,
1585 ) -> Array2<Complex64> {
1586 let phi = f64::midpoint(1.0, 5.0_f64.sqrt());
1588 let inv_phi = 1.0 / phi;
1589
1590 Array2::from_shape_vec(
1591 (2, 2),
1592 vec![
1593 Complex64::new(inv_phi, 0.0),
1594 Complex64::new(inv_phi.sqrt(), 0.0),
1595 Complex64::new(inv_phi.sqrt(), 0.0),
1596 Complex64::new(-inv_phi, 0.0),
1597 ],
1598 )
1599 .unwrap()
1600 }
1601
1602 fn is_abelian(&self) -> bool {
1603 false
1604 }
1605
1606 fn name(&self) -> &'static str {
1607 "Fibonacci Anyons"
1608 }
1609}
1610
1611pub struct IsingAnyons {
1613 anyon_types: Vec<AnyonType>,
1614}
1615
1616impl Default for IsingAnyons {
1617 fn default() -> Self {
1618 Self::new()
1619 }
1620}
1621
1622impl IsingAnyons {
1623 pub fn new() -> Self {
1624 let mut psi = AnyonType {
1625 label: "psi".to_string(),
1626 quantum_dimension: 1.0,
1627 topological_charge: 1,
1628 fusion_rules: HashMap::new(),
1629 r_matrix: Complex64::new(-1.0, 0.0),
1630 is_abelian: true,
1631 };
1632 psi.fusion_rules
1633 .insert("psi".to_string(), vec!["vacuum".to_string()]);
1634
1635 let anyon_types = vec![AnyonType::vacuum(), AnyonType::sigma(), psi];
1636 Self { anyon_types }
1637 }
1638}
1639
1640impl AnyonModelImplementation for IsingAnyons {
1641 fn get_anyon_types(&self) -> Vec<AnyonType> {
1642 self.anyon_types.clone()
1643 }
1644
1645 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1646 match (a.label.as_str(), b.label.as_str(), c.label.as_str()) {
1648 ("sigma", "sigma", "vacuum" | "psi") => Complex64::new(1.0, 0.0),
1649 ("psi", "psi", "vacuum") => Complex64::new(1.0, 0.0),
1650 ("sigma", "psi", "sigma") | ("psi", "sigma", "sigma") => Complex64::new(1.0, 0.0),
1651 ("vacuum", _, label) | (_, "vacuum", label) if label == a.label || label == b.label => {
1652 Complex64::new(1.0, 0.0)
1653 }
1654 _ => Complex64::new(0.0, 0.0),
1655 }
1656 }
1657
1658 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1659 let phase = a.r_matrix * b.r_matrix.conj();
1660
1661 if a.label == "sigma" && b.label == "sigma" {
1662 Array2::from_shape_vec(
1664 (2, 2),
1665 vec![
1666 Complex64::new(0.0, 1.0) * (PI / 8.0).exp(),
1667 Complex64::new(0.0, 0.0),
1668 Complex64::new(0.0, 0.0),
1669 Complex64::new(0.0, -1.0) * (PI / 8.0).exp(),
1670 ],
1671 )
1672 .unwrap()
1673 } else {
1674 Array2::from_shape_vec((1, 1), vec![phase]).unwrap()
1675 }
1676 }
1677
1678 fn f_matrix(
1679 &self,
1680 _a: &AnyonType,
1681 _b: &AnyonType,
1682 _c: &AnyonType,
1683 _d: &AnyonType,
1684 ) -> Array2<Complex64> {
1685 let sqrt_2_inv = 1.0 / 2.0_f64.sqrt();
1687 Array2::from_shape_vec(
1688 (2, 2),
1689 vec![
1690 Complex64::new(sqrt_2_inv, 0.0),
1691 Complex64::new(sqrt_2_inv, 0.0),
1692 Complex64::new(sqrt_2_inv, 0.0),
1693 Complex64::new(-sqrt_2_inv, 0.0),
1694 ],
1695 )
1696 .unwrap()
1697 }
1698
1699 fn is_abelian(&self) -> bool {
1700 false
1701 }
1702
1703 fn name(&self) -> &'static str {
1704 "Ising Anyons"
1705 }
1706}
1707
1708pub struct ParafermionAnyons {
1710 anyon_types: Vec<AnyonType>,
1711}
1712
1713impl Default for ParafermionAnyons {
1714 fn default() -> Self {
1715 Self::new()
1716 }
1717}
1718
1719impl ParafermionAnyons {
1720 pub fn new() -> Self {
1721 Self {
1722 anyon_types: vec![AnyonType::vacuum()],
1723 }
1724 }
1725}
1726
1727impl AnyonModelImplementation for ParafermionAnyons {
1728 fn get_anyon_types(&self) -> Vec<AnyonType> {
1729 self.anyon_types.clone()
1730 }
1731 fn fusion_coefficients(&self, _a: &AnyonType, _b: &AnyonType, _c: &AnyonType) -> Complex64 {
1732 Complex64::new(1.0, 0.0)
1733 }
1734 fn braiding_matrix(&self, _a: &AnyonType, _b: &AnyonType) -> Array2<Complex64> {
1735 Array2::eye(1)
1736 }
1737 fn f_matrix(
1738 &self,
1739 _a: &AnyonType,
1740 _b: &AnyonType,
1741 _c: &AnyonType,
1742 _d: &AnyonType,
1743 ) -> Array2<Complex64> {
1744 Array2::eye(1)
1745 }
1746 fn is_abelian(&self) -> bool {
1747 false
1748 }
1749 fn name(&self) -> &'static str {
1750 "Parafermion Anyons"
1751 }
1752}
1753
1754pub struct ChernSimonsAnyons {
1755 level: u32,
1756 anyon_types: Vec<AnyonType>,
1757}
1758
1759impl ChernSimonsAnyons {
1760 pub fn new(level: u32) -> Self {
1761 Self {
1762 level,
1763 anyon_types: vec![AnyonType::vacuum()],
1764 }
1765 }
1766}
1767
1768impl AnyonModelImplementation for ChernSimonsAnyons {
1769 fn get_anyon_types(&self) -> Vec<AnyonType> {
1770 self.anyon_types.clone()
1771 }
1772 fn fusion_coefficients(&self, _a: &AnyonType, _b: &AnyonType, _c: &AnyonType) -> Complex64 {
1773 Complex64::new(1.0, 0.0)
1774 }
1775 fn braiding_matrix(&self, _a: &AnyonType, _b: &AnyonType) -> Array2<Complex64> {
1776 Array2::eye(1)
1777 }
1778 fn f_matrix(
1779 &self,
1780 _a: &AnyonType,
1781 _b: &AnyonType,
1782 _c: &AnyonType,
1783 _d: &AnyonType,
1784 ) -> Array2<Complex64> {
1785 Array2::eye(1)
1786 }
1787 fn is_abelian(&self) -> bool {
1788 self.level <= 2
1789 }
1790 fn name(&self) -> &'static str {
1791 "Chern-Simons Anyons"
1792 }
1793}
1794
1795pub struct TopologicalUtils;
1797
1798impl TopologicalUtils {
1799 pub fn create_predefined_config(config_type: &str, size: usize) -> TopologicalConfig {
1801 match config_type {
1802 "toric_code" => TopologicalConfig {
1803 lattice_type: LatticeType::SquareLattice,
1804 dimensions: vec![size, size],
1805 anyon_model: AnyonModel::Abelian,
1806 boundary_conditions: TopologicalBoundaryConditions::Periodic,
1807 error_correction_code: TopologicalErrorCode::SurfaceCode,
1808 topological_protection: true,
1809 enable_braiding: false,
1810 ..Default::default()
1811 },
1812 "fibonacci_system" => TopologicalConfig {
1813 lattice_type: LatticeType::TriangularLattice,
1814 dimensions: vec![size, size],
1815 anyon_model: AnyonModel::Fibonacci,
1816 boundary_conditions: TopologicalBoundaryConditions::Open,
1817 topological_protection: true,
1818 enable_braiding: true,
1819 ..Default::default()
1820 },
1821 "majorana_system" => TopologicalConfig {
1822 lattice_type: LatticeType::HoneycombLattice,
1823 dimensions: vec![size, size],
1824 anyon_model: AnyonModel::Ising,
1825 boundary_conditions: TopologicalBoundaryConditions::Open,
1826 topological_protection: true,
1827 enable_braiding: true,
1828 ..Default::default()
1829 },
1830 _ => TopologicalConfig::default(),
1831 }
1832 }
1833
1834 pub fn benchmark_topological_simulation() -> Result<TopologicalBenchmarkResults> {
1836 let mut results = TopologicalBenchmarkResults::default();
1837
1838 let configs = vec![
1839 (
1840 "toric_code",
1841 Self::create_predefined_config("toric_code", 4),
1842 ),
1843 (
1844 "fibonacci",
1845 Self::create_predefined_config("fibonacci_system", 3),
1846 ),
1847 (
1848 "majorana",
1849 Self::create_predefined_config("majorana_system", 3),
1850 ),
1851 ];
1852
1853 for (name, config) in configs {
1854 let mut simulator = TopologicalQuantumSimulator::new(config)?;
1855
1856 if simulator.config.enable_braiding {
1858 let vacuum = AnyonType::vacuum();
1859 simulator.place_anyon(vacuum.clone(), vec![0, 0])?;
1860 simulator.place_anyon(vacuum, vec![1, 1])?;
1861 }
1862
1863 let start = std::time::Instant::now();
1864
1865 if simulator.config.enable_braiding && simulator.state.anyon_config.anyons.len() >= 2 {
1867 simulator.braid_anyons(0, 1, BraidingType::Clockwise)?;
1868 }
1869
1870 simulator.calculate_topological_invariants()?;
1871
1872 let time = start.elapsed().as_secs_f64() * 1000.0;
1873
1874 results.benchmark_times.push((name.to_string(), time));
1875 results
1876 .simulation_stats
1877 .insert(name.to_string(), simulator.get_stats().clone());
1878 }
1879
1880 Ok(results)
1881 }
1882}
1883
1884#[derive(Debug, Clone, Default)]
1886pub struct TopologicalBenchmarkResults {
1887 pub benchmark_times: Vec<(String, f64)>,
1889 pub simulation_stats: HashMap<String, TopologicalSimulationStats>,
1891}
1892
1893#[cfg(test)]
1894mod tests {
1895 use super::*;
1896 use approx::assert_abs_diff_eq;
1897
1898 #[test]
1899 fn test_topological_config_default() {
1900 let config = TopologicalConfig::default();
1901 assert_eq!(config.lattice_type, LatticeType::SquareLattice);
1902 assert_eq!(config.dimensions, vec![8, 8]);
1903 assert!(config.topological_protection);
1904 }
1905
1906 #[test]
1907 fn test_anyon_type_creation() {
1908 let vacuum = AnyonType::vacuum();
1909 assert_eq!(vacuum.label, "vacuum");
1910 assert_eq!(vacuum.quantum_dimension, 1.0);
1911 assert!(vacuum.is_abelian);
1912
1913 let sigma = AnyonType::sigma();
1914 assert_eq!(sigma.label, "sigma");
1915 assert_abs_diff_eq!(sigma.quantum_dimension, 2.0_f64.sqrt(), epsilon = 1e-10);
1916 assert!(!sigma.is_abelian);
1917 }
1918
1919 #[test]
1920 fn test_topological_simulator_creation() {
1921 let config = TopologicalConfig::default();
1922 let simulator = TopologicalQuantumSimulator::new(config);
1923 assert!(simulator.is_ok());
1924 }
1925
1926 #[test]
1927 fn test_square_lattice_creation() {
1928 let dimensions = vec![3, 3];
1929 let lattice = TopologicalQuantumSimulator::create_square_lattice(&dimensions).unwrap();
1930
1931 assert_eq!(lattice.sites.len(), 9); assert_eq!(lattice.coordination_number, 4);
1933 assert!(!lattice.bonds.is_empty());
1934 assert!(!lattice.plaquettes.is_empty());
1935 }
1936
1937 #[test]
1938 fn test_anyon_placement() {
1939 let config = TopologicalConfig::default();
1940 let mut simulator = TopologicalQuantumSimulator::new(config).unwrap();
1941
1942 let vacuum = AnyonType::vacuum();
1943 let anyon_id = simulator.place_anyon(vacuum, vec![2, 3]).unwrap();
1944
1945 assert_eq!(anyon_id, 0);
1946 assert_eq!(simulator.state.anyon_config.anyons.len(), 1);
1947 assert_eq!(simulator.state.anyon_config.anyons[0].0, vec![2, 3]);
1948 }
1949
1950 #[test]
1951 fn test_braiding_operation() {
1952 let mut config = TopologicalConfig::default();
1953 config.enable_braiding = true;
1954 let mut simulator = TopologicalQuantumSimulator::new(config).unwrap();
1955
1956 let sigma = AnyonType::sigma();
1957 let anyon_a = simulator.place_anyon(sigma.clone(), vec![1, 1]).unwrap();
1958 let anyon_b = simulator.place_anyon(sigma, vec![2, 2]).unwrap();
1959
1960 let braiding_phase = simulator.braid_anyons(anyon_a, anyon_b, BraidingType::Clockwise);
1961 assert!(braiding_phase.is_ok());
1962 assert_eq!(simulator.braiding_history.len(), 1);
1963 assert_eq!(simulator.stats.braiding_operations, 1);
1964 }
1965
1966 #[test]
1967 fn test_anyon_fusion() {
1968 let config = TopologicalConfig::default();
1969 let mut simulator = TopologicalQuantumSimulator::new(config).unwrap();
1970
1971 let sigma = AnyonType::sigma();
1972 let anyon_a = simulator.place_anyon(sigma.clone(), vec![1, 1]).unwrap();
1973 let anyon_b = simulator.place_anyon(sigma, vec![1, 2]).unwrap();
1974
1975 let fusion_outcomes = simulator.fuse_anyons(anyon_a, anyon_b);
1976 assert!(fusion_outcomes.is_ok());
1977 }
1978
1979 #[test]
1980 fn test_fibonacci_anyons() {
1981 let fibonacci_model = FibonacciAnyons::new();
1982 let anyon_types = fibonacci_model.get_anyon_types();
1983
1984 assert_eq!(anyon_types.len(), 2); assert!(!fibonacci_model.is_abelian());
1986 assert_eq!(fibonacci_model.name(), "Fibonacci Anyons");
1987 }
1988
1989 #[test]
1990 fn test_ising_anyons() {
1991 let ising_model = IsingAnyons::new();
1992 let anyon_types = ising_model.get_anyon_types();
1993
1994 assert_eq!(anyon_types.len(), 3); assert!(!ising_model.is_abelian());
1996 assert_eq!(ising_model.name(), "Ising Anyons");
1997 }
1998
1999 #[test]
2000 fn test_surface_code_creation() {
2001 let dimensions = vec![4, 4];
2002 let surface_code =
2003 TopologicalQuantumSimulator::create_toric_surface_code(&dimensions).unwrap();
2004
2005 assert_eq!(surface_code.distance, 4);
2006 assert!(!surface_code.data_qubits.is_empty());
2007 assert!(!surface_code.x_stabilizers.is_empty());
2008 assert!(!surface_code.z_stabilizers.is_empty());
2009 }
2010
2011 #[test]
2012 fn test_topological_invariants() {
2013 let config = TopologicalConfig::default();
2014 let mut simulator = TopologicalQuantumSimulator::new(config).unwrap();
2015
2016 let invariants = simulator.calculate_topological_invariants();
2017 assert!(invariants.is_ok());
2018
2019 let inv = invariants.unwrap();
2020 assert!(inv.chern_number.abs() >= 0);
2021 assert!(inv.hall_conductivity.is_finite());
2022 }
2023
2024 #[test]
2025 fn test_triangular_lattice() {
2026 let dimensions = vec![3, 3];
2027 let lattice = TopologicalQuantumSimulator::create_triangular_lattice(&dimensions).unwrap();
2028
2029 assert_eq!(lattice.lattice_type, LatticeType::TriangularLattice);
2030 assert_eq!(lattice.sites.len(), 9);
2031 assert_eq!(lattice.coordination_number, 6);
2032 }
2033
2034 #[test]
2035 fn test_honeycomb_lattice() {
2036 let dimensions = vec![2, 2];
2037 let lattice = TopologicalQuantumSimulator::create_honeycomb_lattice(&dimensions).unwrap();
2038
2039 assert_eq!(lattice.lattice_type, LatticeType::HoneycombLattice);
2040 assert_eq!(lattice.coordination_number, 3);
2041 assert!(!lattice.bonds.is_empty());
2042 }
2043
2044 #[test]
2045 fn test_error_detection_and_correction() {
2046 let mut config = TopologicalConfig::default();
2047 config.topological_protection = true;
2048 let mut simulator = TopologicalQuantumSimulator::new(config).unwrap();
2049
2050 let syndrome = simulator.detect_and_correct_errors();
2051 assert!(syndrome.is_ok());
2052 }
2053
2054 #[test]
2055 fn test_predefined_configs() {
2056 let configs = vec!["toric_code", "fibonacci_system", "majorana_system"];
2057
2058 for config_type in configs {
2059 let config = TopologicalUtils::create_predefined_config(config_type, 4);
2060 let simulator = TopologicalQuantumSimulator::new(config);
2061 assert!(simulator.is_ok());
2062 }
2063 }
2064}