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, Eq, 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.2f64.mul_add(entanglement_bonus, 0.8)).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
390 .cluster_state
391 .as_ref()
392 .expect("cluster state verified to exist above")
393 .clone();
394 let mut results = Vec::new();
395
396 println!(
397 "Performing MBQC sequence with {} measurements",
398 measurement_sequence.len()
399 );
400
401 for (i, measurement) in measurement_sequence.iter().enumerate() {
402 let result = self
403 .perform_single_mbqc_measurement(&mut state, measurement)
404 .await?;
405 results.push(result);
406
407 println!(
408 "Completed measurement {} of {}",
409 i + 1,
410 measurement_sequence.len()
411 );
412 }
413
414 Ok(results)
415 }
416
417 async fn perform_single_mbqc_measurement(
419 &self,
420 state: &mut GaussianState,
421 measurement: &MBQCMeasurement,
422 ) -> DeviceResult<MBQCResult> {
423 match measurement.measurement_type {
424 MBQCMeasurementType::Homodyne { phase } => {
425 let config = CVDeviceConfig::default();
427 let measured_value =
428 state.homodyne_measurement(measurement.mode, phase, &config)?;
429
430 Ok(MBQCResult {
431 mode: measurement.mode,
432 measurement_type: measurement.measurement_type.clone(),
433 outcome: measured_value,
434 feedforward_corrections: self
435 .calculate_feedforward(measurement, measured_value),
436 success_probability: 1.0, })
438 }
439
440 MBQCMeasurementType::Projection { target_value } => {
441 let config = CVDeviceConfig::default();
443 let measured_value = state.homodyne_measurement(measurement.mode, 0.0, &config)?;
444 let success_prob =
445 self.calculate_projection_success_probability(measured_value, target_value);
446
447 Ok(MBQCResult {
448 mode: measurement.mode,
449 measurement_type: measurement.measurement_type.clone(),
450 outcome: measured_value,
451 feedforward_corrections: Vec::new(),
452 success_probability: success_prob,
453 })
454 }
455 }
456 }
457
458 fn calculate_feedforward(
460 &self,
461 measurement: &MBQCMeasurement,
462 outcome: f64,
463 ) -> Vec<FeedforwardCorrection> {
464 let mut corrections = Vec::new();
465
466 if let Some(neighbors) = self.config.graph_structure.get(&measurement.mode) {
468 for &neighbor in neighbors {
469 let correction_phase = outcome * 0.1; corrections.push(FeedforwardCorrection {
472 target_mode: neighbor,
473 correction_type: CorrectionType::PhaseShift {
474 phase: correction_phase,
475 },
476 });
477 }
478 }
479
480 corrections
481 }
482
483 fn calculate_projection_success_probability(&self, measured: f64, target: f64) -> f64 {
485 let tolerance = 0.5; let deviation = (measured - target).abs();
487
488 if deviation <= tolerance {
489 1.0 - deviation / tolerance
490 } else {
491 0.0
492 }
493 }
494
495 pub const fn get_cluster_state(&self) -> Option<&GaussianState> {
497 self.cluster_state.as_ref()
498 }
499
500 pub const fn get_generation_statistics(&self) -> &GenerationStatistics {
502 &self.generation_stats
503 }
504
505 pub fn validate_cluster_state(&self) -> DeviceResult<ClusterStateValidation> {
507 if let Some(state) = &self.cluster_state {
508 let mut validation = ClusterStateValidation::default();
509
510 validation.nullifier_eigenvalues = self.calculate_nullifier_eigenvalues(state);
512 validation.max_nullifier_violation = validation
513 .nullifier_eigenvalues
514 .iter()
515 .fold(0.0, |acc, &x| acc.max(x));
516
517 validation.entanglement_spectrum = self.calculate_entanglement_spectrum(state);
519 validation.average_entanglement = validation.entanglement_spectrum.iter().sum::<f64>()
520 / validation.entanglement_spectrum.len() as f64;
521
522 validation.is_valid =
524 validation.max_nullifier_violation < 0.1 && validation.average_entanglement > 0.5;
525
526 Ok(validation)
527 } else {
528 Err(DeviceError::InvalidInput(
529 "No cluster state to validate".to_string(),
530 ))
531 }
532 }
533
534 fn calculate_nullifier_eigenvalues(&self, state: &GaussianState) -> Vec<f64> {
536 let mut eigenvalues = Vec::new();
538
539 for mode in 0..self.config.num_modes {
540 let var_x = state.covariancematrix[2 * mode][2 * mode];
541 eigenvalues.push(var_x);
542 }
543
544 eigenvalues
545 }
546
547 fn calculate_entanglement_spectrum(&self, state: &GaussianState) -> Vec<f64> {
549 let mut spectrum = Vec::new();
551
552 for i in 0..self.config.num_modes {
554 for j in (i + 1)..self.config.num_modes {
555 let cov_ij = state.covariancematrix[2 * i][2 * j];
556 let entanglement = cov_ij.abs(); spectrum.push(entanglement);
558 }
559 }
560
561 spectrum
562 }
563}
564
565#[derive(Debug, Clone, Serialize, Deserialize)]
567pub struct MBQCMeasurement {
568 pub mode: usize,
570 pub measurement_type: MBQCMeasurementType,
572 pub is_adaptive: bool,
574}
575
576#[derive(Debug, Clone, Serialize, Deserialize)]
578pub enum MBQCMeasurementType {
579 Homodyne { phase: f64 },
581 Projection { target_value: f64 },
583}
584
585#[derive(Debug, Clone, Serialize, Deserialize)]
587pub struct MBQCResult {
588 pub mode: usize,
590 pub measurement_type: MBQCMeasurementType,
592 pub outcome: f64,
594 pub feedforward_corrections: Vec<FeedforwardCorrection>,
596 pub success_probability: f64,
598}
599
600#[derive(Debug, Clone, Serialize, Deserialize)]
602pub struct FeedforwardCorrection {
603 pub target_mode: usize,
605 pub correction_type: CorrectionType,
607}
608
609#[derive(Debug, Clone, Serialize, Deserialize)]
611pub enum CorrectionType {
612 PhaseShift { phase: f64 },
614 Displacement { amplitude: Complex },
616 Squeezing { parameter: f64, phase: f64 },
618}
619
620#[derive(Debug, Clone, Serialize, Deserialize)]
622pub struct ClusterStateValidation {
623 pub is_valid: bool,
625 pub nullifier_eigenvalues: Vec<f64>,
627 pub max_nullifier_violation: f64,
629 pub entanglement_spectrum: Vec<f64>,
631 pub average_entanglement: f64,
633}
634
635impl Default for ClusterStateValidation {
636 fn default() -> Self {
637 Self {
638 is_valid: false,
639 nullifier_eigenvalues: Vec::new(),
640 max_nullifier_violation: 0.0,
641 entanglement_spectrum: Vec::new(),
642 average_entanglement: 0.0,
643 }
644 }
645}
646
647#[cfg(test)]
648mod tests {
649 use super::*;
650
651 #[test]
652 fn test_linear_cluster_config() {
653 let config = ClusterStateConfig::linear(5, 1.0);
654 assert_eq!(config.num_modes, 5);
655 assert_eq!(config.cluster_type, ClusterStateType::Linear);
656 assert_eq!(config.graph_structure.len(), 5);
657
658 assert_eq!(config.graph_structure[&0], vec![1]);
660 assert_eq!(config.graph_structure[&2], vec![1, 3]);
661 assert_eq!(config.graph_structure[&4], vec![3]);
662 }
663
664 #[test]
665 fn test_square_lattice_config() {
666 let config = ClusterStateConfig::square_lattice(3, 3, 1.0);
667 assert_eq!(config.num_modes, 9);
668 assert_eq!(config.cluster_type, ClusterStateType::Square);
669
670 assert_eq!(config.graph_structure[&0].len(), 2);
672 assert_eq!(config.graph_structure[&4].len(), 4);
674 }
675
676 #[test]
677 fn test_custom_cluster_config() {
678 let adjacency = vec![
679 vec![false, true, false],
680 vec![true, false, true],
681 vec![false, true, false],
682 ];
683
684 let config =
685 ClusterStateConfig::custom(adjacency, 1.0).expect("Custom adjacency should be valid");
686 assert_eq!(config.num_modes, 3);
687
688 assert_eq!(config.graph_structure[&0], vec![1]);
690 assert_eq!(config.graph_structure[&1], vec![0, 2]);
691 assert_eq!(config.graph_structure[&2], vec![1]);
692 }
693
694 #[tokio::test]
695 async fn test_cluster_state_generation() {
696 let config = ClusterStateConfig::linear(3, 1.0);
697 let mut generator = ClusterStateGenerator::new(config);
698
699 let state = generator
700 .generate_cluster_state()
701 .await
702 .expect("Cluster state generation should succeed");
703 assert_eq!(state.num_modes, 3);
704
705 let stats = generator.get_generation_statistics();
706 assert!(stats.total_entangling_gates > 0);
707 assert!(stats.generation_fidelity > 0.0);
708 }
709
710 #[tokio::test]
711 async fn test_mbqc_measurement() {
712 let config = ClusterStateConfig::linear(3, 1.0);
713 let mut generator = ClusterStateGenerator::new(config);
714 generator
715 .generate_cluster_state()
716 .await
717 .expect("Cluster state generation should succeed");
718
719 let measurements = vec![MBQCMeasurement {
720 mode: 0,
721 measurement_type: MBQCMeasurementType::Homodyne { phase: 0.0 },
722 is_adaptive: false,
723 }];
724
725 let results = generator
726 .perform_mbqc_sequence(measurements)
727 .await
728 .expect("MBQC sequence should succeed");
729 assert_eq!(results.len(), 1);
730 assert_eq!(results[0].success_probability, 1.0);
731 }
732
733 #[test]
734 fn test_cluster_validation() {
735 let config = ClusterStateConfig::linear(2, 1.0);
736 let generator = ClusterStateGenerator::new(config);
737
738 assert!(generator.validate_cluster_state().is_err());
740 }
741
742 #[test]
743 fn test_feedforward_calculation() {
744 let config = ClusterStateConfig::linear(3, 1.0);
745 let generator = ClusterStateGenerator::new(config);
746
747 let measurement = MBQCMeasurement {
748 mode: 1,
749 measurement_type: MBQCMeasurementType::Homodyne { phase: 0.0 },
750 is_adaptive: false,
751 };
752
753 let corrections = generator.calculate_feedforward(&measurement, 1.0);
754 assert_eq!(corrections.len(), 2); }
756}