1use crate::builder::Circuit;
8use quantrs2_core::{
9 error::{QuantRS2Error, QuantRS2Result},
10 gate::GateOp,
11 qubit::QubitId,
12};
13use serde::{Deserialize, Serialize};
14use std::collections::{HashMap, HashSet};
15use std::f64::consts::PI;
16
17#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
19pub struct PhotonicMode {
20 pub id: u32,
21 pub polarization: Polarization,
22 pub frequency: Option<f64>, }
24
25impl PhotonicMode {
26 #[must_use]
27 pub const fn new(id: u32) -> Self {
28 Self {
29 id,
30 polarization: Polarization::Horizontal,
31 frequency: None,
32 }
33 }
34
35 #[must_use]
36 pub const fn with_polarization(mut self, polarization: Polarization) -> Self {
37 self.polarization = polarization;
38 self
39 }
40
41 #[must_use]
42 pub const fn with_frequency(mut self, frequency: f64) -> Self {
43 self.frequency = Some(frequency);
44 self
45 }
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
50pub enum Polarization {
51 Horizontal,
52 Vertical,
53 Diagonal,
54 AntiDiagonal,
55 LeftCircular,
56 RightCircular,
57}
58
59#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
61pub enum PhotonicGate {
62 BeamSplitter {
64 mode1: PhotonicMode,
65 mode2: PhotonicMode,
66 reflectivity: f64, phase: f64,
68 },
69 PhaseShifter { mode: PhotonicMode, phase: f64 },
71 PolarizationRotator {
73 mode: PhotonicMode,
74 angle: f64, },
76 HalfWavePlate {
78 mode: PhotonicMode,
79 angle: f64, },
81 QuarterWavePlate { mode: PhotonicMode, angle: f64 },
83 PolarizingBeamSplitter {
85 input: PhotonicMode,
86 h_output: PhotonicMode, v_output: PhotonicMode, },
89 MachZehnder {
91 input1: PhotonicMode,
92 input2: PhotonicMode,
93 output1: PhotonicMode,
94 output2: PhotonicMode,
95 phase_shift: f64,
96 },
97 HongOuMandel {
99 mode1: PhotonicMode,
100 mode2: PhotonicMode,
101 },
102 PhotonicCNOT {
104 control: PhotonicMode,
105 target: PhotonicMode,
106 ancilla: Vec<PhotonicMode>,
107 },
108 KerrGate { mode: PhotonicMode, strength: f64 },
110}
111
112impl PhotonicGate {
113 #[must_use]
115 pub fn modes(&self) -> Vec<PhotonicMode> {
116 match self {
117 Self::BeamSplitter { mode1, mode2, .. } => vec![*mode1, *mode2],
118 Self::PhaseShifter { mode, .. }
119 | Self::PolarizationRotator { mode, .. }
120 | Self::HalfWavePlate { mode, .. }
121 | Self::QuarterWavePlate { mode, .. } => vec![*mode],
122 Self::PolarizingBeamSplitter {
123 input,
124 h_output,
125 v_output,
126 ..
127 } => {
128 vec![*input, *h_output, *v_output]
129 }
130 Self::MachZehnder {
131 input1,
132 input2,
133 output1,
134 output2,
135 ..
136 } => {
137 vec![*input1, *input2, *output1, *output2]
138 }
139 Self::HongOuMandel { mode1, mode2, .. } => vec![*mode1, *mode2],
140 Self::PhotonicCNOT {
141 control,
142 target,
143 ancilla,
144 ..
145 } => {
146 let mut modes = vec![*control, *target];
147 modes.extend(ancilla);
148 modes
149 }
150 Self::KerrGate { mode, .. } => vec![*mode],
151 }
152 }
153
154 #[must_use]
156 pub const fn name(&self) -> &'static str {
157 match self {
158 Self::BeamSplitter { .. } => "BS",
159 Self::PhaseShifter { .. } => "PS",
160 Self::PolarizationRotator { .. } => "PR",
161 Self::HalfWavePlate { .. } => "HWP",
162 Self::QuarterWavePlate { .. } => "QWP",
163 Self::PolarizingBeamSplitter { .. } => "PBS",
164 Self::MachZehnder { .. } => "MZ",
165 Self::HongOuMandel { .. } => "HOM",
166 Self::PhotonicCNOT { .. } => "PCNOT",
167 Self::KerrGate { .. } => "KERR",
168 }
169 }
170}
171
172#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
174pub enum PhotonicMeasurement {
175 PhotonNumber {
177 mode: PhotonicMode,
178 detector_efficiency: f64,
179 },
180 Homodyne {
182 mode: PhotonicMode,
183 local_oscillator_phase: f64,
184 detection_efficiency: f64,
185 },
186 Heterodyne {
188 mode: PhotonicMode,
189 detection_efficiency: f64,
190 },
191 Polarization {
193 mode: PhotonicMode,
194 measurement_basis: PolarizationBasis,
195 },
196 Coincidence {
198 modes: Vec<PhotonicMode>,
199 time_window: f64, },
201}
202
203#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
205pub enum PolarizationBasis {
206 Linear, Diagonal, Circular, }
210
211#[derive(Debug, Clone)]
213pub struct PhotonicCircuit {
214 pub num_modes: usize,
216 pub gates: Vec<PhotonicGate>,
218 pub measurements: Vec<PhotonicMeasurement>,
220 pub mode_mapping: HashMap<u32, u32>,
222}
223
224impl PhotonicCircuit {
225 #[must_use]
227 pub fn new(num_modes: usize) -> Self {
228 Self {
229 num_modes,
230 gates: Vec::new(),
231 measurements: Vec::new(),
232 mode_mapping: HashMap::new(),
233 }
234 }
235
236 pub fn add_gate(&mut self, gate: PhotonicGate) -> QuantRS2Result<()> {
238 for mode in gate.modes() {
240 if mode.id as usize >= self.num_modes {
241 return Err(QuantRS2Error::InvalidInput(format!(
242 "Mode {} exceeds circuit size {}",
243 mode.id, self.num_modes
244 )));
245 }
246 }
247
248 self.gates.push(gate);
249 Ok(())
250 }
251
252 pub fn add_measurement(&mut self, measurement: PhotonicMeasurement) -> QuantRS2Result<()> {
254 self.measurements.push(measurement);
255 Ok(())
256 }
257
258 #[must_use]
260 pub fn depth(&self) -> usize {
261 self.gates.len()
264 }
265
266 pub fn validate(&self) -> QuantRS2Result<()> {
268 let mut mode_usage = HashMap::new();
270
271 for (layer, gate) in self.gates.iter().enumerate() {
272 for mode in gate.modes() {
273 if let Some(&last_usage) = mode_usage.get(&mode.id) {
274 if last_usage == layer {
275 return Err(QuantRS2Error::InvalidInput(format!(
276 "Mode {} used multiple times in layer {}",
277 mode.id, layer
278 )));
279 }
280 }
281 mode_usage.insert(mode.id, layer);
282 }
283 }
284
285 Ok(())
286 }
287}
288
289#[derive(Clone)]
291pub struct PhotonicCircuitBuilder {
292 circuit: PhotonicCircuit,
293}
294
295impl PhotonicCircuitBuilder {
296 #[must_use]
298 pub fn new(num_modes: usize) -> Self {
299 Self {
300 circuit: PhotonicCircuit::new(num_modes),
301 }
302 }
303
304 pub fn beam_splitter(
306 &mut self,
307 mode1: u32,
308 mode2: u32,
309 reflectivity: f64,
310 phase: f64,
311 ) -> QuantRS2Result<&mut Self> {
312 let gate = PhotonicGate::BeamSplitter {
313 mode1: PhotonicMode::new(mode1),
314 mode2: PhotonicMode::new(mode2),
315 reflectivity,
316 phase,
317 };
318 self.circuit.add_gate(gate)?;
319 Ok(self)
320 }
321
322 pub fn phase_shifter(&mut self, mode: u32, phase: f64) -> QuantRS2Result<&mut Self> {
324 let gate = PhotonicGate::PhaseShifter {
325 mode: PhotonicMode::new(mode),
326 phase,
327 };
328 self.circuit.add_gate(gate)?;
329 Ok(self)
330 }
331
332 pub fn mach_zehnder(
334 &mut self,
335 input1: u32,
336 input2: u32,
337 output1: u32,
338 output2: u32,
339 phase_shift: f64,
340 ) -> QuantRS2Result<&mut Self> {
341 let gate = PhotonicGate::MachZehnder {
342 input1: PhotonicMode::new(input1),
343 input2: PhotonicMode::new(input2),
344 output1: PhotonicMode::new(output1),
345 output2: PhotonicMode::new(output2),
346 phase_shift,
347 };
348 self.circuit.add_gate(gate)?;
349 Ok(self)
350 }
351
352 pub fn hong_ou_mandel(&mut self, mode1: u32, mode2: u32) -> QuantRS2Result<&mut Self> {
354 let gate = PhotonicGate::HongOuMandel {
355 mode1: PhotonicMode::new(mode1),
356 mode2: PhotonicMode::new(mode2),
357 };
358 self.circuit.add_gate(gate)?;
359 Ok(self)
360 }
361
362 pub fn measure_photon_number(&mut self, mode: u32) -> QuantRS2Result<&mut Self> {
364 let measurement = PhotonicMeasurement::PhotonNumber {
365 mode: PhotonicMode::new(mode),
366 detector_efficiency: 1.0,
367 };
368 self.circuit.add_measurement(measurement)?;
369 Ok(self)
370 }
371
372 pub fn build(self) -> QuantRS2Result<PhotonicCircuit> {
374 self.circuit.validate()?;
375 Ok(self.circuit)
376 }
377}
378
379pub struct PhotonicConverter;
381
382impl PhotonicConverter {
383 pub fn quantum_to_photonic<const N: usize>(
385 circuit: &Circuit<N>,
386 ) -> QuantRS2Result<PhotonicCircuit> {
387 let mut photonic_circuit = PhotonicCircuit::new(N * 2); for gate in circuit.gates() {
390 let photonic_gates = Self::convert_gate(gate.as_ref())?;
391 for pg in photonic_gates {
392 photonic_circuit.add_gate(pg)?;
393 }
394 }
395
396 Ok(photonic_circuit)
397 }
398
399 fn convert_gate(gate: &dyn GateOp) -> QuantRS2Result<Vec<PhotonicGate>> {
401 let mut photonic_gates = Vec::new();
402 let gate_name = gate.name();
403 let qubits = gate.qubits();
404
405 match gate_name {
406 "H" => {
407 let qubit = qubits[0].id();
409 let mode0 = qubit * 2; let mode1 = qubit * 2 + 1; photonic_gates.push(PhotonicGate::BeamSplitter {
414 mode1: PhotonicMode::new(mode0),
415 mode2: PhotonicMode::new(mode1),
416 reflectivity: 0.5,
417 phase: 0.0,
418 });
419 }
420 "X" => {
421 let qubit = qubits[0].id();
423 let mode0 = qubit * 2;
424 let mode1 = qubit * 2 + 1;
425
426 photonic_gates.push(PhotonicGate::BeamSplitter {
428 mode1: PhotonicMode::new(mode0),
429 mode2: PhotonicMode::new(mode1),
430 reflectivity: 1.0, phase: 0.0,
432 });
433 }
434 "Z" => {
435 let qubit = qubits[0].id();
437 let mode1 = qubit * 2 + 1;
438
439 photonic_gates.push(PhotonicGate::PhaseShifter {
440 mode: PhotonicMode::new(mode1),
441 phase: PI,
442 });
443 }
444 "CNOT" => {
445 let control_qubit = qubits[0].id();
447 let target_qubit = qubits[1].id();
448
449 let control_mode = control_qubit * 2 + 1; let target_mode0 = target_qubit * 2;
451 let target_mode1 = target_qubit * 2 + 1;
452
453 photonic_gates.push(PhotonicGate::PhotonicCNOT {
455 control: PhotonicMode::new(control_mode),
456 target: PhotonicMode::new(target_mode0),
457 ancilla: vec![PhotonicMode::new(target_mode1)],
458 });
459 }
460 _ => {
461 return Err(QuantRS2Error::InvalidInput(format!(
462 "Gate {gate_name} not supported in photonic conversion"
463 )));
464 }
465 }
466
467 Ok(photonic_gates)
468 }
469}
470
471#[derive(Debug, Clone)]
473pub struct CVCircuit {
474 pub num_modes: usize,
476 pub gates: Vec<CVGate>,
478 pub measurements: Vec<CVMeasurement>,
480}
481
482#[derive(Debug, Clone, PartialEq)]
484pub enum CVGate {
485 Displacement {
487 mode: u32,
488 amplitude: f64,
489 phase: f64,
490 },
491 Squeezing {
493 mode: u32,
494 squeezing_parameter: f64,
495 squeezing_angle: f64,
496 },
497 TwoModeSqueezing {
499 mode1: u32,
500 mode2: u32,
501 squeezing_parameter: f64,
502 },
503 Rotation { mode: u32, angle: f64 },
505 CVBeamSplitter {
507 mode1: u32,
508 mode2: u32,
509 theta: f64, phi: f64, },
512 CVKerr { mode: u32, strength: f64 },
514 ControlledDisplacement {
516 control_mode: u32,
517 target_mode: u32,
518 strength: f64,
519 },
520}
521
522#[derive(Debug, Clone, PartialEq)]
524pub enum CVMeasurement {
525 CVHomodyne {
527 mode: u32,
528 angle: f64, },
530 CVHeterodyne { mode: u32 },
532 CVPhotonNumber { mode: u32 },
534}
535
536impl CVCircuit {
537 #[must_use]
539 pub const fn new(num_modes: usize) -> Self {
540 Self {
541 num_modes,
542 gates: Vec::new(),
543 measurements: Vec::new(),
544 }
545 }
546
547 pub fn displacement(&mut self, mode: u32, amplitude: f64, phase: f64) -> QuantRS2Result<()> {
549 self.gates.push(CVGate::Displacement {
550 mode,
551 amplitude,
552 phase,
553 });
554 Ok(())
555 }
556
557 pub fn squeezing(&mut self, mode: u32, r: f64, angle: f64) -> QuantRS2Result<()> {
559 self.gates.push(CVGate::Squeezing {
560 mode,
561 squeezing_parameter: r,
562 squeezing_angle: angle,
563 });
564 Ok(())
565 }
566
567 pub fn beam_splitter(
569 &mut self,
570 mode1: u32,
571 mode2: u32,
572 theta: f64,
573 phi: f64,
574 ) -> QuantRS2Result<()> {
575 self.gates.push(CVGate::CVBeamSplitter {
576 mode1,
577 mode2,
578 theta,
579 phi,
580 });
581 Ok(())
582 }
583}
584
585#[cfg(test)]
586mod tests {
587 use super::*;
588 use quantrs2_core::gate::multi::CNOT;
589 use quantrs2_core::gate::single::Hadamard;
590
591 #[test]
592 fn test_photonic_circuit_creation() {
593 let mut circuit = PhotonicCircuit::new(4);
594
595 let bs_gate = PhotonicGate::BeamSplitter {
596 mode1: PhotonicMode::new(0),
597 mode2: PhotonicMode::new(1),
598 reflectivity: 0.5,
599 phase: 0.0,
600 };
601
602 assert!(circuit.add_gate(bs_gate).is_ok());
603 assert_eq!(circuit.gates.len(), 1);
604 }
605
606 #[test]
607 fn test_photonic_builder() {
608 let mut builder = PhotonicCircuitBuilder::new(4);
609
610 builder
611 .beam_splitter(0, 1, 0.5, 0.0)
612 .expect("Failed to add beam splitter");
613 builder
614 .phase_shifter(1, PI / 2.0)
615 .expect("Failed to add phase shifter");
616 builder
617 .mach_zehnder(0, 1, 2, 3, PI / 4.0)
618 .expect("Failed to add Mach-Zehnder interferometer");
619 let result = builder.build();
620
621 assert!(result.is_ok());
622 let circuit = result.expect("Failed to build photonic circuit");
623 assert_eq!(circuit.gates.len(), 3);
624 }
625
626 #[test]
627 fn test_quantum_to_photonic_conversion() {
628 let mut quantum_circuit = Circuit::<2>::new();
629 quantum_circuit
630 .add_gate(Hadamard { target: QubitId(0) })
631 .expect("Failed to add Hadamard gate");
632
633 let photonic_result = PhotonicConverter::quantum_to_photonic(&quantum_circuit);
634 assert!(photonic_result.is_ok());
635
636 let photonic_circuit = photonic_result.expect("Failed to convert to photonic circuit");
637 assert_eq!(photonic_circuit.num_modes, 4); assert!(!photonic_circuit.gates.is_empty());
639 }
640
641 #[test]
642 fn test_cv_circuit() {
643 let mut cv_circuit = CVCircuit::new(2);
644
645 assert!(cv_circuit.displacement(0, 1.0, 0.0).is_ok());
646 assert!(cv_circuit.squeezing(1, 0.5, PI / 4.0).is_ok());
647 assert!(cv_circuit.beam_splitter(0, 1, PI / 4.0, 0.0).is_ok());
648
649 assert_eq!(cv_circuit.gates.len(), 3);
650 }
651
652 #[test]
653 fn test_photonic_modes() {
654 let mode = PhotonicMode::new(0)
655 .with_polarization(Polarization::Vertical)
656 .with_frequency(532e12); assert_eq!(mode.id, 0);
659 assert_eq!(mode.polarization, Polarization::Vertical);
660 assert_eq!(mode.frequency, Some(532e12));
661 }
662
663 #[test]
664 fn test_hong_ou_mandel() {
665 let mut builder = PhotonicCircuitBuilder::new(2);
666 builder
667 .hong_ou_mandel(0, 1)
668 .expect("Failed to add Hong-Ou-Mandel gate");
669 let result = builder.build();
670
671 assert!(result.is_ok());
672 let circuit = result.expect("Failed to build photonic circuit");
673 assert_eq!(circuit.gates.len(), 1);
674
675 match &circuit.gates[0] {
676 PhotonicGate::HongOuMandel { mode1, mode2 } => {
677 assert_eq!(mode1.id, 0);
678 assert_eq!(mode2.id, 1);
679 }
680 _ => panic!("Expected HongOuMandel gate"),
681 }
682 }
683}