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 #[must_use]
137 pub fn vacuum() -> Self {
138 let mut fusion_rules = HashMap::new();
139 fusion_rules.insert("vacuum".to_string(), vec!["vacuum".to_string()]);
140
141 Self {
142 label: "vacuum".to_string(),
143 quantum_dimension: 1.0,
144 topological_charge: 0,
145 fusion_rules,
146 r_matrix: Complex64::new(1.0, 0.0),
147 is_abelian: true,
148 }
149 }
150
151 #[must_use]
153 pub fn sigma() -> Self {
154 let mut fusion_rules = HashMap::new();
155 fusion_rules.insert(
156 "sigma".to_string(),
157 vec!["vacuum".to_string(), "psi".to_string()],
158 );
159 fusion_rules.insert("psi".to_string(), vec!["sigma".to_string()]);
160 fusion_rules.insert("vacuum".to_string(), vec!["sigma".to_string()]);
161
162 Self {
163 label: "sigma".to_string(),
164 quantum_dimension: 2.0_f64.sqrt(),
165 topological_charge: 1,
166 fusion_rules,
167 r_matrix: Complex64::new(0.0, 1.0) * (PI / 8.0).exp(), is_abelian: false,
169 }
170 }
171
172 #[must_use]
174 pub fn tau() -> Self {
175 let golden_ratio = f64::midpoint(1.0, 5.0_f64.sqrt());
176 let mut fusion_rules = HashMap::new();
177 fusion_rules.insert(
178 "tau".to_string(),
179 vec!["vacuum".to_string(), "tau".to_string()],
180 );
181 fusion_rules.insert("vacuum".to_string(), vec!["tau".to_string()]);
182
183 Self {
184 label: "tau".to_string(),
185 quantum_dimension: golden_ratio,
186 topological_charge: 1,
187 fusion_rules,
188 r_matrix: Complex64::new(0.0, 1.0) * (4.0 * PI / 5.0).exp(), is_abelian: false,
190 }
191 }
192}
193
194#[derive(Debug, Clone)]
196pub struct AnyonConfiguration {
197 pub anyons: Vec<(Vec<usize>, AnyonType)>,
199 pub worldlines: Vec<AnyonWorldline>,
201 pub fusion_tree: Option<FusionTree>,
203 pub total_charge: i32,
205}
206
207#[derive(Debug, Clone)]
209pub struct AnyonWorldline {
210 pub anyon_type: AnyonType,
212 pub path: Vec<Vec<usize>>,
214 pub time_stamps: Vec<f64>,
216 pub accumulated_phase: Complex64,
218}
219
220#[derive(Debug, Clone)]
222pub struct FusionTree {
223 pub tree_structure: Vec<FusionNode>,
225 pub total_dimension: f64,
227 pub basis_labels: Vec<String>,
229}
230
231#[derive(Debug, Clone)]
233pub struct FusionNode {
234 pub inputs: Vec<AnyonType>,
236 pub output: AnyonType,
238 pub f_matrix: Array2<Complex64>,
240 pub multiplicity: usize,
242}
243
244#[derive(Debug, Clone)]
246pub struct TopologicalState {
247 pub anyon_config: AnyonConfiguration,
249 pub amplitudes: Array1<Complex64>,
251 pub degeneracy: usize,
253 pub topological_invariants: TopologicalInvariants,
255 pub energy_gap: f64,
257}
258
259#[derive(Debug, Clone, Default, Serialize, Deserialize)]
261pub struct TopologicalInvariants {
262 pub chern_number: i32,
264 pub winding_number: i32,
266 pub z2_invariant: bool,
268 pub berry_phase: f64,
270 pub hall_conductivity: f64,
272 pub topological_entanglement_entropy: f64,
274}
275
276#[derive(Debug, Clone)]
278pub struct BraidingOperation {
279 pub anyon_indices: Vec<usize>,
281 pub braiding_type: BraidingType,
283 pub braiding_matrix: Array2<Complex64>,
285 pub execution_time: f64,
287}
288
289#[derive(Debug, Clone, Copy, PartialEq, Eq)]
291pub enum BraidingType {
292 Clockwise,
294 Counterclockwise,
296 Exchange,
298 Identity,
300}
301
302#[derive(Debug, Clone)]
304pub struct SurfaceCode {
305 pub distance: usize,
307 pub data_qubits: Vec<Vec<usize>>,
309 pub x_stabilizers: Vec<Vec<usize>>,
311 pub z_stabilizers: Vec<Vec<usize>>,
313 pub logical_operators: LogicalOperators,
315 pub syndrome_detectors: Vec<SyndromeDetector>,
317}
318
319#[derive(Debug, Clone)]
321pub struct LogicalOperators {
322 pub logical_x: Vec<Array1<bool>>,
324 pub logical_z: Vec<Array1<bool>>,
326 pub num_logical_qubits: usize,
328}
329
330#[derive(Debug, Clone)]
332pub struct SyndromeDetector {
333 pub stabilizer_type: StabilizerType,
335 pub measured_qubits: Vec<usize>,
337 pub threshold: f64,
339 pub correction_map: HashMap<Vec<bool>, Vec<usize>>,
341}
342
343#[derive(Debug, Clone, Copy, PartialEq, Eq)]
345pub enum StabilizerType {
346 PauliX,
348 PauliZ,
350 XZ,
352}
353
354pub struct TopologicalQuantumSimulator {
356 config: TopologicalConfig,
358 state: TopologicalState,
360 lattice: TopologicalLattice,
362 anyon_model: Box<dyn AnyonModelImplementation + Send + Sync>,
364 error_correction: Option<SurfaceCode>,
366 braiding_history: Vec<BraidingOperation>,
368 stats: TopologicalSimulationStats,
370}
371
372#[derive(Debug, Clone)]
374pub struct TopologicalLattice {
375 pub lattice_type: LatticeType,
377 pub dimensions: Vec<usize>,
379 pub sites: Vec<Vec<f64>>,
381 pub bonds: Vec<(usize, usize)>,
383 pub plaquettes: Vec<Vec<usize>>,
385 pub coordination_number: usize,
387}
388
389#[derive(Debug, Clone, Default, Serialize, Deserialize)]
391pub struct TopologicalSimulationStats {
392 pub braiding_operations: usize,
394 pub total_simulation_time_ms: f64,
396 pub avg_braiding_time_ms: f64,
398 pub error_corrections: usize,
400 pub average_fidelity: f64,
402 pub protection_effectiveness: f64,
404}
405
406pub trait AnyonModelImplementation {
408 fn get_anyon_types(&self) -> Vec<AnyonType>;
410
411 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64;
413
414 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64>;
416
417 fn f_matrix(
419 &self,
420 a: &AnyonType,
421 b: &AnyonType,
422 c: &AnyonType,
423 d: &AnyonType,
424 ) -> Array2<Complex64>;
425
426 fn is_abelian(&self) -> bool;
428
429 fn name(&self) -> &str;
431}
432
433impl TopologicalQuantumSimulator {
434 pub fn new(config: TopologicalConfig) -> Result<Self> {
436 let lattice = Self::create_lattice(&config)?;
437 let anyon_model = Self::create_anyon_model(&config.anyon_model)?;
438 let initial_state = Self::create_initial_topological_state(&config, &lattice)?;
439
440 let error_correction = if config.topological_protection {
441 Some(Self::create_surface_code(&config, &lattice)?)
442 } else {
443 None
444 };
445
446 Ok(Self {
447 config,
448 state: initial_state,
449 lattice,
450 anyon_model,
451 error_correction,
452 braiding_history: Vec::new(),
453 stats: TopologicalSimulationStats::default(),
454 })
455 }
456
457 fn create_lattice(config: &TopologicalConfig) -> Result<TopologicalLattice> {
459 match config.lattice_type {
460 LatticeType::SquareLattice => Self::create_square_lattice(&config.dimensions),
461 LatticeType::TriangularLattice => Self::create_triangular_lattice(&config.dimensions),
462 LatticeType::HexagonalLattice => Self::create_hexagonal_lattice(&config.dimensions),
463 LatticeType::HoneycombLattice => Self::create_honeycomb_lattice(&config.dimensions),
464 LatticeType::KagomeLattice => Self::create_kagome_lattice(&config.dimensions),
465 LatticeType::CustomLattice => Self::create_custom_lattice(&config.dimensions),
466 }
467 }
468
469 fn create_square_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
471 if dimensions.len() != 2 {
472 return Err(SimulatorError::InvalidInput(
473 "Square lattice requires 2D dimensions".to_string(),
474 ));
475 }
476
477 let (width, height) = (dimensions[0], dimensions[1]);
478 let mut sites = Vec::new();
479 let mut bonds = Vec::new();
480 let mut plaquettes = Vec::new();
481
482 for y in 0..height {
484 for x in 0..width {
485 sites.push(vec![x as f64, y as f64]);
486 }
487 }
488
489 for y in 0..height {
491 for x in 0..width {
492 let site = y * width + x;
493
494 if x < width - 1 {
496 bonds.push((site, site + 1));
497 }
498
499 if y < height - 1 {
501 bonds.push((site, site + width));
502 }
503 }
504 }
505
506 for y in 0..height - 1 {
508 for x in 0..width - 1 {
509 let plaquette = vec![
510 y * width + x, y * width + x + 1, (y + 1) * width + x, (y + 1) * width + x + 1, ];
515 plaquettes.push(plaquette);
516 }
517 }
518
519 Ok(TopologicalLattice {
520 lattice_type: LatticeType::SquareLattice,
521 dimensions: dimensions.to_vec(),
522 sites,
523 bonds,
524 plaquettes,
525 coordination_number: 4,
526 })
527 }
528
529 fn create_triangular_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
531 if dimensions.len() != 2 {
532 return Err(SimulatorError::InvalidInput(
533 "Triangular lattice requires 2D dimensions".to_string(),
534 ));
535 }
536
537 let (width, height) = (dimensions[0], dimensions[1]);
538 let mut sites = Vec::new();
539 let mut bonds = Vec::new();
540 let mut plaquettes = Vec::new();
541
542 for y in 0..height {
544 for x in 0..width {
545 let x_pos = x as f64 + if y % 2 == 1 { 0.5 } else { 0.0 };
546 let y_pos = y as f64 * 3.0_f64.sqrt() / 2.0;
547 sites.push(vec![x_pos, y_pos]);
548 }
549 }
550
551 for y in 0..height {
553 for x in 0..width {
554 let site = y * width + x;
555
556 if x < width - 1 {
558 bonds.push((site, site + 1));
559 }
560
561 if y < height - 1 {
563 bonds.push((site, site + width));
564
565 if y % 2 == 0 && x < width - 1 {
566 bonds.push((site, site + width + 1));
567 } else if y % 2 == 1 && x > 0 {
568 bonds.push((site, site + width - 1));
569 }
570 }
571 }
572 }
573
574 for y in 0..height - 1 {
576 for x in 0..width - 1 {
577 if y % 2 == 0 {
578 let plaquette = vec![y * width + x, y * width + x + 1, (y + 1) * width + x];
580 plaquettes.push(plaquette);
581 }
582 }
583 }
584
585 Ok(TopologicalLattice {
586 lattice_type: LatticeType::TriangularLattice,
587 dimensions: dimensions.to_vec(),
588 sites,
589 bonds,
590 plaquettes,
591 coordination_number: 6,
592 })
593 }
594
595 fn create_hexagonal_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
597 if dimensions.len() != 2 {
598 return Err(SimulatorError::InvalidInput(
599 "Hexagonal lattice requires 2D dimensions".to_string(),
600 ));
601 }
602
603 let (width, height) = (dimensions[0], dimensions[1]);
604 let mut sites = Vec::new();
605 let mut bonds = Vec::new();
606 let mut plaquettes = Vec::new();
607
608 for y in 0..height {
610 for x in 0..width {
611 let x_pos = x as f64 * 1.5;
612 let y_pos = (y as f64).mul_add(
613 3.0_f64.sqrt(),
614 if x % 2 == 1 {
615 3.0_f64.sqrt() / 2.0
616 } else {
617 0.0
618 },
619 );
620 sites.push(vec![x_pos, y_pos]);
621 }
622 }
623
624 for y in 0..height {
626 for x in 0..width {
627 let site = y * width + x;
628
629 if x < width - 1 {
631 bonds.push((site, site + 1));
632 }
633
634 if y < height - 1 {
636 bonds.push((site, site + width));
637 }
638
639 if y > 0 {
640 bonds.push((site, site - width));
641 }
642 }
643 }
644
645 for y in 1..height - 1 {
647 for x in 1..width - 1 {
648 let plaquette = vec![
649 (y - 1) * width + x,
650 (y - 1) * width + x + 1,
651 y * width + x + 1,
652 (y + 1) * width + x + 1,
653 (y + 1) * width + x,
654 y * width + x,
655 ];
656 plaquettes.push(plaquette);
657 }
658 }
659
660 Ok(TopologicalLattice {
661 lattice_type: LatticeType::HexagonalLattice,
662 dimensions: dimensions.to_vec(),
663 sites,
664 bonds,
665 plaquettes,
666 coordination_number: 3,
667 })
668 }
669
670 fn create_honeycomb_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
672 if dimensions.len() != 2 {
673 return Err(SimulatorError::InvalidInput(
674 "Honeycomb lattice requires 2D dimensions".to_string(),
675 ));
676 }
677
678 let (width, height) = (dimensions[0], dimensions[1]);
679 let mut sites = Vec::new();
680 let mut bonds = Vec::new();
681 let mut plaquettes = Vec::new();
682
683 for y in 0..height {
685 for x in 0..width {
686 let x_a = x as f64 * 3.0 / 2.0;
688 let y_a = y as f64 * 3.0_f64.sqrt();
689 sites.push(vec![x_a, y_a]);
690
691 let x_b = x as f64 * 3.0 / 2.0 + 1.0;
693 let y_b = (y as f64).mul_add(3.0_f64.sqrt(), 3.0_f64.sqrt() / 3.0);
694 sites.push(vec![x_b, y_b]);
695 }
696 }
697
698 for y in 0..height {
700 for x in 0..width {
701 let a_site = 2 * (y * width + x);
702 let b_site = a_site + 1;
703
704 bonds.push((a_site, b_site));
706
707 if x < width - 1 {
709 bonds.push((b_site, a_site + 2));
710 }
711
712 if y < height - 1 {
713 bonds.push((b_site, a_site + 2 * width));
714 }
715 }
716 }
717
718 for y in 0..height - 1 {
720 for x in 0..width - 1 {
721 let plaquette = vec![
722 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, ];
729 plaquettes.push(plaquette);
730 }
731 }
732
733 Ok(TopologicalLattice {
734 lattice_type: LatticeType::HoneycombLattice,
735 dimensions: dimensions.to_vec(),
736 sites,
737 bonds,
738 plaquettes,
739 coordination_number: 3,
740 })
741 }
742
743 fn create_kagome_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
745 if dimensions.len() != 2 {
746 return Err(SimulatorError::InvalidInput(
747 "Kagome lattice requires 2D dimensions".to_string(),
748 ));
749 }
750
751 let (width, height) = (dimensions[0], dimensions[1]);
752 let mut sites = Vec::new();
753 let mut bonds = Vec::new();
754 let mut plaquettes = Vec::new();
755
756 for y in 0..height {
758 for x in 0..width {
759 let base_x = x as f64 * 2.0;
760 let base_y = y as f64 * 3.0_f64.sqrt();
761
762 sites.push(vec![base_x, base_y]);
764 sites.push(vec![base_x + 1.0, base_y]);
765 sites.push(vec![base_x + 0.5, base_y + 3.0_f64.sqrt() / 2.0]);
766 }
767 }
768
769 for y in 0..height {
771 for x in 0..width {
772 let base_site = 3 * (y * width + x);
773
774 bonds.push((base_site, base_site + 1));
776 bonds.push((base_site + 1, base_site + 2));
777 bonds.push((base_site + 2, base_site));
778
779 if x < width - 1 {
781 bonds.push((base_site + 1, base_site + 3));
782 }
783
784 if y < height - 1 {
785 bonds.push((base_site + 2, base_site + 3 * width));
786 }
787 }
788 }
789
790 for y in 0..height {
792 for x in 0..width {
793 let base_site = 3 * (y * width + x);
794
795 let triangle = vec![base_site, base_site + 1, base_site + 2];
797 plaquettes.push(triangle);
798
799 if x < width - 1 && y < height - 1 {
801 let hexagon = vec![
802 base_site + 1,
803 base_site + 3,
804 base_site + 3 + 2,
805 base_site + 3 * width + 2,
806 base_site + 3 * width,
807 base_site + 2,
808 ];
809 plaquettes.push(hexagon);
810 }
811 }
812 }
813
814 Ok(TopologicalLattice {
815 lattice_type: LatticeType::KagomeLattice,
816 dimensions: dimensions.to_vec(),
817 sites,
818 bonds,
819 plaquettes,
820 coordination_number: 4,
821 })
822 }
823
824 fn create_custom_lattice(dimensions: &[usize]) -> Result<TopologicalLattice> {
826 Self::create_square_lattice(dimensions)
828 }
829
830 fn create_anyon_model(
832 model: &AnyonModel,
833 ) -> Result<Box<dyn AnyonModelImplementation + Send + Sync>> {
834 match model {
835 AnyonModel::Abelian => Ok(Box::new(AbelianAnyons::new())),
836 AnyonModel::NonAbelian => Ok(Box::new(NonAbelianAnyons::new())),
837 AnyonModel::Fibonacci => Ok(Box::new(FibonacciAnyons::new())),
838 AnyonModel::Ising => Ok(Box::new(IsingAnyons::new())),
839 AnyonModel::Parafermion => Ok(Box::new(ParafermionAnyons::new())),
840 AnyonModel::ChernSimons(k) => Ok(Box::new(ChernSimonsAnyons::new(*k))),
841 }
842 }
843
844 fn create_initial_topological_state(
846 config: &TopologicalConfig,
847 lattice: &TopologicalLattice,
848 ) -> Result<TopologicalState> {
849 let anyon_config = AnyonConfiguration {
851 anyons: Vec::new(),
852 worldlines: Vec::new(),
853 fusion_tree: None,
854 total_charge: 0,
855 };
856
857 let degeneracy = Self::calculate_ground_state_degeneracy(config, lattice);
859 let amplitudes = Array1::zeros(degeneracy);
860
861 let topological_invariants = TopologicalInvariants::default();
862
863 Ok(TopologicalState {
864 anyon_config,
865 amplitudes,
866 degeneracy,
867 topological_invariants,
868 energy_gap: config.magnetic_field, })
870 }
871
872 fn calculate_ground_state_degeneracy(
874 config: &TopologicalConfig,
875 lattice: &TopologicalLattice,
876 ) -> usize {
877 match config.anyon_model {
878 AnyonModel::Abelian => {
879 let genus = Self::calculate_genus(lattice);
881 2_usize.pow(genus as u32)
882 }
883 AnyonModel::Fibonacci => {
884 let num_qubits = lattice.sites.len() / 2;
886 let golden_ratio = f64::midpoint(1.0, 5.0_f64.sqrt());
887 (golden_ratio.powi(num_qubits as i32) / 5.0_f64.sqrt()).round() as usize
888 }
889 AnyonModel::Ising => {
890 let num_majoranas = lattice.sites.len();
892 2_usize.pow((num_majoranas / 2) as u32)
893 }
894 _ => 1, }
896 }
897
898 fn calculate_genus(lattice: &TopologicalLattice) -> usize {
900 let vertices = lattice.sites.len();
902 let edges = lattice.bonds.len();
903 let faces = lattice.plaquettes.len() + 1; let euler_characteristic = vertices as i32 - edges as i32 + faces as i32;
906 let genus = (2 - euler_characteristic) / 2;
907 genus.max(0) as usize
908 }
909
910 fn create_surface_code(
912 config: &TopologicalConfig,
913 lattice: &TopologicalLattice,
914 ) -> Result<SurfaceCode> {
915 match config.error_correction_code {
916 TopologicalErrorCode::SurfaceCode => {
917 Self::create_toric_surface_code(&config.dimensions)
918 }
919 TopologicalErrorCode::ColorCode => Self::create_color_code(&config.dimensions),
920 _ => {
921 Self::create_toric_surface_code(&config.dimensions)
923 }
924 }
925 }
926
927 fn create_toric_surface_code(dimensions: &[usize]) -> Result<SurfaceCode> {
929 if dimensions.len() != 2 {
930 return Err(SimulatorError::InvalidInput(
931 "Surface code requires 2D lattice".to_string(),
932 ));
933 }
934
935 let distance = dimensions[0].min(dimensions[1]);
936 let mut data_qubits = Vec::new();
937 let mut x_stabilizers = Vec::new();
938 let mut z_stabilizers = Vec::new();
939
940 for y in 0..distance {
942 for x in 0..distance {
943 data_qubits.push(vec![x, y, 0]); data_qubits.push(vec![x, y, 1]); }
948 }
949
950 for y in 0..distance {
952 for x in 0..distance {
953 let stabilizer_pos = vec![x, y];
954 x_stabilizers.push(stabilizer_pos);
955 }
956 }
957
958 for y in 0..distance - 1 {
960 for x in 0..distance - 1 {
961 let stabilizer_pos = vec![x, y];
962 z_stabilizers.push(stabilizer_pos);
963 }
964 }
965
966 let logical_x = vec![Array1::from_elem(distance, true)];
968 let logical_z = vec![Array1::from_elem(distance, true)];
969
970 let logical_operators = LogicalOperators {
971 logical_x,
972 logical_z,
973 num_logical_qubits: 1,
974 };
975
976 let mut syndrome_detectors = Vec::new();
978
979 for stabilizer in &x_stabilizers {
980 let detector = SyndromeDetector {
981 stabilizer_type: StabilizerType::PauliX,
982 measured_qubits: vec![0, 1, 2, 3], threshold: 0.5,
984 correction_map: HashMap::new(),
985 };
986 syndrome_detectors.push(detector);
987 }
988
989 for stabilizer in &z_stabilizers {
990 let detector = SyndromeDetector {
991 stabilizer_type: StabilizerType::PauliZ,
992 measured_qubits: vec![0, 1, 2, 3], threshold: 0.5,
994 correction_map: HashMap::new(),
995 };
996 syndrome_detectors.push(detector);
997 }
998
999 Ok(SurfaceCode {
1000 distance,
1001 data_qubits,
1002 x_stabilizers,
1003 z_stabilizers,
1004 logical_operators,
1005 syndrome_detectors,
1006 })
1007 }
1008
1009 fn create_color_code(dimensions: &[usize]) -> Result<SurfaceCode> {
1011 Self::create_toric_surface_code(dimensions)
1013 }
1014
1015 pub fn place_anyon(&mut self, anyon_type: AnyonType, position: Vec<usize>) -> Result<usize> {
1017 if position.len() != self.config.dimensions.len() {
1019 return Err(SimulatorError::InvalidInput(
1020 "Position dimension mismatch".to_string(),
1021 ));
1022 }
1023
1024 for (i, &pos) in position.iter().enumerate() {
1025 if pos >= self.config.dimensions[i] {
1026 return Err(SimulatorError::InvalidInput(
1027 "Position out of bounds".to_string(),
1028 ));
1029 }
1030 }
1031
1032 let anyon_id = self.state.anyon_config.anyons.len();
1034 self.state
1035 .anyon_config
1036 .anyons
1037 .push((position.clone(), anyon_type.clone()));
1038
1039 self.state.anyon_config.total_charge += anyon_type.topological_charge;
1041
1042 let worldline = AnyonWorldline {
1044 anyon_type,
1045 path: vec![position],
1046 time_stamps: vec![0.0],
1047 accumulated_phase: Complex64::new(1.0, 0.0),
1048 };
1049 self.state.anyon_config.worldlines.push(worldline);
1050
1051 Ok(anyon_id)
1052 }
1053
1054 pub fn braid_anyons(
1056 &mut self,
1057 anyon_a: usize,
1058 anyon_b: usize,
1059 braiding_type: BraidingType,
1060 ) -> Result<Complex64> {
1061 let start_time = std::time::Instant::now();
1062
1063 if anyon_a >= self.state.anyon_config.anyons.len()
1064 || anyon_b >= self.state.anyon_config.anyons.len()
1065 {
1066 return Err(SimulatorError::InvalidInput(
1067 "Invalid anyon indices".to_string(),
1068 ));
1069 }
1070
1071 let (_, ref type_a) = &self.state.anyon_config.anyons[anyon_a];
1072 let (_, ref type_b) = &self.state.anyon_config.anyons[anyon_b];
1073
1074 let braiding_matrix = self.anyon_model.braiding_matrix(type_a, type_b);
1076
1077 let braiding_phase = match braiding_type {
1079 BraidingType::Clockwise => type_a.r_matrix * type_b.r_matrix.conj(),
1080 BraidingType::Counterclockwise => type_a.r_matrix.conj() * type_b.r_matrix,
1081 BraidingType::Exchange => type_a.r_matrix * type_b.r_matrix,
1082 BraidingType::Identity => Complex64::new(1.0, 0.0),
1083 };
1084
1085 let current_time = self.braiding_history.len() as f64;
1087 if anyon_a < self.state.anyon_config.worldlines.len() {
1088 self.state.anyon_config.worldlines[anyon_a]
1089 .time_stamps
1090 .push(current_time);
1091 self.state.anyon_config.worldlines[anyon_a].accumulated_phase *= braiding_phase;
1092 }
1093 if anyon_b < self.state.anyon_config.worldlines.len() {
1094 self.state.anyon_config.worldlines[anyon_b]
1095 .time_stamps
1096 .push(current_time);
1097 self.state.anyon_config.worldlines[anyon_b].accumulated_phase *= braiding_phase.conj();
1098 }
1099
1100 for amplitude in &mut self.state.amplitudes {
1102 *amplitude *= braiding_phase;
1103 }
1104
1105 let execution_time = start_time.elapsed().as_secs_f64() * 1000.0;
1106
1107 let braiding_op = BraidingOperation {
1109 anyon_indices: vec![anyon_a, anyon_b],
1110 braiding_type,
1111 braiding_matrix,
1112 execution_time,
1113 };
1114 self.braiding_history.push(braiding_op);
1115
1116 self.stats.braiding_operations += 1;
1118 self.stats.avg_braiding_time_ms = self
1119 .stats
1120 .avg_braiding_time_ms
1121 .mul_add((self.stats.braiding_operations - 1) as f64, execution_time)
1122 / self.stats.braiding_operations as f64;
1123
1124 Ok(braiding_phase)
1125 }
1126
1127 pub fn move_anyon(&mut self, anyon_id: usize, new_position: Vec<usize>) -> Result<()> {
1129 if anyon_id >= self.state.anyon_config.anyons.len() {
1130 return Err(SimulatorError::InvalidInput("Invalid anyon ID".to_string()));
1131 }
1132
1133 for (i, &pos) in new_position.iter().enumerate() {
1135 if pos >= self.config.dimensions[i] {
1136 return Err(SimulatorError::InvalidInput(
1137 "New position out of bounds".to_string(),
1138 ));
1139 }
1140 }
1141
1142 self.state.anyon_config.anyons[anyon_id].0 = new_position.clone();
1144
1145 if anyon_id < self.state.anyon_config.worldlines.len() {
1147 self.state.anyon_config.worldlines[anyon_id]
1148 .path
1149 .push(new_position);
1150 let current_time = self.braiding_history.len() as f64;
1151 self.state.anyon_config.worldlines[anyon_id]
1152 .time_stamps
1153 .push(current_time);
1154 }
1155
1156 Ok(())
1157 }
1158
1159 pub fn fuse_anyons(&mut self, anyon_a: usize, anyon_b: usize) -> Result<Vec<AnyonType>> {
1161 if anyon_a >= self.state.anyon_config.anyons.len()
1162 || anyon_b >= self.state.anyon_config.anyons.len()
1163 {
1164 return Err(SimulatorError::InvalidInput(
1165 "Invalid anyon indices".to_string(),
1166 ));
1167 }
1168
1169 let type_a = &self.state.anyon_config.anyons[anyon_a].1;
1170 let type_b = &self.state.anyon_config.anyons[anyon_b].1;
1171
1172 let fusion_outcomes = if let Some(outcomes) = type_a.fusion_rules.get(&type_b.label) {
1174 outcomes.clone()
1175 } else {
1176 vec!["vacuum".to_string()] };
1178
1179 let outcome_types: Vec<AnyonType> = fusion_outcomes
1181 .iter()
1182 .map(|label| self.create_anyon_from_label(label))
1183 .collect::<Result<Vec<_>>>()?;
1184
1185 let mut indices_to_remove = vec![anyon_a, anyon_b];
1189 indices_to_remove.sort_by(|a, b| b.cmp(a)); for &index in &indices_to_remove {
1192 if index < self.state.anyon_config.anyons.len() {
1193 self.state.anyon_config.anyons.remove(index);
1194 }
1195 if index < self.state.anyon_config.worldlines.len() {
1196 self.state.anyon_config.worldlines.remove(index);
1197 }
1198 }
1199
1200 Ok(outcome_types)
1201 }
1202
1203 fn create_anyon_from_label(&self, label: &str) -> Result<AnyonType> {
1205 match label {
1206 "vacuum" => Ok(AnyonType::vacuum()),
1207 "sigma" => Ok(AnyonType::sigma()),
1208 "tau" => Ok(AnyonType::tau()),
1209 _ => {
1210 Ok(AnyonType {
1212 label: label.to_string(),
1213 quantum_dimension: 1.0,
1214 topological_charge: 0,
1215 fusion_rules: HashMap::new(),
1216 r_matrix: Complex64::new(1.0, 0.0),
1217 is_abelian: true,
1218 })
1219 }
1220 }
1221 }
1222
1223 pub fn calculate_topological_invariants(&mut self) -> Result<TopologicalInvariants> {
1225 let mut invariants = TopologicalInvariants::default();
1226
1227 invariants.chern_number = self.calculate_chern_number()?;
1229
1230 invariants.winding_number = self.calculate_winding_number()?;
1232
1233 invariants.z2_invariant = self.calculate_z2_invariant()?;
1235
1236 invariants.berry_phase = self.calculate_berry_phase()?;
1238
1239 invariants.hall_conductivity = f64::from(invariants.chern_number) * 2.0 * PI / 137.0; invariants.topological_entanglement_entropy =
1244 self.calculate_topological_entanglement_entropy()?;
1245
1246 self.state.topological_invariants = invariants.clone();
1247 Ok(invariants)
1248 }
1249
1250 fn calculate_chern_number(&self) -> Result<i32> {
1252 let magnetic_flux = self.config.magnetic_field * self.lattice.sites.len() as f64;
1255 let flux_quanta = (magnetic_flux / (2.0 * PI)).round() as i32;
1256 Ok(flux_quanta)
1257 }
1258
1259 fn calculate_winding_number(&self) -> Result<i32> {
1261 match self.config.dimensions.len() {
1263 1 => Ok(1), _ => Ok(0), }
1266 }
1267
1268 fn calculate_z2_invariant(&self) -> Result<bool> {
1270 let time_reversal_broken = self.config.magnetic_field.abs() > 1e-10;
1272 Ok(!time_reversal_broken)
1273 }
1274
1275 fn calculate_berry_phase(&self) -> Result<f64> {
1277 let total_braiding_phase: Complex64 = self
1279 .state
1280 .anyon_config
1281 .worldlines
1282 .iter()
1283 .map(|wl| wl.accumulated_phase)
1284 .fold(Complex64::new(1.0, 0.0), |acc, phase| acc * phase);
1285
1286 Ok(total_braiding_phase.arg())
1287 }
1288
1289 fn calculate_topological_entanglement_entropy(&self) -> Result<f64> {
1291 let total_quantum_dimension: f64 = self
1293 .anyon_model
1294 .get_anyon_types()
1295 .iter()
1296 .map(|anyon| anyon.quantum_dimension * anyon.quantum_dimension)
1297 .sum();
1298
1299 let gamma = match self.config.anyon_model {
1300 AnyonModel::Abelian => 0.0,
1301 AnyonModel::Fibonacci => 0.5 * (5.0_f64.sqrt() - 1.0) / 2.0, AnyonModel::Ising => 0.5,
1303 _ => 0.5, };
1305
1306 Ok(-gamma * total_quantum_dimension.ln())
1307 }
1308
1309 pub fn detect_and_correct_errors(&mut self) -> Result<Vec<bool>> {
1311 if let Some(ref surface_code) = self.error_correction {
1312 let mut syndrome = Vec::new();
1313
1314 for detector in &surface_code.syndrome_detectors {
1316 let measurement = self.measure_stabilizer(detector)?;
1317 syndrome.push(measurement);
1318 }
1319
1320 let corrections = self.decode_syndrome(&syndrome)?;
1322 self.apply_corrections(&corrections)?;
1323
1324 self.stats.error_corrections += 1;
1325 Ok(syndrome)
1326 } else {
1327 Ok(Vec::new())
1328 }
1329 }
1330
1331 fn measure_stabilizer(&self, detector: &SyndromeDetector) -> Result<bool> {
1333 let probability = match detector.stabilizer_type {
1336 StabilizerType::PauliX => 0.1, StabilizerType::PauliZ => 0.1,
1338 StabilizerType::XZ => 0.05,
1339 };
1340
1341 Ok(fastrand::f64() < probability)
1342 }
1343
1344 fn decode_syndrome(&self, syndrome: &[bool]) -> Result<Vec<usize>> {
1346 let mut corrections = Vec::new();
1349
1350 for (i, &error) in syndrome.iter().enumerate() {
1351 if error {
1352 corrections.push(i);
1353 }
1354 }
1355
1356 Ok(corrections)
1357 }
1358
1359 fn apply_corrections(&mut self, corrections: &[usize]) -> Result<()> {
1361 for &correction_site in corrections {
1363 if correction_site < self.state.amplitudes.len() {
1364 self.state.amplitudes[correction_site] *= Complex64::new(-1.0, 0.0);
1367 }
1368 }
1369
1370 Ok(())
1371 }
1372
1373 #[must_use]
1375 pub const fn get_state(&self) -> &TopologicalState {
1376 &self.state
1377 }
1378
1379 #[must_use]
1381 pub fn get_braiding_history(&self) -> &[BraidingOperation] {
1382 &self.braiding_history
1383 }
1384
1385 #[must_use]
1387 pub const fn get_stats(&self) -> &TopologicalSimulationStats {
1388 &self.stats
1389 }
1390
1391 pub fn reset(&mut self) -> Result<()> {
1393 self.state = Self::create_initial_topological_state(&self.config, &self.lattice)?;
1394 self.braiding_history.clear();
1395 self.stats = TopologicalSimulationStats::default();
1396 Ok(())
1397 }
1398}
1399
1400pub struct AbelianAnyons {
1404 anyon_types: Vec<AnyonType>,
1405}
1406
1407impl Default for AbelianAnyons {
1408 fn default() -> Self {
1409 Self::new()
1410 }
1411}
1412
1413impl AbelianAnyons {
1414 #[must_use]
1415 pub fn new() -> Self {
1416 let anyon_types = vec![AnyonType::vacuum()];
1417 Self { anyon_types }
1418 }
1419}
1420
1421impl AnyonModelImplementation for AbelianAnyons {
1422 fn get_anyon_types(&self) -> Vec<AnyonType> {
1423 self.anyon_types.clone()
1424 }
1425
1426 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1427 if a.topological_charge + b.topological_charge == c.topological_charge {
1429 Complex64::new(1.0, 0.0)
1430 } else {
1431 Complex64::new(0.0, 0.0)
1432 }
1433 }
1434
1435 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1436 let phase = a.r_matrix * b.r_matrix.conj();
1437 Array2::from_shape_vec((1, 1), vec![phase])
1438 .expect("AbelianAnyons::braiding_matrix: 1x1 matrix shape is always valid")
1439 }
1440
1441 fn f_matrix(
1442 &self,
1443 _a: &AnyonType,
1444 _b: &AnyonType,
1445 _c: &AnyonType,
1446 _d: &AnyonType,
1447 ) -> Array2<Complex64> {
1448 Array2::eye(1)
1450 }
1451
1452 fn is_abelian(&self) -> bool {
1453 true
1454 }
1455
1456 fn name(&self) -> &'static str {
1457 "Abelian Anyons"
1458 }
1459}
1460
1461pub struct NonAbelianAnyons {
1463 anyon_types: Vec<AnyonType>,
1464}
1465
1466impl Default for NonAbelianAnyons {
1467 fn default() -> Self {
1468 Self::new()
1469 }
1470}
1471
1472impl NonAbelianAnyons {
1473 #[must_use]
1474 pub fn new() -> Self {
1475 let anyon_types = vec![AnyonType::vacuum(), AnyonType::sigma()];
1476 Self { anyon_types }
1477 }
1478}
1479
1480impl AnyonModelImplementation for NonAbelianAnyons {
1481 fn get_anyon_types(&self) -> Vec<AnyonType> {
1482 self.anyon_types.clone()
1483 }
1484
1485 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1486 if let Some(outcomes) = a.fusion_rules.get(&b.label) {
1488 if outcomes.contains(&c.label) {
1489 Complex64::new(1.0, 0.0)
1490 } else {
1491 Complex64::new(0.0, 0.0)
1492 }
1493 } else {
1494 Complex64::new(0.0, 0.0)
1495 }
1496 }
1497
1498 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1499 let dim = (a.quantum_dimension * b.quantum_dimension) as usize;
1500 let mut matrix = Array2::eye(dim);
1501
1502 if !a.is_abelian || !b.is_abelian {
1504 let phase = a.r_matrix * b.r_matrix.conj();
1505 matrix[[0, 0]] = phase;
1506 if dim > 1 {
1507 matrix[[1, 1]] = phase.conj();
1508 }
1509 }
1510
1511 matrix
1512 }
1513
1514 fn f_matrix(
1515 &self,
1516 _a: &AnyonType,
1517 _b: &AnyonType,
1518 _c: &AnyonType,
1519 _d: &AnyonType,
1520 ) -> Array2<Complex64> {
1521 Array2::eye(2)
1523 }
1524
1525 fn is_abelian(&self) -> bool {
1526 false
1527 }
1528
1529 fn name(&self) -> &'static str {
1530 "Non-Abelian Anyons"
1531 }
1532}
1533
1534pub struct FibonacciAnyons {
1536 anyon_types: Vec<AnyonType>,
1537}
1538
1539impl Default for FibonacciAnyons {
1540 fn default() -> Self {
1541 Self::new()
1542 }
1543}
1544
1545impl FibonacciAnyons {
1546 #[must_use]
1547 pub fn new() -> Self {
1548 let anyon_types = vec![AnyonType::vacuum(), AnyonType::tau()];
1549 Self { anyon_types }
1550 }
1551}
1552
1553impl AnyonModelImplementation for FibonacciAnyons {
1554 fn get_anyon_types(&self) -> Vec<AnyonType> {
1555 self.anyon_types.clone()
1556 }
1557
1558 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1559 match (a.label.as_str(), b.label.as_str(), c.label.as_str()) {
1561 ("tau", "tau", "vacuum" | "tau") => Complex64::new(1.0, 0.0),
1562 ("vacuum", _, label) | (_, "vacuum", label) if label == a.label || label == b.label => {
1563 Complex64::new(1.0, 0.0)
1564 }
1565 _ => Complex64::new(0.0, 0.0),
1566 }
1567 }
1568
1569 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1570 if a.label == "tau" && b.label == "tau" {
1571 let phi = f64::midpoint(1.0, 5.0_f64.sqrt()); let phase = Complex64::new(0.0, 1.0) * (4.0 * PI / 5.0).exp();
1573
1574 Array2::from_shape_vec(
1575 (2, 2),
1576 vec![
1577 phase,
1578 Complex64::new(0.0, 0.0),
1579 Complex64::new(0.0, 0.0),
1580 phase * Complex64::new(-1.0 / phi, 0.0),
1581 ],
1582 )
1583 .expect("FibonacciAnyons::braiding_matrix: 2x2 matrix shape is always valid")
1584 } else {
1585 Array2::eye(1)
1586 }
1587 }
1588
1589 fn f_matrix(
1590 &self,
1591 _a: &AnyonType,
1592 _b: &AnyonType,
1593 _c: &AnyonType,
1594 _d: &AnyonType,
1595 ) -> Array2<Complex64> {
1596 let phi = f64::midpoint(1.0, 5.0_f64.sqrt());
1598 let inv_phi = 1.0 / phi;
1599
1600 Array2::from_shape_vec(
1601 (2, 2),
1602 vec![
1603 Complex64::new(inv_phi, 0.0),
1604 Complex64::new(inv_phi.sqrt(), 0.0),
1605 Complex64::new(inv_phi.sqrt(), 0.0),
1606 Complex64::new(-inv_phi, 0.0),
1607 ],
1608 )
1609 .expect("FibonacciAnyons::f_matrix: 2x2 matrix shape is always valid")
1610 }
1611
1612 fn is_abelian(&self) -> bool {
1613 false
1614 }
1615
1616 fn name(&self) -> &'static str {
1617 "Fibonacci Anyons"
1618 }
1619}
1620
1621pub struct IsingAnyons {
1623 anyon_types: Vec<AnyonType>,
1624}
1625
1626impl Default for IsingAnyons {
1627 fn default() -> Self {
1628 Self::new()
1629 }
1630}
1631
1632impl IsingAnyons {
1633 #[must_use]
1634 pub fn new() -> Self {
1635 let mut psi = AnyonType {
1636 label: "psi".to_string(),
1637 quantum_dimension: 1.0,
1638 topological_charge: 1,
1639 fusion_rules: HashMap::new(),
1640 r_matrix: Complex64::new(-1.0, 0.0),
1641 is_abelian: true,
1642 };
1643 psi.fusion_rules
1644 .insert("psi".to_string(), vec!["vacuum".to_string()]);
1645
1646 let anyon_types = vec![AnyonType::vacuum(), AnyonType::sigma(), psi];
1647 Self { anyon_types }
1648 }
1649}
1650
1651impl AnyonModelImplementation for IsingAnyons {
1652 fn get_anyon_types(&self) -> Vec<AnyonType> {
1653 self.anyon_types.clone()
1654 }
1655
1656 fn fusion_coefficients(&self, a: &AnyonType, b: &AnyonType, c: &AnyonType) -> Complex64 {
1657 match (a.label.as_str(), b.label.as_str(), c.label.as_str()) {
1659 ("sigma", "sigma", "vacuum" | "psi") => Complex64::new(1.0, 0.0),
1660 ("psi", "psi", "vacuum") => Complex64::new(1.0, 0.0),
1661 ("sigma", "psi", "sigma") | ("psi", "sigma", "sigma") => Complex64::new(1.0, 0.0),
1662 ("vacuum", _, label) | (_, "vacuum", label) if label == a.label || label == b.label => {
1663 Complex64::new(1.0, 0.0)
1664 }
1665 _ => Complex64::new(0.0, 0.0),
1666 }
1667 }
1668
1669 fn braiding_matrix(&self, a: &AnyonType, b: &AnyonType) -> Array2<Complex64> {
1670 let phase = a.r_matrix * b.r_matrix.conj();
1671
1672 if a.label == "sigma" && b.label == "sigma" {
1673 Array2::from_shape_vec(
1675 (2, 2),
1676 vec![
1677 Complex64::new(0.0, 1.0) * (PI / 8.0).exp(),
1678 Complex64::new(0.0, 0.0),
1679 Complex64::new(0.0, 0.0),
1680 Complex64::new(0.0, -1.0) * (PI / 8.0).exp(),
1681 ],
1682 )
1683 .expect("IsingAnyons::braiding_matrix: 2x2 matrix shape is always valid")
1684 } else {
1685 Array2::from_shape_vec((1, 1), vec![phase])
1686 .expect("IsingAnyons::braiding_matrix: 1x1 matrix shape is always valid")
1687 }
1688 }
1689
1690 fn f_matrix(
1691 &self,
1692 _a: &AnyonType,
1693 _b: &AnyonType,
1694 _c: &AnyonType,
1695 _d: &AnyonType,
1696 ) -> Array2<Complex64> {
1697 let sqrt_2_inv = 1.0 / 2.0_f64.sqrt();
1699 Array2::from_shape_vec(
1700 (2, 2),
1701 vec![
1702 Complex64::new(sqrt_2_inv, 0.0),
1703 Complex64::new(sqrt_2_inv, 0.0),
1704 Complex64::new(sqrt_2_inv, 0.0),
1705 Complex64::new(-sqrt_2_inv, 0.0),
1706 ],
1707 )
1708 .expect("IsingAnyons::f_matrix: 2x2 matrix shape is always valid")
1709 }
1710
1711 fn is_abelian(&self) -> bool {
1712 false
1713 }
1714
1715 fn name(&self) -> &'static str {
1716 "Ising Anyons"
1717 }
1718}
1719
1720pub struct ParafermionAnyons {
1722 anyon_types: Vec<AnyonType>,
1723}
1724
1725impl Default for ParafermionAnyons {
1726 fn default() -> Self {
1727 Self::new()
1728 }
1729}
1730
1731impl ParafermionAnyons {
1732 #[must_use]
1733 pub fn new() -> Self {
1734 Self {
1735 anyon_types: vec![AnyonType::vacuum()],
1736 }
1737 }
1738}
1739
1740impl AnyonModelImplementation for ParafermionAnyons {
1741 fn get_anyon_types(&self) -> Vec<AnyonType> {
1742 self.anyon_types.clone()
1743 }
1744 fn fusion_coefficients(&self, _a: &AnyonType, _b: &AnyonType, _c: &AnyonType) -> Complex64 {
1745 Complex64::new(1.0, 0.0)
1746 }
1747 fn braiding_matrix(&self, _a: &AnyonType, _b: &AnyonType) -> Array2<Complex64> {
1748 Array2::eye(1)
1749 }
1750 fn f_matrix(
1751 &self,
1752 _a: &AnyonType,
1753 _b: &AnyonType,
1754 _c: &AnyonType,
1755 _d: &AnyonType,
1756 ) -> Array2<Complex64> {
1757 Array2::eye(1)
1758 }
1759 fn is_abelian(&self) -> bool {
1760 false
1761 }
1762 fn name(&self) -> &'static str {
1763 "Parafermion Anyons"
1764 }
1765}
1766
1767pub struct ChernSimonsAnyons {
1768 level: u32,
1769 anyon_types: Vec<AnyonType>,
1770}
1771
1772impl ChernSimonsAnyons {
1773 #[must_use]
1774 pub fn new(level: u32) -> Self {
1775 Self {
1776 level,
1777 anyon_types: vec![AnyonType::vacuum()],
1778 }
1779 }
1780}
1781
1782impl AnyonModelImplementation for ChernSimonsAnyons {
1783 fn get_anyon_types(&self) -> Vec<AnyonType> {
1784 self.anyon_types.clone()
1785 }
1786 fn fusion_coefficients(&self, _a: &AnyonType, _b: &AnyonType, _c: &AnyonType) -> Complex64 {
1787 Complex64::new(1.0, 0.0)
1788 }
1789 fn braiding_matrix(&self, _a: &AnyonType, _b: &AnyonType) -> Array2<Complex64> {
1790 Array2::eye(1)
1791 }
1792 fn f_matrix(
1793 &self,
1794 _a: &AnyonType,
1795 _b: &AnyonType,
1796 _c: &AnyonType,
1797 _d: &AnyonType,
1798 ) -> Array2<Complex64> {
1799 Array2::eye(1)
1800 }
1801 fn is_abelian(&self) -> bool {
1802 self.level <= 2
1803 }
1804 fn name(&self) -> &'static str {
1805 "Chern-Simons Anyons"
1806 }
1807}
1808
1809pub struct TopologicalUtils;
1811
1812impl TopologicalUtils {
1813 #[must_use]
1815 pub fn create_predefined_config(config_type: &str, size: usize) -> TopologicalConfig {
1816 match config_type {
1817 "toric_code" => TopologicalConfig {
1818 lattice_type: LatticeType::SquareLattice,
1819 dimensions: vec![size, size],
1820 anyon_model: AnyonModel::Abelian,
1821 boundary_conditions: TopologicalBoundaryConditions::Periodic,
1822 error_correction_code: TopologicalErrorCode::SurfaceCode,
1823 topological_protection: true,
1824 enable_braiding: false,
1825 ..Default::default()
1826 },
1827 "fibonacci_system" => TopologicalConfig {
1828 lattice_type: LatticeType::TriangularLattice,
1829 dimensions: vec![size, size],
1830 anyon_model: AnyonModel::Fibonacci,
1831 boundary_conditions: TopologicalBoundaryConditions::Open,
1832 topological_protection: true,
1833 enable_braiding: true,
1834 ..Default::default()
1835 },
1836 "majorana_system" => TopologicalConfig {
1837 lattice_type: LatticeType::HoneycombLattice,
1838 dimensions: vec![size, size],
1839 anyon_model: AnyonModel::Ising,
1840 boundary_conditions: TopologicalBoundaryConditions::Open,
1841 topological_protection: true,
1842 enable_braiding: true,
1843 ..Default::default()
1844 },
1845 _ => TopologicalConfig::default(),
1846 }
1847 }
1848
1849 pub fn benchmark_topological_simulation() -> Result<TopologicalBenchmarkResults> {
1851 let mut results = TopologicalBenchmarkResults::default();
1852
1853 let configs = vec![
1854 (
1855 "toric_code",
1856 Self::create_predefined_config("toric_code", 4),
1857 ),
1858 (
1859 "fibonacci",
1860 Self::create_predefined_config("fibonacci_system", 3),
1861 ),
1862 (
1863 "majorana",
1864 Self::create_predefined_config("majorana_system", 3),
1865 ),
1866 ];
1867
1868 for (name, config) in configs {
1869 let mut simulator = TopologicalQuantumSimulator::new(config)?;
1870
1871 if simulator.config.enable_braiding {
1873 let vacuum = AnyonType::vacuum();
1874 simulator.place_anyon(vacuum.clone(), vec![0, 0])?;
1875 simulator.place_anyon(vacuum, vec![1, 1])?;
1876 }
1877
1878 let start = std::time::Instant::now();
1879
1880 if simulator.config.enable_braiding && simulator.state.anyon_config.anyons.len() >= 2 {
1882 simulator.braid_anyons(0, 1, BraidingType::Clockwise)?;
1883 }
1884
1885 simulator.calculate_topological_invariants()?;
1886
1887 let time = start.elapsed().as_secs_f64() * 1000.0;
1888
1889 results.benchmark_times.push((name.to_string(), time));
1890 results
1891 .simulation_stats
1892 .insert(name.to_string(), simulator.get_stats().clone());
1893 }
1894
1895 Ok(results)
1896 }
1897}
1898
1899#[derive(Debug, Clone, Default)]
1901pub struct TopologicalBenchmarkResults {
1902 pub benchmark_times: Vec<(String, f64)>,
1904 pub simulation_stats: HashMap<String, TopologicalSimulationStats>,
1906}
1907
1908#[cfg(test)]
1909mod tests {
1910 use super::*;
1911 use approx::assert_abs_diff_eq;
1912
1913 #[test]
1914 fn test_topological_config_default() {
1915 let config = TopologicalConfig::default();
1916 assert_eq!(config.lattice_type, LatticeType::SquareLattice);
1917 assert_eq!(config.dimensions, vec![8, 8]);
1918 assert!(config.topological_protection);
1919 }
1920
1921 #[test]
1922 fn test_anyon_type_creation() {
1923 let vacuum = AnyonType::vacuum();
1924 assert_eq!(vacuum.label, "vacuum");
1925 assert_eq!(vacuum.quantum_dimension, 1.0);
1926 assert!(vacuum.is_abelian);
1927
1928 let sigma = AnyonType::sigma();
1929 assert_eq!(sigma.label, "sigma");
1930 assert_abs_diff_eq!(sigma.quantum_dimension, 2.0_f64.sqrt(), epsilon = 1e-10);
1931 assert!(!sigma.is_abelian);
1932 }
1933
1934 #[test]
1935 fn test_topological_simulator_creation() {
1936 let config = TopologicalConfig::default();
1937 let simulator = TopologicalQuantumSimulator::new(config);
1938 assert!(simulator.is_ok());
1939 }
1940
1941 #[test]
1942 fn test_square_lattice_creation() {
1943 let dimensions = vec![3, 3];
1944 let lattice = TopologicalQuantumSimulator::create_square_lattice(&dimensions)
1945 .expect("failed to create square lattice");
1946
1947 assert_eq!(lattice.sites.len(), 9); assert_eq!(lattice.coordination_number, 4);
1949 assert!(!lattice.bonds.is_empty());
1950 assert!(!lattice.plaquettes.is_empty());
1951 }
1952
1953 #[test]
1954 fn test_anyon_placement() {
1955 let config = TopologicalConfig::default();
1956 let mut simulator =
1957 TopologicalQuantumSimulator::new(config).expect("failed to create simulator");
1958
1959 let vacuum = AnyonType::vacuum();
1960 let anyon_id = simulator
1961 .place_anyon(vacuum, vec![2, 3])
1962 .expect("failed to place anyon");
1963
1964 assert_eq!(anyon_id, 0);
1965 assert_eq!(simulator.state.anyon_config.anyons.len(), 1);
1966 assert_eq!(simulator.state.anyon_config.anyons[0].0, vec![2, 3]);
1967 }
1968
1969 #[test]
1970 fn test_braiding_operation() {
1971 let mut config = TopologicalConfig::default();
1972 config.enable_braiding = true;
1973 let mut simulator =
1974 TopologicalQuantumSimulator::new(config).expect("failed to create simulator");
1975
1976 let sigma = AnyonType::sigma();
1977 let anyon_a = simulator
1978 .place_anyon(sigma.clone(), vec![1, 1])
1979 .expect("failed to place anyon A");
1980 let anyon_b = simulator
1981 .place_anyon(sigma, vec![2, 2])
1982 .expect("failed to place anyon B");
1983
1984 let braiding_phase = simulator.braid_anyons(anyon_a, anyon_b, BraidingType::Clockwise);
1985 assert!(braiding_phase.is_ok());
1986 assert_eq!(simulator.braiding_history.len(), 1);
1987 assert_eq!(simulator.stats.braiding_operations, 1);
1988 }
1989
1990 #[test]
1991 fn test_anyon_fusion() {
1992 let config = TopologicalConfig::default();
1993 let mut simulator =
1994 TopologicalQuantumSimulator::new(config).expect("failed to create simulator");
1995
1996 let sigma = AnyonType::sigma();
1997 let anyon_a = simulator
1998 .place_anyon(sigma.clone(), vec![1, 1])
1999 .expect("failed to place anyon A");
2000 let anyon_b = simulator
2001 .place_anyon(sigma, vec![1, 2])
2002 .expect("failed to place anyon B");
2003
2004 let fusion_outcomes = simulator.fuse_anyons(anyon_a, anyon_b);
2005 assert!(fusion_outcomes.is_ok());
2006 }
2007
2008 #[test]
2009 fn test_fibonacci_anyons() {
2010 let fibonacci_model = FibonacciAnyons::new();
2011 let anyon_types = fibonacci_model.get_anyon_types();
2012
2013 assert_eq!(anyon_types.len(), 2); assert!(!fibonacci_model.is_abelian());
2015 assert_eq!(fibonacci_model.name(), "Fibonacci Anyons");
2016 }
2017
2018 #[test]
2019 fn test_ising_anyons() {
2020 let ising_model = IsingAnyons::new();
2021 let anyon_types = ising_model.get_anyon_types();
2022
2023 assert_eq!(anyon_types.len(), 3); assert!(!ising_model.is_abelian());
2025 assert_eq!(ising_model.name(), "Ising Anyons");
2026 }
2027
2028 #[test]
2029 fn test_surface_code_creation() {
2030 let dimensions = vec![4, 4];
2031 let surface_code = TopologicalQuantumSimulator::create_toric_surface_code(&dimensions)
2032 .expect("failed to create surface code");
2033
2034 assert_eq!(surface_code.distance, 4);
2035 assert!(!surface_code.data_qubits.is_empty());
2036 assert!(!surface_code.x_stabilizers.is_empty());
2037 assert!(!surface_code.z_stabilizers.is_empty());
2038 }
2039
2040 #[test]
2041 fn test_topological_invariants() {
2042 let config = TopologicalConfig::default();
2043 let mut simulator =
2044 TopologicalQuantumSimulator::new(config).expect("failed to create simulator");
2045
2046 let invariants = simulator.calculate_topological_invariants();
2047 assert!(invariants.is_ok());
2048
2049 let inv = invariants.expect("failed to calculate invariants");
2050 assert!(inv.chern_number.abs() >= 0);
2051 assert!(inv.hall_conductivity.is_finite());
2052 }
2053
2054 #[test]
2055 fn test_triangular_lattice() {
2056 let dimensions = vec![3, 3];
2057 let lattice = TopologicalQuantumSimulator::create_triangular_lattice(&dimensions)
2058 .expect("failed to create triangular lattice");
2059
2060 assert_eq!(lattice.lattice_type, LatticeType::TriangularLattice);
2061 assert_eq!(lattice.sites.len(), 9);
2062 assert_eq!(lattice.coordination_number, 6);
2063 }
2064
2065 #[test]
2066 fn test_honeycomb_lattice() {
2067 let dimensions = vec![2, 2];
2068 let lattice = TopologicalQuantumSimulator::create_honeycomb_lattice(&dimensions)
2069 .expect("failed to create honeycomb lattice");
2070
2071 assert_eq!(lattice.lattice_type, LatticeType::HoneycombLattice);
2072 assert_eq!(lattice.coordination_number, 3);
2073 assert!(!lattice.bonds.is_empty());
2074 }
2075
2076 #[test]
2077 fn test_error_detection_and_correction() {
2078 let mut config = TopologicalConfig::default();
2079 config.topological_protection = true;
2080 let mut simulator =
2081 TopologicalQuantumSimulator::new(config).expect("failed to create simulator");
2082
2083 let syndrome = simulator.detect_and_correct_errors();
2084 assert!(syndrome.is_ok());
2085 }
2086
2087 #[test]
2088 fn test_predefined_configs() {
2089 let configs = vec!["toric_code", "fibonacci_system", "majorana_system"];
2090
2091 for config_type in configs {
2092 let config = TopologicalUtils::create_predefined_config(config_type, 4);
2093 let simulator = TopologicalQuantumSimulator::new(config);
2094 assert!(simulator.is_ok());
2095 }
2096 }
2097}