1use crate::prelude::SimulatorError;
9use ndarray::{Array1, Array2};
10use num_complex::Complex64;
11use scirs2_core::parallel_ops::*;
12use serde::{Deserialize, Serialize};
13use std::collections::HashMap;
14
15use crate::error::Result;
16use crate::scirs2_integration::SciRS2Backend;
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum PhotonicMethod {
21 FockBasis,
23 CoherentBasis,
25 WignerFunction,
27 SciRS2Continuous,
29 TruncatedFock,
31}
32
33#[derive(Debug, Clone)]
35pub struct PhotonicConfig {
36 pub method: PhotonicMethod,
38 pub max_photon_number: usize,
40 pub num_modes: usize,
42 pub precision: f64,
44 pub parallel: bool,
46 pub wigner_grid_size: usize,
48 pub phase_space_range: f64,
50}
51
52impl Default for PhotonicConfig {
53 fn default() -> Self {
54 Self {
55 method: PhotonicMethod::FockBasis,
56 max_photon_number: 20,
57 num_modes: 1,
58 precision: 1e-12,
59 parallel: true,
60 wigner_grid_size: 100,
61 phase_space_range: 5.0,
62 }
63 }
64}
65
66#[derive(Debug, Clone)]
68pub enum PhotonicState {
69 Fock(Array1<Complex64>),
71 Coherent {
73 amplitudes: Vec<Complex64>,
74 basis_states: Vec<FockState>,
75 },
76 Squeezed {
78 amplitudes: Vec<Complex64>,
79 squeezing_params: Vec<Complex64>,
80 basis_states: Vec<FockState>,
81 },
82 Wigner {
84 function_values: Array2<Complex64>,
85 q_grid: Array1<f64>,
86 p_grid: Array1<f64>,
87 },
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, Hash)]
92pub struct FockState {
93 pub photon_numbers: Vec<usize>,
95}
96
97impl FockState {
98 pub fn new(photon_numbers: Vec<usize>) -> Self {
100 Self { photon_numbers }
101 }
102
103 pub fn vacuum(num_modes: usize) -> Self {
105 Self::new(vec![0; num_modes])
106 }
107
108 pub fn single_photon(mode: usize, num_modes: usize) -> Self {
110 let mut photon_numbers = vec![0; num_modes];
111 photon_numbers[mode] = 1;
112 Self::new(photon_numbers)
113 }
114
115 pub fn total_photons(&self) -> usize {
117 self.photon_numbers.iter().sum()
118 }
119
120 pub fn photons_in_mode(&self, mode: usize) -> usize {
122 self.photon_numbers.get(mode).copied().unwrap_or(0)
123 }
124}
125
126#[derive(Debug, Clone)]
128pub enum PhotonicOperator {
129 Creation(usize), Annihilation(usize), Number(usize), Displacement(usize, Complex64), Squeezing(usize, Complex64), BeamSplitter(usize, usize, f64), PhaseShift(usize, f64), Kerr(usize, f64), }
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct PhotonicResult {
150 pub final_state: Vec<Complex64>,
152 pub expectation_values: HashMap<String, Complex64>,
154 pub photon_distribution: Vec<f64>,
156 pub stats: PhotonicStats,
158}
159
160#[derive(Debug, Clone, Default, Serialize, Deserialize)]
162pub struct PhotonicStats {
163 pub execution_time_ms: f64,
165 pub memory_usage_bytes: usize,
167 pub basis_states_count: usize,
169 pub max_photons_used: usize,
171 pub fidelity: f64,
173 pub method_used: String,
175}
176
177pub struct PhotonicSimulator {
179 config: PhotonicConfig,
181 state: PhotonicState,
183 backend: Option<SciRS2Backend>,
185 basis_cache: HashMap<FockState, usize>,
187 operator_cache: HashMap<String, Array2<Complex64>>,
189}
190
191impl PhotonicSimulator {
192 pub fn new(config: PhotonicConfig) -> Result<Self> {
194 let state = PhotonicState::Fock(Array1::zeros(1));
195
196 Ok(Self {
197 config,
198 state,
199 backend: None,
200 basis_cache: HashMap::new(),
201 operator_cache: HashMap::new(),
202 })
203 }
204
205 pub fn with_backend(mut self) -> Result<Self> {
207 self.backend = Some(SciRS2Backend::new());
208 Ok(self)
209 }
210
211 pub fn initialize_vacuum(&mut self) -> Result<()> {
213 match self.config.method {
214 PhotonicMethod::FockBasis => {
215 let dim = self.calculate_fock_dimension()?;
216 let mut state_vector = Array1::zeros(dim);
217 state_vector[0] = Complex64::new(1.0, 0.0); self.state = PhotonicState::Fock(state_vector);
219 }
220 PhotonicMethod::CoherentBasis => {
221 let vacuum = FockState::vacuum(self.config.num_modes);
222 self.state = PhotonicState::Coherent {
223 amplitudes: vec![Complex64::new(1.0, 0.0)],
224 basis_states: vec![vacuum],
225 };
226 }
227 PhotonicMethod::WignerFunction => {
228 let grid_size = self.config.wigner_grid_size;
229 let function_values = Array2::zeros((grid_size, grid_size));
230 let range = self.config.phase_space_range;
231 let q_grid = Array1::linspace(-range, range, grid_size);
232 let p_grid = Array1::linspace(-range, range, grid_size);
233
234 self.state = PhotonicState::Wigner {
235 function_values,
236 q_grid,
237 p_grid,
238 };
239 }
240 _ => {
241 let dim = self.calculate_fock_dimension()?;
242 let mut state_vector = Array1::zeros(dim);
243 state_vector[0] = Complex64::new(1.0, 0.0);
244 self.state = PhotonicState::Fock(state_vector);
245 }
246 }
247
248 Ok(())
249 }
250
251 pub fn initialize_coherent_state(&mut self, alpha: Complex64, mode: usize) -> Result<()> {
253 match self.config.method {
254 PhotonicMethod::FockBasis | PhotonicMethod::TruncatedFock => {
255 let dim = self.calculate_fock_dimension()?;
256 let mut state_vector = Array1::zeros(dim);
257
258 let displacement_factor = (-alpha.norm_sqr() / 2.0).exp();
260
261 let fock_states = self.enumerate_fock_states()?;
263 for (i, fock_state) in fock_states.iter().enumerate() {
264 if i >= dim {
265 break;
266 }
267
268 let n = fock_state.photons_in_mode(mode);
269 let amplitude =
270 displacement_factor * alpha.powu(n as u32) / Self::factorial(n).sqrt();
271 state_vector[i] = amplitude;
272 }
273
274 let norm = state_vector
276 .iter()
277 .map(|x| x.norm_sqr())
278 .sum::<f64>()
279 .sqrt();
280 if norm > 1e-15 {
281 for amp in state_vector.iter_mut() {
282 *amp /= norm;
283 }
284 }
285
286 self.state = PhotonicState::Fock(state_vector);
287 }
288 PhotonicMethod::CoherentBasis => {
289 let vacuum = FockState::vacuum(self.config.num_modes);
290 self.state = PhotonicState::Coherent {
291 amplitudes: vec![alpha],
292 basis_states: vec![vacuum],
293 };
294 }
295 PhotonicMethod::WignerFunction => {
296 self.initialize_coherent_wigner(alpha, mode)?;
297 }
298 PhotonicMethod::SciRS2Continuous => {
299 self.initialize_coherent_scirs2(alpha, mode)?;
300 }
301 }
302
303 Ok(())
304 }
305
306 pub fn initialize_squeezed_state(&mut self, xi: Complex64, mode: usize) -> Result<()> {
308 let r = xi.norm();
309 let phi = xi.arg();
310
311 match self.config.method {
312 PhotonicMethod::FockBasis | PhotonicMethod::TruncatedFock => {
313 let dim = self.calculate_fock_dimension()?;
314 let mut state_vector = Array1::zeros(dim);
315
316 let fock_states = self.enumerate_fock_states()?;
318 for (i, fock_state) in fock_states.iter().enumerate() {
319 if i >= dim {
320 break;
321 }
322
323 let n = fock_state.photons_in_mode(mode);
324 if n % 2 == 0 {
325 let amplitude = self.calculate_squeezed_amplitude(n, r, phi);
327 state_vector[i] = amplitude;
328 }
329 }
330
331 let norm = state_vector
333 .iter()
334 .map(|x| x.norm_sqr())
335 .sum::<f64>()
336 .sqrt();
337 if norm > 1e-15 {
338 for amp in state_vector.iter_mut() {
339 *amp /= norm;
340 }
341 }
342
343 self.state = PhotonicState::Fock(state_vector);
344 }
345 PhotonicMethod::CoherentBasis => {
346 let vacuum = FockState::vacuum(self.config.num_modes);
347 self.state = PhotonicState::Squeezed {
348 amplitudes: vec![Complex64::new(1.0, 0.0)],
349 squeezing_params: vec![xi],
350 basis_states: vec![vacuum],
351 };
352 }
353 _ => {
354 return Err(SimulatorError::UnsupportedOperation(
355 "Squeezed states not supported for this method".to_string(),
356 ));
357 }
358 }
359
360 Ok(())
361 }
362
363 pub fn apply_operator(&mut self, operator: PhotonicOperator) -> Result<()> {
365 let start_time = std::time::Instant::now();
366
367 match operator {
368 PhotonicOperator::Creation(mode) => self.apply_creation(mode)?,
369 PhotonicOperator::Annihilation(mode) => self.apply_annihilation(mode)?,
370 PhotonicOperator::Number(mode) => self.apply_number(mode)?,
371 PhotonicOperator::Displacement(mode, alpha) => self.apply_displacement(mode, alpha)?,
372 PhotonicOperator::Squeezing(mode, xi) => self.apply_squeezing(mode, xi)?,
373 PhotonicOperator::BeamSplitter(mode1, mode2, transmittance) => {
374 self.apply_beam_splitter(mode1, mode2, transmittance)?;
375 }
376 PhotonicOperator::PhaseShift(mode, phase) => self.apply_phase_shift(mode, phase)?,
377 PhotonicOperator::Kerr(mode, strength) => self.apply_kerr(mode, strength)?,
378 }
379
380 Ok(())
381 }
382
383 fn apply_creation(&mut self, mode: usize) -> Result<()> {
385 let fock_states = self.enumerate_fock_states()?;
387
388 match &mut self.state {
389 PhotonicState::Fock(state_vector) => {
390 let mut new_state = Array1::zeros(state_vector.len());
391
392 for (i, amplitude) in state_vector.iter().enumerate() {
393 if amplitude.norm() < 1e-15 {
394 continue;
395 }
396
397 let mut new_fock = fock_states[i].clone();
398 new_fock.photon_numbers[mode] += 1;
399
400 if let Some(j) = fock_states.iter().position(|s| s == &new_fock) {
401 let creation_factor = (new_fock.photon_numbers[mode] as f64).sqrt();
402 new_state[j] += *amplitude * creation_factor;
403 }
404 }
405
406 let norm = new_state
408 .iter()
409 .map(|x: &Complex64| x.norm_sqr())
410 .sum::<f64>()
411 .sqrt();
412 if norm > 1e-15 {
413 for amp in new_state.iter_mut() {
414 *amp /= norm;
415 }
416 }
417
418 *state_vector = new_state;
419 }
420 _ => {
421 return Err(SimulatorError::UnsupportedOperation(
422 "Creation operator not supported for this state representation".to_string(),
423 ));
424 }
425 }
426
427 Ok(())
428 }
429
430 fn apply_annihilation(&mut self, mode: usize) -> Result<()> {
432 let fock_states = self.enumerate_fock_states()?;
434
435 match &mut self.state {
436 PhotonicState::Fock(state_vector) => {
437 let mut new_state = Array1::zeros(state_vector.len());
438
439 for (i, amplitude) in state_vector.iter().enumerate() {
440 if amplitude.norm() < 1e-15 {
441 continue;
442 }
443
444 let current_fock = &fock_states[i];
445 if current_fock.photon_numbers[mode] > 0 {
446 let mut new_fock = current_fock.clone();
447 new_fock.photon_numbers[mode] -= 1;
448
449 if let Some(j) = fock_states.iter().position(|s| s == &new_fock) {
450 let annihilation_factor =
451 (current_fock.photon_numbers[mode] as f64).sqrt();
452 new_state[j] += *amplitude * annihilation_factor;
453 }
454 }
455 }
456
457 let norm = new_state
459 .iter()
460 .map(|x: &Complex64| x.norm_sqr())
461 .sum::<f64>()
462 .sqrt();
463 if norm > 1e-15 {
464 for amp in new_state.iter_mut() {
465 *amp /= norm;
466 }
467 }
468
469 *state_vector = new_state;
470 }
471 _ => {
472 return Err(SimulatorError::UnsupportedOperation(
473 "Annihilation operator not supported for this state representation".to_string(),
474 ));
475 }
476 }
477
478 Ok(())
479 }
480
481 fn apply_number(&mut self, mode: usize) -> Result<()> {
483 let fock_states = self.enumerate_fock_states()?;
485
486 match &mut self.state {
487 PhotonicState::Fock(state_vector) => {
488 for (i, amplitude) in state_vector.iter_mut().enumerate() {
489 let n = fock_states[i].photon_numbers[mode] as f64;
490 *amplitude *= n;
491 }
492 }
493 _ => {
494 return Err(SimulatorError::UnsupportedOperation(
495 "Number operator not supported for this state representation".to_string(),
496 ));
497 }
498 }
499
500 Ok(())
501 }
502
503 fn apply_displacement(&mut self, mode: usize, alpha: Complex64) -> Result<()> {
505 match self.config.method {
506 PhotonicMethod::FockBasis | PhotonicMethod::TruncatedFock => {
507 self.apply_displacement_fock(mode, alpha)?;
508 }
509 PhotonicMethod::CoherentBasis => {
510 self.apply_displacement_coherent(mode, alpha)?;
511 }
512 PhotonicMethod::SciRS2Continuous => {
513 self.apply_displacement_scirs2(mode, alpha)?;
514 }
515 _ => {
516 return Err(SimulatorError::UnsupportedOperation(
517 "Displacement not supported for this method".to_string(),
518 ));
519 }
520 }
521
522 Ok(())
523 }
524
525 fn apply_displacement_fock(&mut self, mode: usize, alpha: Complex64) -> Result<()> {
527 let displacement_matrix = self.build_displacement_matrix(mode, alpha)?;
529
530 if let PhotonicState::Fock(state_vector) = &mut self.state {
531 let new_state = displacement_matrix.dot(state_vector);
532 *state_vector = new_state;
533 }
534 Ok(())
535 }
536
537 fn apply_displacement_coherent(&mut self, mode: usize, alpha: Complex64) -> Result<()> {
539 if let PhotonicState::Coherent { amplitudes, .. } = &mut self.state {
540 if mode < amplitudes.len() {
542 amplitudes[mode] += alpha;
543 }
544 }
545 Ok(())
546 }
547
548 fn apply_squeezing(&mut self, mode: usize, xi: Complex64) -> Result<()> {
550 let squeezing_matrix = self.build_squeezing_matrix(mode, xi)?;
552
553 match &mut self.state {
554 PhotonicState::Fock(state_vector) => {
555 let new_state = squeezing_matrix.dot(state_vector);
556 *state_vector = new_state;
557 }
558 _ => {
559 return Err(SimulatorError::UnsupportedOperation(
560 "Squeezing not supported for this state representation".to_string(),
561 ));
562 }
563 }
564
565 Ok(())
566 }
567
568 fn apply_beam_splitter(
570 &mut self,
571 mode1: usize,
572 mode2: usize,
573 transmittance: f64,
574 ) -> Result<()> {
575 if mode1 == mode2 {
576 return Err(SimulatorError::InvalidInput(
577 "Beam splitter modes must be different".to_string(),
578 ));
579 }
580
581 let theta = transmittance.acos();
582
583 let bs_matrix = self.build_beam_splitter_matrix(mode1, mode2, theta)?;
585
586 match &mut self.state {
587 PhotonicState::Fock(state_vector) => {
588 let new_state = bs_matrix.dot(state_vector);
589 *state_vector = new_state;
590 }
591 _ => {
592 return Err(SimulatorError::UnsupportedOperation(
593 "Beam splitter not supported for this state representation".to_string(),
594 ));
595 }
596 }
597
598 Ok(())
599 }
600
601 fn apply_phase_shift(&mut self, mode: usize, phase: f64) -> Result<()> {
603 let fock_states = if matches!(self.state, PhotonicState::Fock(_)) {
605 Some(self.enumerate_fock_states()?)
606 } else {
607 None
608 };
609
610 match &mut self.state {
611 PhotonicState::Fock(state_vector) => {
612 let fock_states = fock_states.unwrap();
613
614 for (i, amplitude) in state_vector.iter_mut().enumerate() {
615 let n = fock_states[i].photon_numbers[mode] as f64;
616 let phase_factor = Complex64::new(0.0, n * phase).exp();
617 *amplitude *= phase_factor;
618 }
619 }
620 PhotonicState::Coherent { amplitudes, .. } => {
621 if mode < amplitudes.len() {
622 amplitudes[mode] *= Complex64::new(0.0, phase).exp();
623 }
624 }
625 _ => {
626 return Err(SimulatorError::UnsupportedOperation(
627 "Phase shift not supported for this state representation".to_string(),
628 ));
629 }
630 }
631
632 Ok(())
633 }
634
635 fn apply_kerr(&mut self, mode: usize, strength: f64) -> Result<()> {
637 let fock_states = self.enumerate_fock_states()?;
639
640 match &mut self.state {
641 PhotonicState::Fock(state_vector) => {
642 for (i, amplitude) in state_vector.iter_mut().enumerate() {
643 let n = fock_states[i].photon_numbers[mode] as f64;
644 let kerr_phase = Complex64::new(0.0, strength * n * (n - 1.0) / 2.0).exp();
645 *amplitude *= kerr_phase;
646 }
647 }
648 _ => {
649 return Err(SimulatorError::UnsupportedOperation(
650 "Kerr nonlinearity not supported for this state representation".to_string(),
651 ));
652 }
653 }
654
655 Ok(())
656 }
657
658 pub fn measure_photon_number(&self, mode: usize) -> Result<f64> {
660 match &self.state {
661 PhotonicState::Fock(state_vector) => {
662 let fock_states = self.enumerate_fock_states()?;
663 let mut expectation = 0.0;
664
665 for (i, amplitude) in state_vector.iter().enumerate() {
666 let probability = amplitude.norm_sqr();
667 let n = fock_states[i].photon_numbers[mode] as f64;
668 expectation += probability * n;
669 }
670
671 Ok(expectation)
672 }
673 PhotonicState::Coherent { amplitudes, .. } => {
674 if mode < amplitudes.len() {
675 Ok(amplitudes[mode].norm_sqr())
676 } else {
677 Ok(0.0)
678 }
679 }
680 _ => Err(SimulatorError::UnsupportedOperation(
681 "Photon number measurement not supported for this state".to_string(),
682 )),
683 }
684 }
685
686 pub fn photon_distribution(&self, mode: usize) -> Result<Vec<f64>> {
688 match &self.state {
689 PhotonicState::Fock(state_vector) => {
690 let fock_states = self.enumerate_fock_states()?;
691 let mut distribution = vec![0.0; self.config.max_photon_number + 1];
692
693 for (i, amplitude) in state_vector.iter().enumerate() {
694 let probability = amplitude.norm_sqr();
695 let n = fock_states[i].photon_numbers[mode];
696 if n <= self.config.max_photon_number {
697 distribution[n] += probability;
698 }
699 }
700
701 Ok(distribution)
702 }
703 _ => Err(SimulatorError::UnsupportedOperation(
704 "Photon distribution not supported for this state".to_string(),
705 )),
706 }
707 }
708
709 pub fn wigner_function(&self) -> Result<Array2<f64>> {
711 match &self.state {
712 PhotonicState::Wigner {
713 function_values, ..
714 } => Ok(function_values.mapv(|z| z.re)),
715 PhotonicState::Fock(state_vector) => {
716 if self.config.num_modes != 1 {
717 return Err(SimulatorError::UnsupportedOperation(
718 "Wigner function calculation only supported for single mode".to_string(),
719 ));
720 }
721
722 let grid_size = self.config.wigner_grid_size;
723 let range = self.config.phase_space_range;
724 let mut wigner = Array2::zeros((grid_size, grid_size));
725
726 for i in 0..grid_size {
727 for j in 0..grid_size {
728 let q = -range + 2.0 * range * i as f64 / (grid_size - 1) as f64;
729 let p = -range + 2.0 * range * j as f64 / (grid_size - 1) as f64;
730
731 wigner[[i, j]] = self.calculate_wigner_point(q, p, state_vector)?;
732 }
733 }
734
735 Ok(wigner)
736 }
737 _ => Err(SimulatorError::UnsupportedOperation(
738 "Wigner function not supported for this state representation".to_string(),
739 )),
740 }
741 }
742
743 fn calculate_fock_dimension(&self) -> Result<usize> {
745 let n = self.config.max_photon_number;
747 let m = self.config.num_modes;
748
749 let dim = if m == 1 {
750 n + 1
752 } else {
753 Self::binomial_coefficient(n + m - 1, m - 1)
755 };
756
757 if dim > 1_000_000 {
758 return Err(SimulatorError::InvalidInput(
759 "Fock space dimension too large".to_string(),
760 ));
761 }
762
763 Ok(dim)
764 }
765
766 fn enumerate_fock_states(&self) -> Result<Vec<FockState>> {
767 let mut states = Vec::new();
768 let max_n = self.config.max_photon_number;
769 let num_modes = self.config.num_modes;
770
771 self.generate_fock_states_recursive(&mut states, &mut vec![0; num_modes], 0, 0, max_n);
773
774 Ok(states)
775 }
776
777 fn generate_fock_states_recursive(
778 &self,
779 states: &mut Vec<FockState>,
780 current_state: &mut Vec<usize>,
781 mode: usize,
782 current_total: usize,
783 max_total: usize,
784 ) {
785 if mode == self.config.num_modes {
786 states.push(FockState::new(current_state.clone()));
787 return;
788 }
789
790 for n in 0..=(max_total - current_total) {
791 current_state[mode] = n;
792 self.generate_fock_states_recursive(
793 states,
794 current_state,
795 mode + 1,
796 current_total + n,
797 max_total,
798 );
799 }
800 }
801
802 fn get_state_index(&self, state: &FockState, fock_states: &[FockState]) -> Option<usize> {
803 self.basis_cache
804 .get(state)
805 .copied()
806 .or_else(|| fock_states.iter().position(|s| s == state))
807 }
808
809 fn calculate_squeezed_amplitude(&self, n: usize, r: f64, phi: f64) -> Complex64 {
810 if n % 2 != 0 {
811 return Complex64::new(0.0, 0.0);
812 }
813
814 let m = n / 2;
815 let tanh_r = r.tanh();
816 let sech_r = 1.0 / r.cosh();
817
818 let amplitude = sech_r.sqrt()
819 * (-tanh_r).powi(m as i32)
820 * Complex64::new(0.0, m as f64 * phi).exp()
821 * Self::double_factorial(2 * m - 1)
822 / Self::factorial(m)
823 * tanh_r.powf(m as f64);
824
825 amplitude
826 }
827
828 fn build_displacement_matrix(
829 &self,
830 mode: usize,
831 alpha: Complex64,
832 ) -> Result<Array2<Complex64>> {
833 let dim = self.calculate_fock_dimension()?;
834 let mut matrix = Array2::zeros((dim, dim));
835
836 for i in 0..dim {
839 matrix[[i, i]] = Complex64::new(1.0, 0.0);
840 }
841
842 Ok(matrix)
843 }
844
845 fn build_squeezing_matrix(&self, mode: usize, xi: Complex64) -> Result<Array2<Complex64>> {
846 let dim = self.calculate_fock_dimension()?;
847 let mut matrix = Array2::eye(dim);
848
849 Ok(matrix.mapv(|x| Complex64::new(x, 0.0)))
851 }
852
853 fn build_beam_splitter_matrix(
854 &self,
855 mode1: usize,
856 mode2: usize,
857 theta: f64,
858 ) -> Result<Array2<Complex64>> {
859 let dim = self.calculate_fock_dimension()?;
860 let mut matrix = Array2::eye(dim);
861
862 Ok(matrix.mapv(|x| Complex64::new(x, 0.0)))
864 }
865
866 fn calculate_wigner_point(&self, q: f64, p: f64, state: &Array1<Complex64>) -> Result<f64> {
867 let alpha = Complex64::new(q, p) / 2.0_f64.sqrt();
869 let displacement_state = self.apply_displacement_to_state(state, alpha)?;
870
871 let parity = self.calculate_parity_expectation(&displacement_state)?;
873
874 Ok(2.0 * parity / std::f64::consts::PI)
875 }
876
877 fn apply_displacement_to_state(
878 &self,
879 state: &Array1<Complex64>,
880 alpha: Complex64,
881 ) -> Result<Array1<Complex64>> {
882 Ok(state.clone())
884 }
885
886 fn calculate_parity_expectation(&self, state: &Array1<Complex64>) -> Result<f64> {
887 Ok(0.5)
889 }
890
891 fn initialize_coherent_scirs2(&mut self, alpha: Complex64, mode: usize) -> Result<()> {
894 if let Some(_backend) = &mut self.backend {
895 let dim = 1000; let mut state_vector = Array1::zeros(dim);
898 state_vector[0] = Complex64::new(1.0, 0.0);
899 self.state = PhotonicState::Fock(state_vector);
900 } else {
901 self.initialize_coherent_state(alpha, mode)?;
902 }
903 Ok(())
904 }
905
906 fn apply_displacement_scirs2(&mut self, mode: usize, alpha: Complex64) -> Result<()> {
907 if let Some(_backend) = &mut self.backend {
908 self.apply_displacement_fock(mode, alpha)?;
911 } else {
912 self.apply_displacement_fock(mode, alpha)?;
913 }
914 Ok(())
915 }
916
917 fn initialize_coherent_wigner(&mut self, alpha: Complex64, mode: usize) -> Result<()> {
918 let grid_size = self.config.wigner_grid_size;
919 let range = self.config.phase_space_range;
920 let mut function_values = Array2::zeros((grid_size, grid_size));
921
922 let q0 = alpha.re * 2.0_f64.sqrt();
924 let p0 = alpha.im * 2.0_f64.sqrt();
925
926 for i in 0..grid_size {
927 for j in 0..grid_size {
928 let q = -range + 2.0 * range * i as f64 / (grid_size - 1) as f64;
929 let p = -range + 2.0 * range * j as f64 / (grid_size - 1) as f64;
930
931 let gaussian = (-(q - q0).powi(2) - (p - p0).powi(2)).exp() / std::f64::consts::PI;
932 function_values[[i, j]] = Complex64::new(gaussian, 0.0);
933 }
934 }
935
936 let q_grid = Array1::linspace(-range, range, grid_size);
937 let p_grid = Array1::linspace(-range, range, grid_size);
938
939 self.state = PhotonicState::Wigner {
940 function_values,
941 q_grid,
942 p_grid,
943 };
944
945 Ok(())
946 }
947
948 fn factorial(n: usize) -> f64 {
951 (1..=n).fold(1.0, |acc, x| acc * x as f64)
952 }
953
954 fn double_factorial(n: usize) -> f64 {
955 if n <= 1 {
956 1.0
957 } else {
958 n as f64 * Self::double_factorial(n - 2)
959 }
960 }
961
962 fn binomial_coefficient(n: usize, k: usize) -> usize {
963 if k > n {
964 0
965 } else if k == 0 || k == n {
966 1
967 } else {
968 (1..=k).fold(1, |acc, i| acc * (n - i + 1) / i)
969 }
970 }
971
972 pub fn get_state(&self) -> &PhotonicState {
974 &self.state
975 }
976
977 pub fn get_config(&self) -> &PhotonicConfig {
979 &self.config
980 }
981
982 pub fn set_config(&mut self, config: PhotonicConfig) {
984 self.config = config;
985 }
986}
987
988pub struct PhotonicUtils;
990
991impl PhotonicUtils {
992 pub fn cat_state(
994 alpha: Complex64,
995 phase: f64,
996 ) -> impl Fn(&mut PhotonicSimulator) -> Result<()> {
997 move |simulator: &mut PhotonicSimulator| -> Result<()> {
998 simulator.initialize_coherent_state(alpha, 0)?;
1000
1001 Ok(())
1004 }
1005 }
1006
1007 pub fn fidelity(state1: &PhotonicState, state2: &PhotonicState) -> Result<f64> {
1009 match (state1, state2) {
1010 (PhotonicState::Fock(s1), PhotonicState::Fock(s2)) => {
1011 if s1.len() != s2.len() {
1012 return Err(SimulatorError::DimensionMismatch(
1013 "State vectors have different dimensions".to_string(),
1014 ));
1015 }
1016
1017 let overlap: Complex64 = s1.iter().zip(s2.iter()).map(|(a, b)| a.conj() * b).sum();
1018
1019 Ok(overlap.norm_sqr())
1020 }
1021 _ => Err(SimulatorError::UnsupportedOperation(
1022 "Fidelity calculation not supported for these state types".to_string(),
1023 )),
1024 }
1025 }
1026
1027 pub fn von_neumann_entropy(state: &PhotonicState) -> Result<f64> {
1029 match state {
1030 PhotonicState::Fock(state_vector) => {
1031 let probabilities: Vec<f64> = state_vector
1032 .iter()
1033 .map(|amp| amp.norm_sqr())
1034 .filter(|&p| p > 1e-15)
1035 .collect();
1036
1037 let entropy = -probabilities.iter().map(|&p| p * p.ln()).sum::<f64>();
1038
1039 Ok(entropy)
1040 }
1041 _ => Err(SimulatorError::UnsupportedOperation(
1042 "Entropy calculation not supported for this state type".to_string(),
1043 )),
1044 }
1045 }
1046}
1047
1048pub fn benchmark_photonic_methods(
1050 max_photon_number: usize,
1051 num_modes: usize,
1052) -> Result<HashMap<String, PhotonicStats>> {
1053 let mut results = HashMap::new();
1054
1055 let methods = vec![
1056 ("FockBasis", PhotonicMethod::FockBasis),
1057 ("CoherentBasis", PhotonicMethod::CoherentBasis),
1058 ("TruncatedFock", PhotonicMethod::TruncatedFock),
1059 ];
1060
1061 for (name, method) in methods {
1062 let config = PhotonicConfig {
1063 method,
1064 max_photon_number,
1065 num_modes,
1066 ..Default::default()
1067 };
1068
1069 let start_time = std::time::Instant::now();
1070 let mut simulator = PhotonicSimulator::new(config.clone())?;
1071 simulator.initialize_vacuum()?;
1072
1073 simulator.apply_operator(PhotonicOperator::Creation(0))?;
1075 simulator.apply_operator(PhotonicOperator::Displacement(0, Complex64::new(1.0, 0.5)))?;
1076
1077 let execution_time = start_time.elapsed().as_secs_f64() * 1000.0;
1078
1079 let stats = PhotonicStats {
1080 execution_time_ms: execution_time,
1081 method_used: name.to_string(),
1082 basis_states_count: simulator.calculate_fock_dimension().unwrap_or(0),
1083 ..Default::default()
1084 };
1085
1086 results.insert(name.to_string(), stats);
1087 }
1088
1089 Ok(results)
1090}
1091
1092#[cfg(test)]
1093mod tests {
1094 use super::*;
1095 use approx::assert_abs_diff_eq;
1096
1097 #[test]
1098 fn test_photonic_config_default() {
1099 let config = PhotonicConfig::default();
1100 assert_eq!(config.method, PhotonicMethod::FockBasis);
1101 assert_eq!(config.max_photon_number, 20);
1102 assert_eq!(config.num_modes, 1);
1103 }
1104
1105 #[test]
1106 fn test_fock_state_creation() {
1107 let state = FockState::new(vec![2, 1, 0]);
1108 assert_eq!(state.total_photons(), 3);
1109 assert_eq!(state.photons_in_mode(0), 2);
1110 assert_eq!(state.photons_in_mode(1), 1);
1111 assert_eq!(state.photons_in_mode(2), 0);
1112 }
1113
1114 #[test]
1115 fn test_vacuum_state() {
1116 let vacuum = FockState::vacuum(3);
1117 assert_eq!(vacuum.total_photons(), 0);
1118 assert_eq!(vacuum.photons_in_mode(0), 0);
1119 }
1120
1121 #[test]
1122 fn test_single_photon_state() {
1123 let single = FockState::single_photon(1, 3);
1124 assert_eq!(single.total_photons(), 1);
1125 assert_eq!(single.photons_in_mode(1), 1);
1126 assert_eq!(single.photons_in_mode(0), 0);
1127 }
1128
1129 #[test]
1130 fn test_photonic_simulator_creation() {
1131 let config = PhotonicConfig::default();
1132 let simulator = PhotonicSimulator::new(config).unwrap();
1133 assert_eq!(simulator.config.num_modes, 1);
1134 }
1135
1136 #[test]
1137 fn test_vacuum_initialization() {
1138 let config = PhotonicConfig::default();
1139 let mut simulator = PhotonicSimulator::new(config).unwrap();
1140 simulator.initialize_vacuum().unwrap();
1141
1142 if let PhotonicState::Fock(state) = &simulator.state {
1143 assert_abs_diff_eq!(state[0].norm(), 1.0, epsilon = 1e-10);
1144 }
1145 }
1146
1147 #[test]
1148 fn test_coherent_state_initialization() {
1149 let config = PhotonicConfig {
1150 max_photon_number: 10,
1151 ..Default::default()
1152 };
1153 let mut simulator = PhotonicSimulator::new(config).unwrap();
1154 let alpha = Complex64::new(1.0, 0.5);
1155
1156 simulator.initialize_coherent_state(alpha, 0).unwrap();
1157
1158 if let PhotonicState::Fock(state) = &simulator.state {
1160 let norm_sqr = state.iter().map(|x| x.norm_sqr()).sum::<f64>();
1161 assert_abs_diff_eq!(norm_sqr, 1.0, epsilon = 1e-10);
1162 }
1163 }
1164
1165 #[test]
1166 fn test_creation_operator() {
1167 let config = PhotonicConfig {
1168 max_photon_number: 5,
1169 ..Default::default()
1170 };
1171 let mut simulator = PhotonicSimulator::new(config).unwrap();
1172 simulator.initialize_vacuum().unwrap();
1173
1174 simulator
1176 .apply_operator(PhotonicOperator::Creation(0))
1177 .unwrap();
1178
1179 let photon_number = simulator.measure_photon_number(0).unwrap();
1181 assert_abs_diff_eq!(photon_number, 1.0, epsilon = 1e-10);
1182 }
1183
1184 #[test]
1185 fn test_photon_number_measurement() {
1186 let config = PhotonicConfig {
1187 max_photon_number: 5,
1188 ..Default::default()
1189 };
1190 let mut simulator = PhotonicSimulator::new(config).unwrap();
1191 simulator.initialize_vacuum().unwrap();
1192
1193 simulator
1195 .apply_operator(PhotonicOperator::Creation(0))
1196 .unwrap();
1197 let photon_number_1 = simulator.measure_photon_number(0).unwrap();
1198 assert_abs_diff_eq!(photon_number_1, 1.0, epsilon = 1e-10);
1199
1200 simulator
1202 .apply_operator(PhotonicOperator::Creation(0))
1203 .unwrap();
1204 let photon_number_2 = simulator.measure_photon_number(0).unwrap();
1205 assert_abs_diff_eq!(photon_number_2, 2.0, epsilon = 1e-10);
1206 }
1207
1208 #[test]
1209 fn test_photon_distribution() {
1210 let config = PhotonicConfig {
1211 max_photon_number: 3,
1212 ..Default::default()
1213 };
1214 let mut simulator = PhotonicSimulator::new(config).unwrap();
1215 simulator.initialize_vacuum().unwrap();
1216
1217 let distribution = simulator.photon_distribution(0).unwrap();
1218
1219 assert_abs_diff_eq!(distribution[0], 1.0, epsilon = 1e-10);
1221 assert_abs_diff_eq!(distribution[1], 0.0, epsilon = 1e-10);
1222 }
1223
1224 #[test]
1225 fn test_mathematical_helpers() {
1226 assert_abs_diff_eq!(PhotonicSimulator::factorial(0), 1.0, epsilon = 1e-10);
1227 assert_abs_diff_eq!(PhotonicSimulator::factorial(5), 120.0, epsilon = 1e-10);
1228
1229 assert_eq!(PhotonicSimulator::binomial_coefficient(5, 2), 10);
1230 assert_eq!(PhotonicSimulator::binomial_coefficient(4, 0), 1);
1231 }
1232}