use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use thiserror::Error;
use super::continuous_variable::{CVError, CVResult, GaussianState};
use super::{PhotonicMode, PhotonicSystemType};
use crate::DeviceResult;
#[derive(Error, Debug)]
pub enum PhotonicQECError {
#[error("Loss rate too high: {0}")]
LossRateTooHigh(f64),
#[error("Insufficient redundancy: {0}")]
InsufficientRedundancy(String),
#[error("Syndrome extraction failed: {0}")]
SyndromeExtractionFailed(String),
#[error("Correction application failed: {0}")]
CorrectionFailed(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum PhotonicErrorCorrectionCode {
LossTolerant { redundancy: usize },
MeasurementBased { cluster_size: usize },
ContinuousVariable { code_type: CVQECType },
Hybrid {
photonic_modes: usize,
matter_qubits: usize,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum CVQECType {
SqueezedState,
DisplacedSqueezed,
MultiMode,
}
pub struct PhotonicQECEngine {
pub active_codes: Vec<PhotonicErrorCorrectionCode>,
pub error_stats: HashMap<String, f64>,
}
impl PhotonicQECEngine {
pub fn new() -> Self {
Self {
active_codes: Vec::new(),
error_stats: HashMap::new(),
}
}
pub fn apply_error_correction(
&mut self,
state: &mut GaussianState,
code: &PhotonicErrorCorrectionCode,
) -> Result<(), PhotonicQECError> {
match code {
PhotonicErrorCorrectionCode::LossTolerant { redundancy } => {
self.apply_loss_tolerance(state, *redundancy)
}
PhotonicErrorCorrectionCode::ContinuousVariable { code_type } => {
self.apply_cv_error_correction(state, code_type)
}
_ => Ok(()), }
}
fn apply_loss_tolerance(
&mut self,
state: &mut GaussianState,
redundancy: usize,
) -> Result<(), PhotonicQECError> {
if redundancy < 2 {
return Err(PhotonicQECError::InsufficientRedundancy(
"Loss tolerance requires redundancy >= 2".to_string(),
));
}
for mode in 0..state.num_modes.min(redundancy) {
if let Ok(loss_rate) = state.average_photon_number(mode) {
if loss_rate < 0.1 {
state.covariance[2 * mode][2 * mode] *= 1.1;
state.covariance[2 * mode + 1][2 * mode + 1] *= 1.1;
}
}
}
Ok(())
}
fn apply_cv_error_correction(
&mut self,
state: &mut GaussianState,
code_type: &CVQECType,
) -> Result<(), PhotonicQECError> {
match code_type {
CVQECType::SqueezedState => {
for mode in 0..state.num_modes {
if state.squeeze(0.1, 0.0, mode).is_err() {
return Err(PhotonicQECError::CorrectionFailed(format!(
"Failed to apply squeezing correction to mode {mode}"
)));
}
}
}
CVQECType::DisplacedSqueezed => {
for mode in 0..state.num_modes {
let _ =
state.displace(super::continuous_variable::Complex::new(0.1, 0.0), mode);
let _ = state.squeeze(0.05, 0.0, mode);
}
}
CVQECType::MultiMode => {
}
}
Ok(())
}
pub fn extract_syndrome(
&self,
state: &GaussianState,
code: &PhotonicErrorCorrectionCode,
) -> Result<Vec<bool>, PhotonicQECError> {
match code {
PhotonicErrorCorrectionCode::LossTolerant { redundancy } => {
let mut syndrome = Vec::new();
for mode in 0..state.num_modes.min(*redundancy) {
if let Ok(avg_photons) = state.average_photon_number(mode) {
syndrome.push(avg_photons < 0.5); } else {
syndrome.push(false);
}
}
Ok(syndrome)
}
_ => Ok(vec![false; 4]), }
}
pub fn get_statistics(&self) -> PhotonicQECStatistics {
PhotonicQECStatistics {
active_codes: self.active_codes.len(),
total_corrections_applied: self.error_stats.get("corrections").copied().unwrap_or(0.0)
as usize,
loss_correction_rate: self
.error_stats
.get("loss_corrections")
.copied()
.unwrap_or(0.0),
phase_correction_rate: self
.error_stats
.get("phase_corrections")
.copied()
.unwrap_or(0.0),
overall_fidelity: self.error_stats.get("fidelity").copied().unwrap_or(0.95),
}
}
}
impl Default for PhotonicQECEngine {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PhotonicQECStatistics {
pub active_codes: usize,
pub total_corrections_applied: usize,
pub loss_correction_rate: f64,
pub phase_correction_rate: f64,
pub overall_fidelity: f64,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::photonic::continuous_variable::GaussianState;
#[test]
fn test_qec_engine_creation() {
let engine = PhotonicQECEngine::new();
assert_eq!(engine.active_codes.len(), 0);
}
#[test]
fn test_loss_tolerant_correction() {
let mut engine = PhotonicQECEngine::new();
let mut state = GaussianState::vacuum(2);
let code = PhotonicErrorCorrectionCode::LossTolerant { redundancy: 3 };
let result = engine.apply_error_correction(&mut state, &code);
assert!(result.is_ok());
}
#[test]
fn test_syndrome_extraction() {
let engine = PhotonicQECEngine::new();
let state = GaussianState::vacuum(2);
let code = PhotonicErrorCorrectionCode::LossTolerant { redundancy: 2 };
let syndrome = engine
.extract_syndrome(&state, &code)
.expect("Syndrome extraction should succeed");
assert_eq!(syndrome.len(), 2);
}
}