1use super::{Complex, GaussianState};
7use crate::{DeviceError, DeviceResult};
8use serde::{Deserialize, Serialize};
9use std::f64::consts::PI;
10
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub enum CVGateType {
14 Displacement { amplitude: Complex },
16 Squeezing { parameter: f64, phase: f64 },
18 TwoModeSqueezing { parameter: f64, phase: f64 },
20 Beamsplitter { transmittance: f64, phase: f64 },
22 PhaseRotation { phase: f64 },
24 ControlledDisplacement { amplitude: Complex },
26 ControlledPhase { parameter: f64 },
28 CrossKerr { parameter: f64 },
30 CubicPhase { parameter: f64 },
32 PositionMeasurement { result: f64 },
34 MomentumMeasurement { result: f64 },
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct CVGateParams {
41 pub real_params: Vec<f64>,
43 pub complex_params: Vec<Complex>,
45 pub target_modes: Vec<usize>,
47 pub control_modes: Vec<usize>,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct CVGateSequence {
54 pub gates: Vec<(CVGateType, CVGateParams)>,
56 pub num_modes: usize,
58}
59
60impl CVGateSequence {
61 pub const fn new(num_modes: usize) -> Self {
63 Self {
64 gates: Vec::new(),
65 num_modes,
66 }
67 }
68
69 pub fn displacement(&mut self, mode: usize, amplitude: Complex) -> DeviceResult<()> {
71 if mode >= self.num_modes {
72 return Err(DeviceError::InvalidInput(format!(
73 "Mode {mode} exceeds sequence capacity"
74 )));
75 }
76
77 self.gates.push((
78 CVGateType::Displacement { amplitude },
79 CVGateParams {
80 real_params: vec![amplitude.real, amplitude.imag],
81 complex_params: vec![amplitude],
82 target_modes: vec![mode],
83 control_modes: vec![],
84 },
85 ));
86
87 Ok(())
88 }
89
90 pub fn squeezing(&mut self, mode: usize, parameter: f64, phase: f64) -> DeviceResult<()> {
92 if mode >= self.num_modes {
93 return Err(DeviceError::InvalidInput(format!(
94 "Mode {mode} exceeds sequence capacity"
95 )));
96 }
97
98 self.gates.push((
99 CVGateType::Squeezing { parameter, phase },
100 CVGateParams {
101 real_params: vec![parameter, phase],
102 complex_params: vec![],
103 target_modes: vec![mode],
104 control_modes: vec![],
105 },
106 ));
107
108 Ok(())
109 }
110
111 pub fn two_mode_squeezing(
113 &mut self,
114 mode1: usize,
115 mode2: usize,
116 parameter: f64,
117 phase: f64,
118 ) -> DeviceResult<()> {
119 if mode1 >= self.num_modes || mode2 >= self.num_modes {
120 return Err(DeviceError::InvalidInput(
121 "One or both modes exceed sequence capacity".to_string(),
122 ));
123 }
124
125 self.gates.push((
126 CVGateType::TwoModeSqueezing { parameter, phase },
127 CVGateParams {
128 real_params: vec![parameter, phase],
129 complex_params: vec![],
130 target_modes: vec![mode1, mode2],
131 control_modes: vec![],
132 },
133 ));
134
135 Ok(())
136 }
137
138 pub fn beamsplitter(
140 &mut self,
141 mode1: usize,
142 mode2: usize,
143 transmittance: f64,
144 phase: f64,
145 ) -> DeviceResult<()> {
146 if mode1 >= self.num_modes || mode2 >= self.num_modes {
147 return Err(DeviceError::InvalidInput(
148 "One or both modes exceed sequence capacity".to_string(),
149 ));
150 }
151
152 if !(0.0..=1.0).contains(&transmittance) {
153 return Err(DeviceError::InvalidInput(
154 "Transmittance must be between 0 and 1".to_string(),
155 ));
156 }
157
158 self.gates.push((
159 CVGateType::Beamsplitter {
160 transmittance,
161 phase,
162 },
163 CVGateParams {
164 real_params: vec![transmittance, phase],
165 complex_params: vec![],
166 target_modes: vec![mode1, mode2],
167 control_modes: vec![],
168 },
169 ));
170
171 Ok(())
172 }
173
174 pub fn phase_rotation(&mut self, mode: usize, phase: f64) -> DeviceResult<()> {
176 if mode >= self.num_modes {
177 return Err(DeviceError::InvalidInput(format!(
178 "Mode {mode} exceeds sequence capacity"
179 )));
180 }
181
182 self.gates.push((
183 CVGateType::PhaseRotation { phase },
184 CVGateParams {
185 real_params: vec![phase],
186 complex_params: vec![],
187 target_modes: vec![mode],
188 control_modes: vec![],
189 },
190 ));
191
192 Ok(())
193 }
194
195 pub fn controlled_displacement(
197 &mut self,
198 control_mode: usize,
199 target_mode: usize,
200 amplitude: Complex,
201 ) -> DeviceResult<()> {
202 if control_mode >= self.num_modes || target_mode >= self.num_modes {
203 return Err(DeviceError::InvalidInput(
204 "Control or target mode exceeds sequence capacity".to_string(),
205 ));
206 }
207
208 self.gates.push((
209 CVGateType::ControlledDisplacement { amplitude },
210 CVGateParams {
211 real_params: vec![amplitude.real, amplitude.imag],
212 complex_params: vec![amplitude],
213 target_modes: vec![target_mode],
214 control_modes: vec![control_mode],
215 },
216 ));
217
218 Ok(())
219 }
220
221 pub fn controlled_phase(
223 &mut self,
224 control_mode: usize,
225 target_mode: usize,
226 parameter: f64,
227 ) -> DeviceResult<()> {
228 if control_mode >= self.num_modes || target_mode >= self.num_modes {
229 return Err(DeviceError::InvalidInput(
230 "Control or target mode exceeds sequence capacity".to_string(),
231 ));
232 }
233
234 self.gates.push((
235 CVGateType::ControlledPhase { parameter },
236 CVGateParams {
237 real_params: vec![parameter],
238 complex_params: vec![],
239 target_modes: vec![target_mode],
240 control_modes: vec![control_mode],
241 },
242 ));
243
244 Ok(())
245 }
246
247 pub fn cross_kerr(&mut self, mode1: usize, mode2: usize, parameter: f64) -> DeviceResult<()> {
249 if mode1 >= self.num_modes || mode2 >= self.num_modes {
250 return Err(DeviceError::InvalidInput(
251 "One or both modes exceed sequence capacity".to_string(),
252 ));
253 }
254
255 self.gates.push((
256 CVGateType::CrossKerr { parameter },
257 CVGateParams {
258 real_params: vec![parameter],
259 complex_params: vec![],
260 target_modes: vec![mode1, mode2],
261 control_modes: vec![],
262 },
263 ));
264
265 Ok(())
266 }
267
268 pub fn cubic_phase(&mut self, mode: usize, parameter: f64) -> DeviceResult<()> {
270 if mode >= self.num_modes {
271 return Err(DeviceError::InvalidInput(format!(
272 "Mode {mode} exceeds sequence capacity"
273 )));
274 }
275
276 self.gates.push((
277 CVGateType::CubicPhase { parameter },
278 CVGateParams {
279 real_params: vec![parameter],
280 complex_params: vec![],
281 target_modes: vec![mode],
282 control_modes: vec![],
283 },
284 ));
285
286 Ok(())
287 }
288
289 pub fn gate_count(&self) -> usize {
291 self.gates.len()
292 }
293
294 pub fn depth(&self) -> usize {
296 let mut mode_depths = vec![0; self.num_modes];
297
298 for (_, params) in &self.gates {
299 for &mode in ¶ms.target_modes {
300 mode_depths[mode] += 1;
301 }
302 for &mode in ¶ms.control_modes {
303 mode_depths[mode] += 1;
304 }
305 }
306
307 *mode_depths.iter().max().unwrap_or(&0)
308 }
309
310 pub fn is_gaussian(&self) -> bool {
312 for (gate_type, _) in &self.gates {
313 match gate_type {
314 CVGateType::CubicPhase { .. }
315 | CVGateType::PositionMeasurement { .. }
316 | CVGateType::MomentumMeasurement { .. } => return false,
317 _ => continue,
318 }
319 }
320 true
321 }
322
323 pub fn execute_on_state(&self, state: &mut GaussianState) -> DeviceResult<()> {
325 if state.num_modes != self.num_modes {
326 return Err(DeviceError::InvalidInput(
327 "State mode count doesn't match sequence requirements".to_string(),
328 ));
329 }
330
331 for (gate_type, params) in &self.gates {
332 self.execute_single_gate(gate_type, params, state)?;
333 }
334
335 Ok(())
336 }
337
338 fn execute_single_gate(
340 &self,
341 gate_type: &CVGateType,
342 params: &CVGateParams,
343 state: &mut GaussianState,
344 ) -> DeviceResult<()> {
345 match gate_type {
346 CVGateType::Displacement { amplitude } => {
347 if params.target_modes.len() != 1 {
348 return Err(DeviceError::InvalidInput(
349 "Displacement gate requires exactly one target mode".to_string(),
350 ));
351 }
352 state.apply_displacement(params.target_modes[0], *amplitude)?;
353 }
354
355 CVGateType::Squeezing { parameter, phase } => {
356 if params.target_modes.len() != 1 {
357 return Err(DeviceError::InvalidInput(
358 "Squeezing gate requires exactly one target mode".to_string(),
359 ));
360 }
361 state.apply_squeezing(params.target_modes[0], *parameter, *phase)?;
362 }
363
364 CVGateType::TwoModeSqueezing { parameter, phase } => {
365 if params.target_modes.len() != 2 {
366 return Err(DeviceError::InvalidInput(
367 "Two-mode squeezing gate requires exactly two target modes".to_string(),
368 ));
369 }
370 state.apply_two_mode_squeezing(
371 params.target_modes[0],
372 params.target_modes[1],
373 *parameter,
374 *phase,
375 )?;
376 }
377
378 CVGateType::Beamsplitter {
379 transmittance,
380 phase,
381 } => {
382 if params.target_modes.len() != 2 {
383 return Err(DeviceError::InvalidInput(
384 "Beamsplitter gate requires exactly two target modes".to_string(),
385 ));
386 }
387 state.apply_beamsplitter(
388 params.target_modes[0],
389 params.target_modes[1],
390 *transmittance,
391 *phase,
392 )?;
393 }
394
395 CVGateType::PhaseRotation { phase } => {
396 if params.target_modes.len() != 1 {
397 return Err(DeviceError::InvalidInput(
398 "Phase rotation gate requires exactly one target mode".to_string(),
399 ));
400 }
401 state.apply_phase_rotation(params.target_modes[0], *phase)?;
402 }
403
404 CVGateType::ControlledDisplacement { amplitude } => {
405 if params.control_modes.len() != 1 || params.target_modes.len() != 1 {
406 return Err(DeviceError::InvalidInput(
407 "Controlled displacement requires one control and one target mode"
408 .to_string(),
409 ));
410 }
411 self.apply_controlled_displacement(
412 params.control_modes[0],
413 params.target_modes[0],
414 *amplitude,
415 state,
416 )?;
417 }
418
419 CVGateType::ControlledPhase { parameter } => {
420 if params.control_modes.len() != 1 || params.target_modes.len() != 1 {
421 return Err(DeviceError::InvalidInput(
422 "Controlled phase requires one control and one target mode".to_string(),
423 ));
424 }
425 self.apply_controlled_phase(
426 params.control_modes[0],
427 params.target_modes[0],
428 *parameter,
429 state,
430 )?;
431 }
432
433 CVGateType::CrossKerr { parameter } => {
434 if params.target_modes.len() != 2 {
435 return Err(DeviceError::InvalidInput(
436 "Cross-Kerr gate requires exactly two target modes".to_string(),
437 ));
438 }
439 self.apply_cross_kerr(
440 params.target_modes[0],
441 params.target_modes[1],
442 *parameter,
443 state,
444 )?;
445 }
446
447 CVGateType::CubicPhase { parameter } => {
448 return Err(DeviceError::UnsupportedOperation(
449 "Cubic phase gate is non-Gaussian and not supported for Gaussian states"
450 .to_string(),
451 ));
452 }
453
454 CVGateType::PositionMeasurement { .. } | CVGateType::MomentumMeasurement { .. } => {
455 return Err(DeviceError::UnsupportedOperation(
456 "Measurements should be performed separately from gate sequences".to_string(),
457 ));
458 }
459 }
460
461 Ok(())
462 }
463
464 fn apply_controlled_displacement(
466 &self,
467 control_mode: usize,
468 target_mode: usize,
469 amplitude: Complex,
470 state: &mut GaussianState,
471 ) -> DeviceResult<()> {
472 let control_amplitude = Complex::new(
475 state.mean_vector[2 * control_mode] / (2.0_f64).sqrt(),
476 state.mean_vector[2 * control_mode + 1] / (2.0_f64).sqrt(),
477 );
478
479 let scaled_amplitude = amplitude * control_amplitude.magnitude();
480 state.apply_displacement(target_mode, scaled_amplitude)?;
481
482 Ok(())
483 }
484
485 fn apply_controlled_phase(
487 &self,
488 control_mode: usize,
489 target_mode: usize,
490 parameter: f64,
491 state: &mut GaussianState,
492 ) -> DeviceResult<()> {
493 let control_photon_number = self.estimate_photon_number(control_mode, state);
495 let phase = parameter * control_photon_number;
496 state.apply_phase_rotation(target_mode, phase)?;
497
498 Ok(())
499 }
500
501 fn apply_cross_kerr(
503 &self,
504 mode1: usize,
505 mode2: usize,
506 parameter: f64,
507 state: &mut GaussianState,
508 ) -> DeviceResult<()> {
509 let n1 = self.estimate_photon_number(mode1, state);
512 let n2 = self.estimate_photon_number(mode2, state);
513
514 state.apply_phase_rotation(mode1, parameter * n2)?;
515 state.apply_phase_rotation(mode2, parameter * n1)?;
516
517 Ok(())
518 }
519
520 fn estimate_photon_number(&self, mode: usize, state: &GaussianState) -> f64 {
522 let mean_x = state.mean_vector[2 * mode];
523 let mean_p = state.mean_vector[2 * mode + 1];
524 let var_x = state.covariancematrix[2 * mode][2 * mode];
525 let var_p = state.covariancematrix[2 * mode + 1][2 * mode + 1];
526
527 0.5 * (mean_p.mul_add(mean_p, mean_x.powi(2)) / 2.0 + (var_x + var_p) - 1.0)
529 }
530}
531
532pub struct CVGateLibrary;
534
535impl CVGateLibrary {
536 pub fn displacement(amplitude: Complex) -> (CVGateType, CVGateParams) {
538 (
539 CVGateType::Displacement { amplitude },
540 CVGateParams {
541 real_params: vec![amplitude.real, amplitude.imag],
542 complex_params: vec![amplitude],
543 target_modes: vec![],
544 control_modes: vec![],
545 },
546 )
547 }
548
549 pub fn squeezing(parameter: f64, phase: f64) -> (CVGateType, CVGateParams) {
551 (
552 CVGateType::Squeezing { parameter, phase },
553 CVGateParams {
554 real_params: vec![parameter, phase],
555 complex_params: vec![],
556 target_modes: vec![],
557 control_modes: vec![],
558 },
559 )
560 }
561
562 pub fn balanced_beamsplitter() -> (CVGateType, CVGateParams) {
564 (
565 CVGateType::Beamsplitter {
566 transmittance: 0.5,
567 phase: 0.0,
568 },
569 CVGateParams {
570 real_params: vec![0.5, 0.0],
571 complex_params: vec![],
572 target_modes: vec![],
573 control_modes: vec![],
574 },
575 )
576 }
577
578 pub fn fourier_transform() -> CVGateSequence {
580 let mut sequence = CVGateSequence::new(1);
581 sequence
582 .phase_rotation(0, PI / 2.0)
583 .expect("Phase rotation on mode 0 should always succeed for single-mode sequence");
584 sequence
585 }
586
587 pub fn cv_cnot() -> CVGateSequence {
589 let mut sequence = CVGateSequence::new(2);
590 sequence
592 .beamsplitter(0, 1, 0.5, 0.0)
593 .expect("Beamsplitter on modes 0,1 should always succeed for two-mode sequence");
594 sequence
595 .phase_rotation(1, PI)
596 .expect("Phase rotation on mode 1 should always succeed for two-mode sequence");
597 sequence
598 .beamsplitter(0, 1, 0.5, 0.0)
599 .expect("Beamsplitter on modes 0,1 should always succeed for two-mode sequence");
600 sequence
601 }
602
603 pub fn epr_pair_generation(squeezing_param: f64) -> CVGateSequence {
605 let mut sequence = CVGateSequence::new(2);
606 sequence
607 .two_mode_squeezing(0, 1, squeezing_param, 0.0)
608 .expect("Two-mode squeezing on modes 0,1 should always succeed for two-mode sequence");
609 sequence
610 }
611
612 pub fn gkp_state_preparation() -> CVGateSequence {
614 let mut sequence = CVGateSequence::new(1);
615 for i in 0..10 {
617 let phase = 2.0 * PI * i as f64 / 10.0;
618 sequence
619 .squeezing(0, 0.5, phase)
620 .expect("Squeezing on mode 0 should always succeed for single-mode sequence");
621 }
622 sequence
623 }
624}
625
626#[cfg(test)]
627mod tests {
628 use super::*;
629
630 #[test]
631 fn test_gate_sequence_creation() {
632 let mut sequence = CVGateSequence::new(3);
633 assert_eq!(sequence.num_modes, 3);
634 assert_eq!(sequence.gate_count(), 0);
635 }
636
637 #[test]
638 fn test_displacement_gate_addition() {
639 let mut sequence = CVGateSequence::new(2);
640 let amplitude = Complex::new(1.0, 0.5);
641
642 sequence
643 .displacement(0, amplitude)
644 .expect("Failed to add displacement gate");
645 assert_eq!(sequence.gate_count(), 1);
646
647 match &sequence.gates[0].0 {
648 CVGateType::Displacement { amplitude: a } => {
649 assert_eq!(*a, amplitude);
650 }
651 _ => panic!("Expected displacement gate"),
652 }
653 }
654
655 #[test]
656 fn test_beamsplitter_gate_addition() {
657 let mut sequence = CVGateSequence::new(2);
658
659 sequence
660 .beamsplitter(0, 1, 0.7, PI / 4.0)
661 .expect("Failed to add beamsplitter gate");
662 assert_eq!(sequence.gate_count(), 1);
663
664 match &sequence.gates[0].0 {
665 CVGateType::Beamsplitter {
666 transmittance,
667 phase,
668 } => {
669 assert_eq!(*transmittance, 0.7);
670 assert_eq!(*phase, PI / 4.0);
671 }
672 _ => panic!("Expected beamsplitter gate"),
673 }
674 }
675
676 #[test]
677 fn test_gaussian_property() {
678 let mut sequence = CVGateSequence::new(2);
679
680 sequence
681 .displacement(0, Complex::new(1.0, 0.0))
682 .expect("Failed to add displacement gate");
683 sequence
684 .squeezing(1, 0.5, 0.0)
685 .expect("Failed to add squeezing gate");
686 sequence
687 .beamsplitter(0, 1, 0.5, 0.0)
688 .expect("Failed to add beamsplitter gate");
689
690 assert!(sequence.is_gaussian());
691
692 sequence
693 .cubic_phase(0, 0.1)
694 .expect("Failed to add cubic phase gate");
695 assert!(!sequence.is_gaussian());
696 }
697
698 #[test]
699 fn test_sequence_depth_calculation() {
700 let mut sequence = CVGateSequence::new(3);
701
702 sequence
703 .displacement(0, Complex::new(1.0, 0.0))
704 .expect("Failed to add first displacement gate");
705 sequence
706 .displacement(0, Complex::new(0.5, 0.0))
707 .expect("Failed to add second displacement gate");
708 sequence
709 .squeezing(1, 0.5, 0.0)
710 .expect("Failed to add squeezing gate");
711 sequence
712 .beamsplitter(0, 2, 0.5, 0.0)
713 .expect("Failed to add beamsplitter gate");
714
715 assert_eq!(sequence.depth(), 3); }
717
718 #[test]
719 fn test_gate_execution_on_state() {
720 let mut sequence = CVGateSequence::new(2);
721 sequence
722 .displacement(0, Complex::new(1.0, 0.0))
723 .expect("Failed to add displacement gate");
724 sequence
725 .squeezing(1, 0.5, 0.0)
726 .expect("Failed to add squeezing gate");
727
728 let mut state = GaussianState::vacuum_state(2);
729 sequence
730 .execute_on_state(&mut state)
731 .expect("Failed to execute gate sequence on state");
732
733 assert!(state.mean_vector[0] > 0.0);
735
736 assert!(state.covariancematrix[2][2] < 0.5);
740 }
741
742 #[test]
743 fn test_epr_pair_generation() {
744 let sequence = CVGateLibrary::epr_pair_generation(1.0);
745 assert_eq!(sequence.gate_count(), 1);
746
747 let mut state = GaussianState::vacuum_state(2);
748 sequence
749 .execute_on_state(&mut state)
750 .expect("Failed to execute EPR pair generation sequence");
751
752 let entanglement = state.calculate_entanglement_measures();
754 assert!(entanglement.epr_correlation > 0.0);
755 }
756
757 #[test]
758 fn test_balanced_beamsplitter() {
759 let (gate_type, params) = CVGateLibrary::balanced_beamsplitter();
760
761 match gate_type {
762 CVGateType::Beamsplitter {
763 transmittance,
764 phase,
765 } => {
766 assert_eq!(transmittance, 0.5);
767 assert_eq!(phase, 0.0);
768 }
769 _ => panic!("Expected balanced beamsplitter"),
770 }
771 }
772
773 #[test]
774 fn test_invalid_mode_error() {
775 let mut sequence = CVGateSequence::new(2);
776
777 let result = sequence.displacement(3, Complex::new(1.0, 0.0));
778 assert!(result.is_err());
779
780 let result = sequence.beamsplitter(0, 3, 0.5, 0.0);
781 assert!(result.is_err());
782 }
783}