#[derive(Debug, Clone)]
pub struct FloquetCavity {
pub omega0: f64,
pub modulation_depth: f64,
pub modulation_freq: f64,
}
impl FloquetCavity {
pub fn quasi_energy(&self, n_floquet: i32, sign: i8) -> f64 {
let sign_f = if sign >= 0 { 1.0_f64 } else { -1.0_f64 };
let coupling = self.modulation_depth * self.omega0 / 4.0;
self.omega0 + (n_floquet as f64) * self.modulation_freq + sign_f * coupling
}
pub fn is_parametric_resonance(&self, m: u32) -> bool {
if m == 0 {
return false;
}
let resonant_freq = 2.0 * self.omega0 / (m as f64);
let detuning = (self.modulation_freq - resonant_freq).abs();
let bandwidth = self.modulation_depth * self.omega0 / 2.0;
detuning < bandwidth
}
pub fn is_stable(&self) -> bool {
!self.is_parametric_resonance(1)
}
pub fn band_gap_width(&self) -> f64 {
self.modulation_depth * self.omega0
}
pub fn growth_rate(&self) -> f64 {
let half_gap_sq = (self.modulation_depth * self.omega0 / 4.0).powi(2);
let detuning = self.modulation_freq - 2.0 * self.omega0;
let detuning_sq = detuning.powi(2);
if detuning_sq >= half_gap_sq {
0.0
} else {
(half_gap_sq - detuning_sq).sqrt()
}
}
pub fn sideband_amplitude_sq(&self, n: i32) -> f64 {
let abs_n = n.unsigned_abs() as i32;
if abs_n == 0 {
let leakage = (self.modulation_depth / 4.0).powi(2);
(1.0_f64 - 2.0 * leakage).max(0.0)
} else {
(self.modulation_depth / 4.0).powi(2 * abs_n)
}
}
pub fn effective_mass(&self) -> f64 {
if self.modulation_freq == 0.0 {
return f64::INFINITY;
}
1.0 / self.modulation_freq
}
}
#[derive(Debug, Clone)]
pub struct ModulatedCavity {
pub omega0: f64,
pub q_factor: f64,
pub modulation_rate: f64,
pub modulation_freq: f64,
}
impl ModulatedCavity {
fn loss_rate(&self) -> f64 {
self.omega0 / self.q_factor
}
fn net_gain_rate(&self) -> f64 {
let kappa_half = self.loss_rate() / 2.0;
let discriminant = self.modulation_rate.powi(2) - kappa_half.powi(2);
if discriminant <= 0.0 {
0.0
} else {
discriminant.sqrt()
}
}
pub fn amplification_factor(&self, time_s: f64) -> f64 {
let kappa_half = self.loss_rate() / 2.0;
let gamma = self.net_gain_rate();
if gamma > 0.0 {
(gamma - kappa_half).exp().powf(time_s)
} else {
let effective_rate = (kappa_half - self.modulation_rate).max(0.0);
(-effective_rate * time_s).exp()
}
}
pub fn is_above_threshold(&self) -> bool {
self.modulation_rate > self.loss_rate() / 2.0
}
pub fn squeezing_db(&self, time_s: f64) -> f64 {
if self.is_above_threshold() {
return 0.0;
}
let kappa_half = self.loss_rate() / 2.0;
let discriminant = kappa_half.powi(2) - self.modulation_rate.powi(2);
let gamma_sq = discriminant.max(0.0).sqrt();
-10.0 * ((-2.0 * gamma_sq * time_s).exp()).log10()
}
}
#[cfg(test)]
mod tests {
use super::*;
fn default_cavity() -> FloquetCavity {
FloquetCavity {
omega0: 2e14, modulation_depth: 0.1, modulation_freq: 4e14, }
}
#[test]
fn quasi_energy_n0_zero_sign() {
let fc = default_cavity();
let expected = fc.omega0 + fc.modulation_depth * fc.omega0 / 4.0;
let result = fc.quasi_energy(0, 1_i8);
assert!(
(result - expected).abs() < 1e6,
"quasi_energy mismatch: {result} vs {expected}"
);
}
#[test]
fn quasi_energy_antisymmetry() {
let fc = default_cavity();
let ep = fc.quasi_energy(1, 1_i8);
let em = fc.quasi_energy(1, -1_i8);
let mid = (ep + em) / 2.0;
let expected_mid = fc.omega0 + fc.modulation_freq;
assert!((mid - expected_mid).abs() < 1e6);
}
#[test]
fn parametric_resonance_detected() {
let fc = default_cavity(); assert!(
fc.is_parametric_resonance(1),
"primary resonance should be detected"
);
assert!(
!fc.is_parametric_resonance(2),
"second-order resonance should not fire here"
);
}
#[test]
fn stability_off_resonance() {
let fc = FloquetCavity {
omega0: 2e14,
modulation_depth: 0.01,
modulation_freq: 1e14, };
assert!(fc.is_stable(), "far off-resonance cavity should be stable");
}
#[test]
fn growth_rate_positive_on_resonance() {
let fc = default_cavity(); let gr = fc.growth_rate();
assert!(
gr > 0.0,
"growth rate should be positive at resonance: {gr}"
);
}
#[test]
fn sideband_normalization() {
let fc = default_cavity();
let s0 = fc.sideband_amplitude_sq(0);
let sp = fc.sideband_amplitude_sq(1);
let sm = fc.sideband_amplitude_sq(-1);
assert!(s0 + sp + sm <= 1.001, "sideband sum > 1: {}", s0 + sp + sm);
}
#[test]
fn threshold_detection() {
let mc = ModulatedCavity {
omega0: 2e14,
q_factor: 1e4,
modulation_rate: 2e10, modulation_freq: 4e14,
};
assert!(mc.is_above_threshold());
}
#[test]
fn squeezing_below_threshold() {
let mc = ModulatedCavity {
omega0: 2e14,
q_factor: 1e3,
modulation_rate: 1e9, modulation_freq: 4e14,
};
let sq = mc.squeezing_db(1e-9);
assert!(sq >= 0.0, "squeezing should be non-negative: {sq}");
}
}