1use crate::{CircuitExecutor, CircuitResult, DeviceError, DeviceResult, QuantumDevice};
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10use std::f64::consts::PI;
11use std::time::Duration;
12
13pub mod cluster_states;
14pub mod cv_gates;
15pub mod error_correction;
16pub mod gaussian_states;
17pub mod heterodyne;
18pub mod homodyne;
19pub mod measurements;
20
21pub use cluster_states::*;
22pub use cv_gates::*;
23pub use error_correction::*;
24pub use gaussian_states::*;
25pub use heterodyne::*;
26pub use homodyne::*;
27pub use measurements::*;
28
29#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
31pub struct Complex {
32 pub real: f64,
33 pub imag: f64,
34}
35
36impl Complex {
37 pub const fn new(real: f64, imag: f64) -> Self {
38 Self { real, imag }
39 }
40
41 pub const fn zero() -> Self {
42 Self {
43 real: 0.0,
44 imag: 0.0,
45 }
46 }
47
48 pub const fn one() -> Self {
49 Self {
50 real: 1.0,
51 imag: 0.0,
52 }
53 }
54
55 pub const fn i() -> Self {
56 Self {
57 real: 0.0,
58 imag: 1.0,
59 }
60 }
61
62 pub fn magnitude(&self) -> f64 {
63 self.real.hypot(self.imag)
64 }
65
66 pub fn phase(&self) -> f64 {
67 self.imag.atan2(self.real)
68 }
69
70 #[must_use]
71 pub fn conjugate(&self) -> Self {
72 Self {
73 real: self.real,
74 imag: -self.imag,
75 }
76 }
77}
78
79impl std::ops::Add for Complex {
80 type Output = Self;
81 fn add(self, other: Self) -> Self {
82 Self {
83 real: self.real + other.real,
84 imag: self.imag + other.imag,
85 }
86 }
87}
88
89impl std::ops::Mul for Complex {
90 type Output = Self;
91 fn mul(self, other: Self) -> Self {
92 Self {
93 real: self.real.mul_add(other.real, -(self.imag * other.imag)),
94 imag: self.real.mul_add(other.imag, self.imag * other.real),
95 }
96 }
97}
98
99impl std::ops::Mul<f64> for Complex {
100 type Output = Self;
101 fn mul(self, scalar: f64) -> Self {
102 Self {
103 real: self.real * scalar,
104 imag: self.imag * scalar,
105 }
106 }
107}
108
109#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
111pub enum CVSystemType {
112 GaussianStates,
114 ClusterState,
116 MeasurementBased,
118 HybridDvCv,
120}
121
122pub struct CVQuantumDevice {
124 pub system_type: CVSystemType,
126 pub num_modes: usize,
128 pub mode_frequencies: Vec<f64>,
130 pub gaussian_state: GaussianState,
132 pub config: CVDeviceConfig,
134 pub is_connected: bool,
136 pub measurement_history: Vec<CVMeasurementResult>,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct CVDeviceConfig {
143 pub max_squeezing_db: f64,
145 pub optical_power_mw: f64,
147 pub detection_efficiency: f64,
149 pub electronic_noise_db: f64,
151 pub homodyne_bandwidth_hz: f64,
153 pub phase_noise: f64,
155 pub temperature_k: f64,
157 pub enable_error_correction: bool,
159}
160
161impl Default for CVDeviceConfig {
162 fn default() -> Self {
163 Self {
164 max_squeezing_db: 15.0,
165 optical_power_mw: 1.0,
166 detection_efficiency: 0.95,
167 electronic_noise_db: -90.0,
168 homodyne_bandwidth_hz: 10e6,
169 phase_noise: 1e-6,
170 temperature_k: 0.1,
171 enable_error_correction: true,
172 }
173 }
174}
175
176impl CVQuantumDevice {
177 pub fn new(
179 system_type: CVSystemType,
180 num_modes: usize,
181 config: CVDeviceConfig,
182 ) -> DeviceResult<Self> {
183 let mode_frequencies = (0..num_modes)
184 .map(|i| (i as f64).mul_add(1e12, 1e14)) .collect();
186
187 let gaussian_state = GaussianState::vacuum_state(num_modes);
188
189 Ok(Self {
190 system_type,
191 num_modes,
192 mode_frequencies,
193 gaussian_state,
194 config,
195 is_connected: false,
196 measurement_history: Vec::new(),
197 })
198 }
199
200 pub async fn connect(&mut self) -> DeviceResult<()> {
202 tokio::time::sleep(Duration::from_millis(200)).await;
204
205 self.initialize_optical_system().await?;
207
208 self.is_connected = true;
209 Ok(())
210 }
211
212 async fn initialize_optical_system(&mut self) -> DeviceResult<()> {
214 for (i, &freq) in self.mode_frequencies.iter().enumerate() {
216 println!("Initializing mode {i} at frequency {freq:.2e} Hz");
217 }
218
219 println!("Initializing homodyne detection system");
221
222 println!("Initializing squeezing apparatus");
224
225 Ok(())
226 }
227
228 pub async fn disconnect(&mut self) -> DeviceResult<()> {
230 self.is_connected = false;
231 Ok(())
232 }
233
234 pub async fn displacement(
236 &mut self,
237 mode: usize,
238 amplitude: f64,
239 phase: f64,
240 ) -> DeviceResult<()> {
241 if mode >= self.num_modes {
242 return Err(DeviceError::InvalidInput(format!(
243 "Mode {} exceeds available modes {}",
244 mode, self.num_modes
245 )));
246 }
247
248 let displacement = Complex::new(amplitude * phase.cos(), amplitude * phase.sin());
249
250 self.gaussian_state.apply_displacement(mode, displacement)?;
251 Ok(())
252 }
253
254 pub async fn squeezing(
256 &mut self,
257 mode: usize,
258 squeezing_param: f64,
259 phase: f64,
260 ) -> DeviceResult<()> {
261 if mode >= self.num_modes {
262 return Err(DeviceError::InvalidInput(format!(
263 "Mode {} exceeds available modes {}",
264 mode, self.num_modes
265 )));
266 }
267
268 if squeezing_param.abs() > self.config.max_squeezing_db / 8.686 {
269 return Err(DeviceError::InvalidInput(format!(
270 "Squeezing parameter {squeezing_param} exceeds maximum"
271 )));
272 }
273
274 self.gaussian_state
275 .apply_squeezing(mode, squeezing_param, phase)?;
276 Ok(())
277 }
278
279 pub async fn two_mode_squeezing(
281 &mut self,
282 mode1: usize,
283 mode2: usize,
284 squeezing_param: f64,
285 phase: f64,
286 ) -> DeviceResult<()> {
287 if mode1 >= self.num_modes || mode2 >= self.num_modes {
288 return Err(DeviceError::InvalidInput(
289 "One or both modes exceed available modes".to_string(),
290 ));
291 }
292
293 self.gaussian_state
294 .apply_two_mode_squeezing(mode1, mode2, squeezing_param, phase)?;
295 Ok(())
296 }
297
298 pub async fn beamsplitter(
300 &mut self,
301 mode1: usize,
302 mode2: usize,
303 transmittance: f64,
304 phase: f64,
305 ) -> DeviceResult<()> {
306 if mode1 >= self.num_modes || mode2 >= self.num_modes {
307 return Err(DeviceError::InvalidInput(
308 "One or both modes exceed available modes".to_string(),
309 ));
310 }
311
312 if !(0.0..=1.0).contains(&transmittance) {
313 return Err(DeviceError::InvalidInput(
314 "Transmittance must be between 0 and 1".to_string(),
315 ));
316 }
317
318 self.gaussian_state
319 .apply_beamsplitter(mode1, mode2, transmittance, phase)?;
320 Ok(())
321 }
322
323 pub async fn phase_rotation(&mut self, mode: usize, phase: f64) -> DeviceResult<()> {
325 if mode >= self.num_modes {
326 return Err(DeviceError::InvalidInput(format!(
327 "Mode {} exceeds available modes {}",
328 mode, self.num_modes
329 )));
330 }
331
332 self.gaussian_state.apply_phase_rotation(mode, phase)?;
333 Ok(())
334 }
335
336 pub async fn homodyne_measurement(&mut self, mode: usize, phase: f64) -> DeviceResult<f64> {
338 if mode >= self.num_modes {
339 return Err(DeviceError::InvalidInput(format!(
340 "Mode {} exceeds available modes {}",
341 mode, self.num_modes
342 )));
343 }
344
345 let result = self
346 .gaussian_state
347 .homodyne_measurement(mode, phase, &self.config)?;
348
349 self.measurement_history.push(CVMeasurementResult {
350 mode,
351 measurement_type: CVMeasurementType::Homodyne { phase },
352 result: CVMeasurementOutcome::Real(result),
353 timestamp: std::time::SystemTime::now()
354 .duration_since(std::time::UNIX_EPOCH)
355 .unwrap_or_default()
356 .as_secs_f64(),
357 });
358
359 Ok(result)
360 }
361
362 pub async fn heterodyne_measurement(&mut self, mode: usize) -> DeviceResult<Complex> {
364 if mode >= self.num_modes {
365 return Err(DeviceError::InvalidInput(format!(
366 "Mode {} exceeds available modes {}",
367 mode, self.num_modes
368 )));
369 }
370
371 let result = self
372 .gaussian_state
373 .heterodyne_measurement(mode, &self.config)?;
374
375 self.measurement_history.push(CVMeasurementResult {
376 mode,
377 measurement_type: CVMeasurementType::Heterodyne,
378 result: CVMeasurementOutcome::Complex(result),
379 timestamp: std::time::SystemTime::now()
380 .duration_since(std::time::UNIX_EPOCH)
381 .unwrap_or_default()
382 .as_secs_f64(),
383 });
384
385 Ok(result)
386 }
387
388 pub async fn reset_mode(&mut self, mode: usize) -> DeviceResult<()> {
390 if mode >= self.num_modes {
391 return Err(DeviceError::InvalidInput(format!(
392 "Mode {} exceeds available modes {}",
393 mode, self.num_modes
394 )));
395 }
396
397 self.gaussian_state.reset_mode_to_vacuum(mode)?;
398 Ok(())
399 }
400
401 pub fn get_mode_state(&self, mode: usize) -> DeviceResult<CVModeState> {
403 if mode >= self.num_modes {
404 return Err(DeviceError::InvalidInput(format!(
405 "Mode {} exceeds available modes {}",
406 mode, self.num_modes
407 )));
408 }
409
410 self.gaussian_state.get_mode_state(mode)
411 }
412
413 pub fn get_entanglement_measures(&self) -> CVEntanglementMeasures {
415 self.gaussian_state.calculate_entanglement_measures()
416 }
417
418 pub async fn get_diagnostics(&self) -> CVDeviceDiagnostics {
420 CVDeviceDiagnostics {
421 is_connected: self.is_connected,
422 num_modes: self.num_modes,
423 total_measurements: self.measurement_history.len(),
424 average_squeezing: self.gaussian_state.calculate_average_squeezing(),
425 system_purity: self.gaussian_state.calculate_purity(),
426 entanglement_entropy: self.gaussian_state.calculate_entanglement_entropy(),
427 optical_power_mw: self.config.optical_power_mw,
428 detection_efficiency: self.config.detection_efficiency,
429 }
430 }
431}
432
433#[derive(Debug, Clone, Serialize, Deserialize)]
435pub enum CVMeasurementType {
436 Homodyne { phase: f64 },
438 Heterodyne,
440 PhotonNumber,
442 Parity,
444}
445
446#[derive(Debug, Clone, Serialize, Deserialize)]
448pub enum CVMeasurementOutcome {
449 Real(f64),
450 Complex(Complex),
451 Integer(i32),
452 Boolean(bool),
453}
454
455#[derive(Debug, Clone, Serialize, Deserialize)]
457pub struct CVMeasurementResult {
458 pub mode: usize,
459 pub measurement_type: CVMeasurementType,
460 pub result: CVMeasurementOutcome,
461 pub timestamp: f64,
462}
463
464#[derive(Debug, Clone, Serialize, Deserialize)]
466pub struct CVModeState {
467 pub mean_amplitude: Complex,
469 pub quadrature_variances: (f64, f64),
471 pub squeezing_parameter: f64,
473 pub squeezing_phase: f64,
475 pub purity: f64,
477}
478
479#[derive(Debug, Clone, Serialize, Deserialize)]
481pub struct CVEntanglementMeasures {
482 pub logarithmic_negativity: f64,
484 pub entanglement_of_formation: f64,
486 pub mutual_information: f64,
488 pub epr_correlation: f64,
490}
491
492#[derive(Debug, Clone, Serialize, Deserialize)]
494pub struct CVDeviceDiagnostics {
495 pub is_connected: bool,
496 pub num_modes: usize,
497 pub total_measurements: usize,
498 pub average_squeezing: f64,
499 pub system_purity: f64,
500 pub entanglement_entropy: f64,
501 pub optical_power_mw: f64,
502 pub detection_efficiency: f64,
503}
504
505#[async_trait::async_trait]
506impl QuantumDevice for CVQuantumDevice {
507 async fn is_available(&self) -> DeviceResult<bool> {
508 Ok(self.is_connected)
509 }
510
511 async fn qubit_count(&self) -> DeviceResult<usize> {
512 Ok(self.num_modes)
514 }
515
516 async fn properties(&self) -> DeviceResult<HashMap<String, String>> {
517 let mut props = HashMap::new();
518 props.insert("device_type".to_string(), "continuous_variable".to_string());
519 props.insert("system_type".to_string(), format!("{:?}", self.system_type));
520 props.insert("num_modes".to_string(), self.num_modes.to_string());
521 props.insert(
522 "max_squeezing_db".to_string(),
523 self.config.max_squeezing_db.to_string(),
524 );
525 props.insert(
526 "detection_efficiency".to_string(),
527 self.config.detection_efficiency.to_string(),
528 );
529 props.insert(
530 "optical_power_mw".to_string(),
531 self.config.optical_power_mw.to_string(),
532 );
533 Ok(props)
534 }
535
536 async fn is_simulator(&self) -> DeviceResult<bool> {
537 Ok(true) }
539}
540
541pub fn create_gaussian_cv_device(
543 num_modes: usize,
544 config: Option<CVDeviceConfig>,
545) -> DeviceResult<CVQuantumDevice> {
546 let config = config.unwrap_or_default();
547 CVQuantumDevice::new(CVSystemType::GaussianStates, num_modes, config)
548}
549
550pub fn create_cluster_state_cv_device(
552 num_modes: usize,
553 config: Option<CVDeviceConfig>,
554) -> DeviceResult<CVQuantumDevice> {
555 let config = config.unwrap_or_default();
556 CVQuantumDevice::new(CVSystemType::ClusterState, num_modes, config)
557}
558
559#[cfg(test)]
560mod tests {
561 use super::*;
562
563 #[tokio::test]
564 async fn test_cv_device_creation() {
565 let device = create_gaussian_cv_device(4, None).expect("Failed to create CV device");
566 assert_eq!(device.num_modes, 4);
567 assert_eq!(device.system_type, CVSystemType::GaussianStates);
568 }
569
570 #[tokio::test]
571 async fn test_cv_device_connection() {
572 let mut device = create_gaussian_cv_device(2, None).expect("Failed to create CV device");
573 assert!(!device.is_connected);
574
575 device.connect().await.expect("Failed to connect");
576 assert!(device.is_connected);
577
578 device.disconnect().await.expect("Failed to disconnect");
579 assert!(!device.is_connected);
580 }
581
582 #[tokio::test]
583 async fn test_displacement_operation() {
584 let mut device = create_gaussian_cv_device(2, None).expect("Failed to create CV device");
585 device.connect().await.expect("Failed to connect");
586
587 device
588 .displacement(0, 1.0, PI / 4.0)
589 .await
590 .expect("Failed to apply displacement");
591
592 let state = device.get_mode_state(0).expect("Failed to get mode state");
593 assert!(state.mean_amplitude.magnitude() > 0.0);
594 }
595
596 #[tokio::test]
597 async fn test_squeezing_operation() {
598 let mut device = create_gaussian_cv_device(2, None).expect("Failed to create CV device");
599 device.connect().await.expect("Failed to connect");
600
601 device
602 .squeezing(0, 1.0, 0.0)
603 .await
604 .expect("Failed to apply squeezing");
605
606 let state = device.get_mode_state(0).expect("Failed to get mode state");
607 assert!(state.squeezing_parameter > 0.0);
608 }
609
610 #[tokio::test]
611 async fn test_homodyne_measurement() {
612 let mut device = create_gaussian_cv_device(2, None).expect("Failed to create CV device");
613 device.connect().await.expect("Failed to connect");
614
615 device
617 .displacement(0, 2.0, 0.0)
618 .await
619 .expect("Failed to apply displacement");
620
621 let result = device
622 .homodyne_measurement(0, 0.0)
623 .await
624 .expect("Failed to perform homodyne measurement");
625 assert!(result.is_finite());
626
627 assert_eq!(device.measurement_history.len(), 1);
628 }
629
630 #[test]
631 fn test_complex_number_operations() {
632 let z1 = Complex::new(1.0, 2.0);
633 let z2 = Complex::new(3.0, 4.0);
634
635 let sum = z1 + z2;
636 assert_eq!(sum.real, 4.0);
637 assert_eq!(sum.imag, 6.0);
638
639 let product = z1 * z2;
640 assert_eq!(product.real, -5.0);
641 assert_eq!(product.imag, 10.0);
642
643 assert!((z1.magnitude() - (5.0_f64).sqrt()).abs() < 1e-10);
644 }
645}