1use super::{CVDeviceConfig, CVGateSequence, Complex, GaussianState};
7use crate::{DeviceError, DeviceResult};
8use serde::{Deserialize, Serialize};
9use std::collections::{HashMap, HashSet};
10use std::f64::consts::PI;
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
14pub enum ClusterStateType {
15 Linear,
17 Square,
19 Hexagonal,
21 Custom { adjacency_matrix: Vec<Vec<bool>> },
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct ClusterStateConfig {
28 pub cluster_type: ClusterStateType,
30 pub num_modes: usize,
32 pub squeezing_parameter: f64,
34 pub entangling_strength: f64,
36 pub graph_structure: HashMap<usize, Vec<usize>>,
38 pub finite_squeezing_compensation: bool,
40}
41
42impl ClusterStateConfig {
43 pub fn linear(num_modes: usize, squeezing: f64) -> Self {
45 let mut graph_structure = HashMap::new();
46
47 for i in 0..num_modes {
48 let mut neighbors = Vec::new();
49 if i > 0 {
50 neighbors.push(i - 1);
51 }
52 if i < num_modes - 1 {
53 neighbors.push(i + 1);
54 }
55 graph_structure.insert(i, neighbors);
56 }
57
58 Self {
59 cluster_type: ClusterStateType::Linear,
60 num_modes,
61 squeezing_parameter: squeezing,
62 entangling_strength: 1.0,
63 graph_structure,
64 finite_squeezing_compensation: true,
65 }
66 }
67
68 pub fn square_lattice(width: usize, height: usize, squeezing: f64) -> Self {
70 let num_modes = width * height;
71 let mut graph_structure = HashMap::new();
72
73 for i in 0..height {
74 for j in 0..width {
75 let node = i * width + j;
76 let mut neighbors = Vec::new();
77
78 if j > 0 {
80 neighbors.push(i * width + (j - 1));
81 }
82 if j < width - 1 {
83 neighbors.push(i * width + (j + 1));
84 }
85
86 if i > 0 {
88 neighbors.push((i - 1) * width + j);
89 }
90 if i < height - 1 {
91 neighbors.push((i + 1) * width + j);
92 }
93
94 graph_structure.insert(node, neighbors);
95 }
96 }
97
98 Self {
99 cluster_type: ClusterStateType::Square,
100 num_modes,
101 squeezing_parameter: squeezing,
102 entangling_strength: 1.0,
103 graph_structure,
104 finite_squeezing_compensation: true,
105 }
106 }
107
108 pub fn custom(adjacency_matrix: Vec<Vec<bool>>, squeezing: f64) -> DeviceResult<Self> {
110 let num_modes = adjacency_matrix.len();
111
112 for row in &adjacency_matrix {
114 if row.len() != num_modes {
115 return Err(DeviceError::InvalidInput(
116 "Adjacency matrix must be square".to_string(),
117 ));
118 }
119 }
120
121 let mut graph_structure = HashMap::new();
123 for i in 0..num_modes {
124 let mut neighbors = Vec::new();
125 for j in 0..num_modes {
126 if adjacency_matrix[i][j] {
127 neighbors.push(j);
128 }
129 }
130 graph_structure.insert(i, neighbors);
131 }
132
133 Ok(Self {
134 cluster_type: ClusterStateType::Custom { adjacency_matrix },
135 num_modes,
136 squeezing_parameter: squeezing,
137 entangling_strength: 1.0,
138 graph_structure,
139 finite_squeezing_compensation: true,
140 })
141 }
142}
143
144pub struct ClusterStateGenerator {
146 config: ClusterStateConfig,
148 cluster_state: Option<GaussianState>,
150 generation_stats: GenerationStatistics,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize)]
156pub struct GenerationStatistics {
157 pub total_entangling_gates: usize,
159 pub average_entanglement: f64,
161 pub nullifier_violations: f64,
163 pub generation_fidelity: f64,
165 pub generation_time_ms: f64,
167}
168
169impl Default for GenerationStatistics {
170 fn default() -> Self {
171 Self {
172 total_entangling_gates: 0,
173 average_entanglement: 0.0,
174 nullifier_violations: 0.0,
175 generation_fidelity: 0.0,
176 generation_time_ms: 0.0,
177 }
178 }
179}
180
181impl ClusterStateGenerator {
182 pub fn new(config: ClusterStateConfig) -> Self {
184 Self {
185 config,
186 cluster_state: None,
187 generation_stats: GenerationStatistics::default(),
188 }
189 }
190
191 pub async fn generate_cluster_state(&mut self) -> DeviceResult<GaussianState> {
193 let start_time = std::time::Instant::now();
194
195 println!(
196 "Generating {} cluster state with {} modes",
197 match self.config.cluster_type {
198 ClusterStateType::Linear => "linear",
199 ClusterStateType::Square => "square lattice",
200 ClusterStateType::Hexagonal => "hexagonal",
201 ClusterStateType::Custom { .. } => "custom",
202 },
203 self.config.num_modes
204 );
205
206 let mut state = self.initialize_squeezed_modes().await?;
208
209 self.apply_entangling_gates(&mut state).await?;
211
212 if self.config.finite_squeezing_compensation {
214 self.apply_squeezing_compensation(&mut state).await?;
215 }
216
217 self.calculate_generation_statistics(&state);
219
220 let generation_time = start_time.elapsed();
221 self.generation_stats.generation_time_ms = generation_time.as_millis() as f64;
222
223 println!(
224 "Cluster state generated in {:.2} ms with fidelity {:.3}",
225 self.generation_stats.generation_time_ms, self.generation_stats.generation_fidelity
226 );
227
228 self.cluster_state = Some(state.clone());
229 Ok(state)
230 }
231
232 async fn initialize_squeezed_modes(&mut self) -> DeviceResult<GaussianState> {
234 let squeezing_params = vec![self.config.squeezing_parameter; self.config.num_modes];
235 let squeezing_phases = vec![0.0; self.config.num_modes]; GaussianState::squeezed_vacuum_state(
238 self.config.num_modes,
239 squeezing_params,
240 squeezing_phases,
241 )
242 .map_err(|e| DeviceError::InvalidInput(format!("Failed to create squeezed states: {}", e)))
243 }
244
245 async fn apply_entangling_gates(&mut self, state: &mut GaussianState) -> DeviceResult<()> {
247 let mut gate_count = 0;
248
249 let mut edges = HashSet::new();
251 for (node, neighbors) in &self.config.graph_structure {
252 for neighbor in neighbors {
253 let edge = if node < neighbor {
254 (*node, *neighbor)
255 } else {
256 (*neighbor, *node)
257 };
258 edges.insert(edge);
259 }
260 }
261
262 println!("Applying {} entangling gates", edges.len());
263
264 for (mode1, mode2) in edges {
266 self.apply_cv_cz_gate(state, mode1, mode2).await?;
267 gate_count += 1;
268
269 if gate_count % 10 == 0 {
271 tokio::time::sleep(std::time::Duration::from_millis(1)).await;
272 }
273 }
274
275 self.generation_stats.total_entangling_gates = gate_count;
276 Ok(())
277 }
278
279 async fn apply_cv_cz_gate(
281 &self,
282 state: &mut GaussianState,
283 mode1: usize,
284 mode2: usize,
285 ) -> DeviceResult<()> {
286 let strength = self.config.entangling_strength;
290
291 let old_covar = state.covariancematrix.clone();
293
294 let i1_x = 2 * mode1; let i1_p = 2 * mode1 + 1; let i2_x = 2 * mode2; let i2_p = 2 * mode2 + 1; state.covariancematrix[i1_x][i2_p] +=
304 strength * old_covar[i1_x][i1_x].sqrt() * old_covar[i2_p][i2_p].sqrt();
305 state.covariancematrix[i2_p][i1_x] +=
306 strength * old_covar[i1_x][i1_x].sqrt() * old_covar[i2_p][i2_p].sqrt();
307
308 state.covariancematrix[i1_p][i2_x] +=
309 strength * old_covar[i1_p][i1_p].sqrt() * old_covar[i2_x][i2_x].sqrt();
310 state.covariancematrix[i2_x][i1_p] +=
311 strength * old_covar[i1_p][i1_p].sqrt() * old_covar[i2_x][i2_x].sqrt();
312
313 Ok(())
314 }
315
316 async fn apply_squeezing_compensation(
318 &mut self,
319 state: &mut GaussianState,
320 ) -> DeviceResult<()> {
321 println!("Applying finite squeezing compensation");
322
323 for mode in 0..self.config.num_modes {
328 let var_x = state.covariancematrix[2 * mode][2 * mode];
330 let compensation_squeezing = if var_x > 0.1 {
331 -0.5 * var_x.ln() } else {
333 0.0
334 };
335
336 if compensation_squeezing > 0.1 {
337 state.apply_squeezing(mode, compensation_squeezing, 0.0)?;
338 }
339 }
340
341 Ok(())
342 }
343
344 fn calculate_generation_statistics(&mut self, state: &GaussianState) {
346 let entanglement_measures = state.calculate_entanglement_measures();
348 self.generation_stats.average_entanglement = entanglement_measures.logarithmic_negativity;
349
350 let mut total_violation = 0.0;
352 for mode in 0..self.config.num_modes {
353 let var_x = state.covariancematrix[2 * mode][2 * mode];
354 total_violation += var_x;
356 }
357 self.generation_stats.nullifier_violations = total_violation / self.config.num_modes as f64;
358
359 self.generation_stats.generation_fidelity = self.estimate_cluster_state_fidelity(state);
361 }
362
363 fn estimate_cluster_state_fidelity(&self, state: &GaussianState) -> f64 {
365 let ideal_variance = 0.0; let actual_variance = self.generation_stats.nullifier_violations;
368
369 let variance_penalty = (-actual_variance / 0.5).exp();
371
372 let entanglement_bonus = (self.generation_stats.average_entanglement / 2.0).tanh();
374
375 (variance_penalty * (0.8 + 0.2 * entanglement_bonus)).clamp(0.0, 1.0)
376 }
377
378 pub async fn perform_mbqc_sequence(
380 &mut self,
381 measurement_sequence: Vec<MBQCMeasurement>,
382 ) -> DeviceResult<Vec<MBQCResult>> {
383 if self.cluster_state.is_none() {
384 return Err(DeviceError::InvalidInput(
385 "No cluster state generated".to_string(),
386 ));
387 }
388
389 let mut state = self.cluster_state.as_ref().unwrap().clone();
390 let mut results = Vec::new();
391
392 println!(
393 "Performing MBQC sequence with {} measurements",
394 measurement_sequence.len()
395 );
396
397 for (i, measurement) in measurement_sequence.iter().enumerate() {
398 let result = self
399 .perform_single_mbqc_measurement(&mut state, measurement)
400 .await?;
401 results.push(result);
402
403 println!(
404 "Completed measurement {} of {}",
405 i + 1,
406 measurement_sequence.len()
407 );
408 }
409
410 Ok(results)
411 }
412
413 async fn perform_single_mbqc_measurement(
415 &self,
416 state: &mut GaussianState,
417 measurement: &MBQCMeasurement,
418 ) -> DeviceResult<MBQCResult> {
419 match measurement.measurement_type {
420 MBQCMeasurementType::Homodyne { phase } => {
421 let config = CVDeviceConfig::default();
423 let measured_value =
424 state.homodyne_measurement(measurement.mode, phase, &config)?;
425
426 Ok(MBQCResult {
427 mode: measurement.mode,
428 measurement_type: measurement.measurement_type.clone(),
429 outcome: measured_value,
430 feedforward_corrections: self
431 .calculate_feedforward(measurement, measured_value),
432 success_probability: 1.0, })
434 }
435
436 MBQCMeasurementType::Projection { target_value } => {
437 let config = CVDeviceConfig::default();
439 let measured_value = state.homodyne_measurement(measurement.mode, 0.0, &config)?;
440 let success_prob =
441 self.calculate_projection_success_probability(measured_value, target_value);
442
443 Ok(MBQCResult {
444 mode: measurement.mode,
445 measurement_type: measurement.measurement_type.clone(),
446 outcome: measured_value,
447 feedforward_corrections: Vec::new(),
448 success_probability: success_prob,
449 })
450 }
451 }
452 }
453
454 fn calculate_feedforward(
456 &self,
457 measurement: &MBQCMeasurement,
458 outcome: f64,
459 ) -> Vec<FeedforwardCorrection> {
460 let mut corrections = Vec::new();
461
462 if let Some(neighbors) = self.config.graph_structure.get(&measurement.mode) {
464 for &neighbor in neighbors {
465 let correction_phase = outcome * 0.1; corrections.push(FeedforwardCorrection {
468 target_mode: neighbor,
469 correction_type: CorrectionType::PhaseShift {
470 phase: correction_phase,
471 },
472 });
473 }
474 }
475
476 corrections
477 }
478
479 fn calculate_projection_success_probability(&self, measured: f64, target: f64) -> f64 {
481 let tolerance = 0.5; let deviation = (measured - target).abs();
483
484 if deviation <= tolerance {
485 1.0 - deviation / tolerance
486 } else {
487 0.0
488 }
489 }
490
491 pub fn get_cluster_state(&self) -> Option<&GaussianState> {
493 self.cluster_state.as_ref()
494 }
495
496 pub fn get_generation_statistics(&self) -> &GenerationStatistics {
498 &self.generation_stats
499 }
500
501 pub fn validate_cluster_state(&self) -> DeviceResult<ClusterStateValidation> {
503 if let Some(state) = &self.cluster_state {
504 let mut validation = ClusterStateValidation::default();
505
506 validation.nullifier_eigenvalues = self.calculate_nullifier_eigenvalues(state);
508 validation.max_nullifier_violation = validation
509 .nullifier_eigenvalues
510 .iter()
511 .fold(0.0, |acc, &x| acc.max(x));
512
513 validation.entanglement_spectrum = self.calculate_entanglement_spectrum(state);
515 validation.average_entanglement = validation.entanglement_spectrum.iter().sum::<f64>()
516 / validation.entanglement_spectrum.len() as f64;
517
518 validation.is_valid =
520 validation.max_nullifier_violation < 0.1 && validation.average_entanglement > 0.5;
521
522 Ok(validation)
523 } else {
524 Err(DeviceError::InvalidInput(
525 "No cluster state to validate".to_string(),
526 ))
527 }
528 }
529
530 fn calculate_nullifier_eigenvalues(&self, state: &GaussianState) -> Vec<f64> {
532 let mut eigenvalues = Vec::new();
534
535 for mode in 0..self.config.num_modes {
536 let var_x = state.covariancematrix[2 * mode][2 * mode];
537 eigenvalues.push(var_x);
538 }
539
540 eigenvalues
541 }
542
543 fn calculate_entanglement_spectrum(&self, state: &GaussianState) -> Vec<f64> {
545 let mut spectrum = Vec::new();
547
548 for i in 0..self.config.num_modes {
550 for j in (i + 1)..self.config.num_modes {
551 let cov_ij = state.covariancematrix[2 * i][2 * j];
552 let entanglement = cov_ij.abs(); spectrum.push(entanglement);
554 }
555 }
556
557 spectrum
558 }
559}
560
561#[derive(Debug, Clone, Serialize, Deserialize)]
563pub struct MBQCMeasurement {
564 pub mode: usize,
566 pub measurement_type: MBQCMeasurementType,
568 pub is_adaptive: bool,
570}
571
572#[derive(Debug, Clone, Serialize, Deserialize)]
574pub enum MBQCMeasurementType {
575 Homodyne { phase: f64 },
577 Projection { target_value: f64 },
579}
580
581#[derive(Debug, Clone, Serialize, Deserialize)]
583pub struct MBQCResult {
584 pub mode: usize,
586 pub measurement_type: MBQCMeasurementType,
588 pub outcome: f64,
590 pub feedforward_corrections: Vec<FeedforwardCorrection>,
592 pub success_probability: f64,
594}
595
596#[derive(Debug, Clone, Serialize, Deserialize)]
598pub struct FeedforwardCorrection {
599 pub target_mode: usize,
601 pub correction_type: CorrectionType,
603}
604
605#[derive(Debug, Clone, Serialize, Deserialize)]
607pub enum CorrectionType {
608 PhaseShift { phase: f64 },
610 Displacement { amplitude: Complex },
612 Squeezing { parameter: f64, phase: f64 },
614}
615
616#[derive(Debug, Clone, Serialize, Deserialize)]
618pub struct ClusterStateValidation {
619 pub is_valid: bool,
621 pub nullifier_eigenvalues: Vec<f64>,
623 pub max_nullifier_violation: f64,
625 pub entanglement_spectrum: Vec<f64>,
627 pub average_entanglement: f64,
629}
630
631impl Default for ClusterStateValidation {
632 fn default() -> Self {
633 Self {
634 is_valid: false,
635 nullifier_eigenvalues: Vec::new(),
636 max_nullifier_violation: 0.0,
637 entanglement_spectrum: Vec::new(),
638 average_entanglement: 0.0,
639 }
640 }
641}
642
643#[cfg(test)]
644mod tests {
645 use super::*;
646
647 #[test]
648 fn test_linear_cluster_config() {
649 let config = ClusterStateConfig::linear(5, 1.0);
650 assert_eq!(config.num_modes, 5);
651 assert_eq!(config.cluster_type, ClusterStateType::Linear);
652 assert_eq!(config.graph_structure.len(), 5);
653
654 assert_eq!(config.graph_structure[&0], vec![1]);
656 assert_eq!(config.graph_structure[&2], vec![1, 3]);
657 assert_eq!(config.graph_structure[&4], vec![3]);
658 }
659
660 #[test]
661 fn test_square_lattice_config() {
662 let config = ClusterStateConfig::square_lattice(3, 3, 1.0);
663 assert_eq!(config.num_modes, 9);
664 assert_eq!(config.cluster_type, ClusterStateType::Square);
665
666 assert_eq!(config.graph_structure[&0].len(), 2);
668 assert_eq!(config.graph_structure[&4].len(), 4);
670 }
671
672 #[test]
673 fn test_custom_cluster_config() {
674 let adjacency = vec![
675 vec![false, true, false],
676 vec![true, false, true],
677 vec![false, true, false],
678 ];
679
680 let config = ClusterStateConfig::custom(adjacency, 1.0).unwrap();
681 assert_eq!(config.num_modes, 3);
682
683 assert_eq!(config.graph_structure[&0], vec![1]);
685 assert_eq!(config.graph_structure[&1], vec![0, 2]);
686 assert_eq!(config.graph_structure[&2], vec![1]);
687 }
688
689 #[tokio::test]
690 async fn test_cluster_state_generation() {
691 let config = ClusterStateConfig::linear(3, 1.0);
692 let mut generator = ClusterStateGenerator::new(config);
693
694 let state = generator.generate_cluster_state().await.unwrap();
695 assert_eq!(state.num_modes, 3);
696
697 let stats = generator.get_generation_statistics();
698 assert!(stats.total_entangling_gates > 0);
699 assert!(stats.generation_fidelity > 0.0);
700 }
701
702 #[tokio::test]
703 async fn test_mbqc_measurement() {
704 let config = ClusterStateConfig::linear(3, 1.0);
705 let mut generator = ClusterStateGenerator::new(config);
706 generator.generate_cluster_state().await.unwrap();
707
708 let measurements = vec![MBQCMeasurement {
709 mode: 0,
710 measurement_type: MBQCMeasurementType::Homodyne { phase: 0.0 },
711 is_adaptive: false,
712 }];
713
714 let results = generator.perform_mbqc_sequence(measurements).await.unwrap();
715 assert_eq!(results.len(), 1);
716 assert_eq!(results[0].success_probability, 1.0);
717 }
718
719 #[test]
720 fn test_cluster_validation() {
721 let config = ClusterStateConfig::linear(2, 1.0);
722 let generator = ClusterStateGenerator::new(config);
723
724 assert!(generator.validate_cluster_state().is_err());
726 }
727
728 #[test]
729 fn test_feedforward_calculation() {
730 let config = ClusterStateConfig::linear(3, 1.0);
731 let generator = ClusterStateGenerator::new(config);
732
733 let measurement = MBQCMeasurement {
734 mode: 1,
735 measurement_type: MBQCMeasurementType::Homodyne { phase: 0.0 },
736 is_adaptive: false,
737 };
738
739 let corrections = generator.calculate_feedforward(&measurement, 1.0);
740 assert_eq!(corrections.len(), 2); }
742}