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