use crate::error::{QuantRS2Error, QuantRS2Result};
use scirs2_core::ndarray::{Array1, Array2};
use scirs2_core::Complex64;
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum QuantumDotType {
SpinQubit,
ChargeQubit,
SingletTriplet,
HybridQubit,
}
#[derive(Debug, Clone)]
pub struct QuantumDotParams {
pub diameter: f64,
pub tunnel_coupling: f64,
pub charging_energy: f64,
pub zeeman_splitting: f64,
pub spin_orbit_coupling: f64,
pub valley_splitting: f64,
pub temperature: f64,
pub magnetic_field: f64,
}
impl QuantumDotParams {
pub const fn typical_silicon_dot() -> Self {
Self {
diameter: 50.0, tunnel_coupling: 1e-6, charging_energy: 1e-3, zeeman_splitting: 1e-5, spin_orbit_coupling: 1e-7, valley_splitting: 1e-4, temperature: 0.01, magnetic_field: 0.1, }
}
pub fn coherence_time(&self) -> f64 {
let noise_level = self.temperature * 8.617e-5; let dephasing_rate = noise_level / (6.582e-16); 1.0 / dephasing_rate }
pub fn single_qubit_gate_time(&self) -> f64 {
let rabi_freq = self.zeeman_splitting / (6.582e-16); std::f64::consts::PI / (2.0 * rabi_freq) }
pub fn two_qubit_gate_time(&self) -> f64 {
let exchange_freq = self.tunnel_coupling / (6.582e-16); std::f64::consts::PI / (4.0 * exchange_freq) }
}
#[derive(Debug, Clone)]
pub struct SiliconQuantumDot {
pub dot_id: usize,
pub dot_type: QuantumDotType,
pub params: QuantumDotParams,
pub position: [f64; 2],
pub state: Array1<Complex64>,
pub energy_levels: Vec<f64>,
pub gate_voltages: HashMap<String, f64>,
}
impl SiliconQuantumDot {
pub fn new(
dot_id: usize,
dot_type: QuantumDotType,
params: QuantumDotParams,
position: [f64; 2],
) -> Self {
let state_size = match dot_type {
QuantumDotType::SpinQubit | QuantumDotType::ChargeQubit => 2, QuantumDotType::SingletTriplet | QuantumDotType::HybridQubit => 4, };
let mut state = Array1::zeros(state_size);
state[0] = Complex64::new(1.0, 0.0);
let energy_levels = Self::calculate_energy_levels(&dot_type, ¶ms);
Self {
dot_id,
dot_type,
params,
position,
state,
energy_levels,
gate_voltages: HashMap::new(),
}
}
fn calculate_energy_levels(dot_type: &QuantumDotType, params: &QuantumDotParams) -> Vec<f64> {
match dot_type {
QuantumDotType::SpinQubit => {
vec![
-params.zeeman_splitting / 2.0, params.zeeman_splitting / 2.0, ]
}
QuantumDotType::ChargeQubit => {
vec![
0.0, params.charging_energy, ]
}
QuantumDotType::SingletTriplet => {
let exchange = params.tunnel_coupling;
vec![
-exchange, 0.0, params.zeeman_splitting, -params.zeeman_splitting, ]
}
QuantumDotType::HybridQubit => {
vec![
0.0,
params.charging_energy,
params.zeeman_splitting,
params.charging_energy + params.zeeman_splitting,
]
}
}
}
pub fn set_gate_voltage(&mut self, gate_name: String, voltage: f64) {
if gate_name.starts_with("plunger") {
self.params.charging_energy *= voltage.mul_add(0.1, 1.0);
} else if gate_name.starts_with("barrier") {
self.params.tunnel_coupling *= (-voltage).exp();
}
self.gate_voltages.insert(gate_name, voltage);
self.energy_levels = Self::calculate_energy_levels(&self.dot_type, &self.params);
}
pub fn get_probabilities(&self) -> Vec<f64> {
self.state.iter().map(|x| x.norm_sqr()).collect()
}
pub fn apply_unitary(&mut self, unitary: &Array2<Complex64>) -> QuantRS2Result<()> {
if unitary.nrows() != self.state.len() || unitary.ncols() != self.state.len() {
return Err(QuantRS2Error::InvalidInput(
"Unitary matrix size doesn't match state".to_string(),
));
}
self.state = unitary.dot(&self.state);
Ok(())
}
pub fn measure(&mut self) -> QuantRS2Result<usize> {
let probabilities = self.get_probabilities();
use scirs2_core::random::prelude::*;
let mut rng = thread_rng();
let random_value: f64 = rng.random();
let mut cumulative = 0.0;
for (i, &prob) in probabilities.iter().enumerate() {
cumulative += prob;
if random_value <= cumulative {
self.state.fill(Complex64::new(0.0, 0.0));
self.state[i] = Complex64::new(1.0, 0.0);
return Ok(i);
}
}
Ok(probabilities.len() - 1)
}
}
#[derive(Debug, Clone)]
pub struct SiliconQuantumDotSystem {
pub num_dots: usize,
pub dots: Vec<SiliconQuantumDot>,
pub coupling_matrix: Array2<f64>,
pub global_state: Option<Array1<Complex64>>,
pub device_params: DeviceParams,
}
#[derive(Debug, Clone)]
pub struct DeviceParams {
pub temperature: f64,
pub magnetic_field: [f64; 3],
pub electric_field: [f64; 3],
pub substrate: String,
pub oxide_thickness: f64,
}
impl DeviceParams {
pub fn typical_silicon_device() -> Self {
Self {
temperature: 0.01, magnetic_field: [0.0, 0.0, 0.1], electric_field: [0.0, 0.0, 0.0],
substrate: "Si/SiGe".to_string(),
oxide_thickness: 10.0, }
}
}
impl SiliconQuantumDotSystem {
pub fn new(
dot_configs: Vec<(QuantumDotType, QuantumDotParams, [f64; 2])>,
device_params: DeviceParams,
) -> Self {
let num_dots = dot_configs.len();
let dots: Vec<SiliconQuantumDot> = dot_configs
.into_iter()
.enumerate()
.map(|(id, (dot_type, params, position))| {
SiliconQuantumDot::new(id, dot_type, params, position)
})
.collect();
let coupling_matrix = Array2::zeros((num_dots, num_dots));
Self {
num_dots,
dots,
coupling_matrix,
global_state: None,
device_params,
}
}
pub fn set_coupling(&mut self, dot1: usize, dot2: usize, coupling: f64) -> QuantRS2Result<()> {
if dot1 >= self.num_dots || dot2 >= self.num_dots {
return Err(QuantRS2Error::InvalidInput(
"Dot index out of bounds".to_string(),
));
}
self.coupling_matrix[[dot1, dot2]] = coupling;
self.coupling_matrix[[dot2, dot1]] = coupling;
Ok(())
}
pub fn calculate_distance_coupling(&mut self) -> QuantRS2Result<()> {
for i in 0..self.num_dots {
for j in i + 1..self.num_dots {
let pos1 = self.dots[i].position;
let pos2 = self.dots[j].position;
let distance = (pos1[0] - pos2[0]).hypot(pos1[1] - pos2[1]);
let coupling = 1e-6 * (-distance / 100.0).exp(); self.set_coupling(i, j, coupling)?;
}
}
Ok(())
}
pub fn apply_exchange_interaction(
&mut self,
dot1: usize,
dot2: usize,
duration: f64,
) -> QuantRS2Result<()> {
if dot1 >= self.num_dots || dot2 >= self.num_dots {
return Err(QuantRS2Error::InvalidInput(
"Dot index out of bounds".to_string(),
));
}
let exchange_strength = self.coupling_matrix[[dot1, dot2]];
let rotation_angle = exchange_strength * duration / (6.582e-16);
let cos_theta = rotation_angle.cos();
let sin_theta = rotation_angle.sin();
let state1 = self.dots[dot1].state.clone();
let state2 = self.dots[dot2].state.clone();
if state1.len() == 2 && state2.len() == 2 {
let amp_00 = state1[0] * state2[0];
let amp_01 = state1[0] * state2[1];
let amp_10 = state1[1] * state2[0];
let _amp_11 = state1[1] * state2[1];
let new_01 = cos_theta * amp_01 + Complex64::new(0.0, 1.0) * sin_theta * amp_10;
let new_10 = cos_theta * amp_10 + Complex64::new(0.0, 1.0) * sin_theta * amp_01;
let norm1 = (amp_00.norm_sqr() + amp_10.norm_sqr()).sqrt();
let norm2 = (amp_00.norm_sqr() + amp_01.norm_sqr()).sqrt();
if norm1 > 1e-10 && norm2 > 1e-10 {
self.dots[dot1].state[0] = amp_00 / norm1;
self.dots[dot1].state[1] = new_10 / norm1;
self.dots[dot2].state[0] = amp_00 / norm2;
self.dots[dot2].state[1] = new_01 / norm2;
}
}
Ok(())
}
pub fn apply_magnetic_pulse(
&mut self,
target_dots: &[usize],
field_amplitude: f64,
duration: f64,
phase: f64,
) -> QuantRS2Result<()> {
for &dot_id in target_dots {
if dot_id >= self.num_dots {
return Err(QuantRS2Error::InvalidInput(
"Dot ID out of bounds".to_string(),
));
}
let dot = &mut self.dots[dot_id];
if dot.dot_type == QuantumDotType::SpinQubit && dot.state.len() == 2 {
let omega = field_amplitude * 2.0 * std::f64::consts::PI; let theta = omega * duration;
let cos_half = (theta / 2.0).cos();
let sin_half = (theta / 2.0).sin();
let old_state = dot.state.clone();
if phase.abs() < 1e-10 {
dot.state[0] =
cos_half * old_state[0] - Complex64::new(0.0, sin_half) * old_state[1];
dot.state[1] =
-Complex64::new(0.0, sin_half) * old_state[0] + cos_half * old_state[1];
} else if (phase - std::f64::consts::PI / 2.0).abs() < 1e-10 {
dot.state[0] = cos_half * old_state[0] - sin_half * old_state[1];
dot.state[1] = sin_half * old_state[0] + cos_half * old_state[1];
} else {
let phase_factor = Complex64::new(0.0, phase).exp();
dot.state[0] = cos_half * old_state[0]
- Complex64::new(0.0, sin_half) * phase_factor * old_state[1];
dot.state[1] =
-Complex64::new(0.0, sin_half) * phase_factor.conj() * old_state[0]
+ cos_half * old_state[1];
}
}
}
Ok(())
}
pub fn apply_electric_pulse(
&mut self,
target_dots: &[usize],
field_amplitude: f64,
duration: f64,
) -> QuantRS2Result<()> {
for &dot_id in target_dots {
if dot_id >= self.num_dots {
return Err(QuantRS2Error::InvalidInput(
"Dot ID out of bounds".to_string(),
));
}
let dot = &mut self.dots[dot_id];
if dot.dot_type == QuantumDotType::ChargeQubit && dot.state.len() == 2 {
let energy_shift = field_amplitude * 1.602e-19; let omega = energy_shift / (6.582e-16); let theta = omega * duration;
let phase_0 = Complex64::new(0.0, -theta / 2.0).exp();
let phase_1 = Complex64::new(0.0, theta / 2.0).exp();
dot.state[0] *= phase_0;
dot.state[1] *= phase_1;
}
}
Ok(())
}
pub fn apply_decoherence(&mut self, time_step: f64) -> QuantRS2Result<()> {
for dot in &mut self.dots {
let t2_star = dot.params.coherence_time();
let dephasing_prob = time_step / t2_star;
if dephasing_prob > 0.01 {
use scirs2_core::random::prelude::*;
let mut rng = thread_rng();
let phase_noise = rng.random_range(-dephasing_prob..dephasing_prob);
let noise_factor = Complex64::new(0.0, phase_noise).exp();
dot.state[1] *= noise_factor;
}
}
Ok(())
}
pub fn measure_all(&mut self) -> QuantRS2Result<Vec<usize>> {
let mut results = Vec::new();
for dot in &mut self.dots {
let result = dot.measure()?;
results.push(result);
}
Ok(results)
}
pub fn calculate_fidelity(&self, target_state: &[Vec<Complex64>]) -> f64 {
if target_state.len() != self.num_dots {
return 0.0;
}
let mut total_fidelity = 1.0;
for (i, dot) in self.dots.iter().enumerate() {
if target_state[i].len() != dot.state.len() {
return 0.0;
}
let overlap = dot
.state
.iter()
.zip(target_state[i].iter())
.map(|(a, b)| (a.conj() * b).norm_sqr())
.sum::<f64>();
total_fidelity *= overlap;
}
total_fidelity
}
pub fn average_coherence_time(&self) -> f64 {
let total_t2: f64 = self
.dots
.iter()
.map(|dot| dot.params.coherence_time())
.sum();
total_t2 / self.num_dots as f64
}
}
pub struct SiliconQuantumDotGates;
impl SiliconQuantumDotGates {
pub fn spin_x_rotation(
system: &mut SiliconQuantumDotSystem,
dot_id: usize,
angle: f64,
) -> QuantRS2Result<()> {
if dot_id >= system.num_dots {
return Err(QuantRS2Error::InvalidInput(
"Dot ID out of bounds".to_string(),
));
}
let field_amplitude = 1e-3;
let omega = field_amplitude * 2.0 * std::f64::consts::PI;
let duration = angle / omega;
system.apply_magnetic_pulse(&[dot_id], field_amplitude, duration, 0.0)
}
pub fn spin_y_rotation(
system: &mut SiliconQuantumDotSystem,
dot_id: usize,
angle: f64,
) -> QuantRS2Result<()> {
if dot_id >= system.num_dots {
return Err(QuantRS2Error::InvalidInput(
"Dot ID out of bounds".to_string(),
));
}
let field_amplitude = 1e-3;
let omega = field_amplitude * 2.0 * std::f64::consts::PI;
let duration = angle / omega;
system.apply_magnetic_pulse(
&[dot_id],
field_amplitude,
duration,
std::f64::consts::PI / 2.0,
)
}
pub fn spin_z_rotation(
system: &mut SiliconQuantumDotSystem,
dot_id: usize,
angle: f64,
) -> QuantRS2Result<()> {
if dot_id >= system.num_dots {
return Err(QuantRS2Error::InvalidInput(
"Dot ID out of bounds".to_string(),
));
}
let dot = &mut system.dots[dot_id];
let phase_factor = Complex64::new(0.0, angle / 2.0).exp();
dot.state[0] *= phase_factor.conj();
dot.state[1] *= phase_factor;
Ok(())
}
pub fn hadamard(system: &mut SiliconQuantumDotSystem, dot_id: usize) -> QuantRS2Result<()> {
if dot_id >= system.num_dots {
return Err(QuantRS2Error::InvalidInput(
"Dot ID out of bounds".to_string(),
));
}
let dot = &mut system.dots[dot_id];
if dot.dot_type == QuantumDotType::SpinQubit && dot.state.len() == 2 {
let old_state = dot.state.clone();
let inv_sqrt2 = 1.0 / std::f64::consts::SQRT_2;
dot.state[0] = inv_sqrt2 * (old_state[0] + old_state[1]);
dot.state[1] = inv_sqrt2 * (old_state[0] - old_state[1]);
}
Ok(())
}
pub fn cnot(
system: &mut SiliconQuantumDotSystem,
control: usize,
target: usize,
) -> QuantRS2Result<()> {
if control >= system.num_dots || target >= system.num_dots {
return Err(QuantRS2Error::InvalidInput(
"Dot ID out of bounds".to_string(),
));
}
let control_state = &system.dots[control].state;
let control_prob_1 = control_state[1].norm_sqr();
if control_prob_1 > 0.5 {
Self::spin_x_rotation(system, target, std::f64::consts::PI)?;
}
Ok(())
}
pub fn cz(
system: &mut SiliconQuantumDotSystem,
control: usize,
target: usize,
) -> QuantRS2Result<()> {
if control >= system.num_dots || target >= system.num_dots {
return Err(QuantRS2Error::InvalidInput(
"Dot ID out of bounds".to_string(),
));
}
let exchange_strength = system.coupling_matrix[[control, target]];
let gate_time = std::f64::consts::PI / (4.0 * exchange_strength / (6.582e-16));
system.apply_exchange_interaction(control, target, gate_time)
}
pub fn swap(
system: &mut SiliconQuantumDotSystem,
dot1: usize,
dot2: usize,
) -> QuantRS2Result<()> {
if dot1 >= system.num_dots || dot2 >= system.num_dots {
return Err(QuantRS2Error::InvalidInput(
"Dot ID out of bounds".to_string(),
));
}
let exchange_strength = system.coupling_matrix[[dot1, dot2]];
let gate_time = std::f64::consts::PI / (2.0 * exchange_strength / (6.582e-16));
system.apply_exchange_interaction(dot1, dot2, gate_time)
}
pub fn toffoli(
system: &mut SiliconQuantumDotSystem,
control1: usize,
control2: usize,
target: usize,
) -> QuantRS2Result<()> {
Self::hadamard(system, target)?;
Self::cnot(system, control2, target)?;
Self::spin_z_rotation(system, target, -std::f64::consts::PI / 4.0)?;
Self::cnot(system, control1, target)?;
Self::spin_z_rotation(system, target, std::f64::consts::PI / 4.0)?;
Self::cnot(system, control2, target)?;
Self::spin_z_rotation(system, target, -std::f64::consts::PI / 4.0)?;
Self::cnot(system, control1, target)?;
Self::spin_z_rotation(system, control1, std::f64::consts::PI / 4.0)?;
Self::spin_z_rotation(system, control2, std::f64::consts::PI / 4.0)?;
Self::spin_z_rotation(system, target, std::f64::consts::PI / 4.0)?;
Self::hadamard(system, target)?;
Self::cnot(system, control1, control2)?;
Self::spin_z_rotation(system, control1, std::f64::consts::PI / 4.0)?;
Self::spin_z_rotation(system, control2, -std::f64::consts::PI / 4.0)?;
Self::cnot(system, control1, control2)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_quantum_dot_params() {
let params = QuantumDotParams::typical_silicon_dot();
assert!(params.diameter > 0.0);
assert!(params.coherence_time() > 0.0);
assert!(params.single_qubit_gate_time() > 0.0);
assert!(params.two_qubit_gate_time() > 0.0);
}
#[test]
fn test_silicon_quantum_dot_creation() {
let params = QuantumDotParams::typical_silicon_dot();
let dot = SiliconQuantumDot::new(0, QuantumDotType::SpinQubit, params, [0.0, 0.0]);
assert_eq!(dot.dot_id, 0);
assert_eq!(dot.dot_type, QuantumDotType::SpinQubit);
assert_eq!(dot.state.len(), 2);
assert!((dot.state[0] - Complex64::new(1.0, 0.0)).norm() < 1e-10);
}
#[test]
fn test_quantum_dot_system() {
let params = QuantumDotParams::typical_silicon_dot();
let device_params = DeviceParams::typical_silicon_device();
let dot_configs = vec![
(QuantumDotType::SpinQubit, params.clone(), [0.0, 0.0]),
(QuantumDotType::SpinQubit, params, [100.0, 0.0]), ];
let mut system = SiliconQuantumDotSystem::new(dot_configs, device_params);
assert_eq!(system.num_dots, 2);
system
.calculate_distance_coupling()
.expect("distance coupling calculation should succeed");
assert!(system.coupling_matrix[[0, 1]] > 0.0);
}
#[test]
fn test_gate_voltage_effects() {
let params = QuantumDotParams::typical_silicon_dot();
let mut dot = SiliconQuantumDot::new(0, QuantumDotType::ChargeQubit, params, [0.0, 0.0]);
let initial_charging_energy = dot.params.charging_energy;
dot.set_gate_voltage("plunger1".to_string(), 0.1);
assert!((dot.params.charging_energy - initial_charging_energy).abs() > 1e-10);
}
#[test]
fn test_magnetic_pulse() {
let params = QuantumDotParams::typical_silicon_dot();
let device_params = DeviceParams::typical_silicon_device();
let dot_configs = vec![(QuantumDotType::SpinQubit, params, [0.0, 0.0])];
let mut system = SiliconQuantumDotSystem::new(dot_configs, device_params);
let field_amplitude = 1e-3;
let omega = field_amplitude * 2.0 * std::f64::consts::PI;
let duration = std::f64::consts::PI / omega; system
.apply_magnetic_pulse(&[0], field_amplitude, duration, 0.0)
.expect("magnetic pulse application should succeed");
let probs = system.dots[0].get_probabilities();
assert!(probs[1] > 0.8);
}
#[test]
fn test_exchange_interaction() {
let params = QuantumDotParams::typical_silicon_dot();
let device_params = DeviceParams::typical_silicon_device();
let dot_configs = vec![
(QuantumDotType::SpinQubit, params.clone(), [0.0, 0.0]),
(QuantumDotType::SpinQubit, params, [50.0, 0.0]),
];
let mut system = SiliconQuantumDotSystem::new(dot_configs, device_params);
system
.set_coupling(0, 1, 1e-6)
.expect("set_coupling should succeed");
let duration = 1e-9; system
.apply_exchange_interaction(0, 1, duration)
.expect("exchange interaction should succeed");
let state1 = system.dots[0].get_probabilities();
let state2 = system.dots[1].get_probabilities();
assert!(state1.len() == 2);
assert!(state2.len() == 2);
}
#[test]
fn test_measurement() {
let params = QuantumDotParams::typical_silicon_dot();
let device_params = DeviceParams::typical_silicon_device();
let dot_configs = vec![(QuantumDotType::SpinQubit, params, [0.0, 0.0])];
let mut system = SiliconQuantumDotSystem::new(dot_configs, device_params);
system.dots[0].state[0] = Complex64::new(1.0 / 2.0_f64.sqrt(), 0.0);
system.dots[0].state[1] = Complex64::new(1.0 / 2.0_f64.sqrt(), 0.0);
let result = system.dots[0]
.measure()
.expect("measurement should succeed");
assert!(result == 0 || result == 1);
let probs = system.dots[0].get_probabilities();
assert!(probs[result] > 0.99);
}
#[test]
fn test_silicon_gates() {
let params = QuantumDotParams::typical_silicon_dot();
let device_params = DeviceParams::typical_silicon_device();
let dot_configs = vec![(QuantumDotType::SpinQubit, params, [0.0, 0.0])];
let mut system = SiliconQuantumDotSystem::new(dot_configs, device_params);
SiliconQuantumDotGates::spin_x_rotation(&mut system, 0, std::f64::consts::PI)
.expect("spin X rotation should succeed");
let probs = system.dots[0].get_probabilities();
assert!(probs[1] > 0.8);
SiliconQuantumDotGates::hadamard(&mut system, 0).expect("hadamard gate should succeed");
let probs = system.dots[0].get_probabilities();
assert!(probs[0] > 0.05 && probs[0] < 0.95); }
#[test]
fn test_cnot_gate() {
let params = QuantumDotParams::typical_silicon_dot();
let device_params = DeviceParams::typical_silicon_device();
let dot_configs = vec![
(QuantumDotType::SpinQubit, params.clone(), [0.0, 0.0]),
(QuantumDotType::SpinQubit, params, [50.0, 0.0]),
];
let mut system = SiliconQuantumDotSystem::new(dot_configs, device_params);
system
.set_coupling(0, 1, 1e-3)
.expect("set_coupling should succeed");
SiliconQuantumDotGates::spin_x_rotation(&mut system, 0, std::f64::consts::PI)
.expect("spin X rotation should succeed");
SiliconQuantumDotGates::cnot(&mut system, 0, 1).expect("CNOT gate should succeed");
let target_probs = system.dots[1].get_probabilities();
assert!(target_probs[1] > 0.1); }
#[test]
fn test_decoherence() {
let params = QuantumDotParams::typical_silicon_dot();
let device_params = DeviceParams::typical_silicon_device();
let dot_configs = vec![(QuantumDotType::SpinQubit, params, [0.0, 0.0])];
let mut system = SiliconQuantumDotSystem::new(dot_configs, device_params);
system.dots[0].state[0] = Complex64::new(1.0 / 2.0_f64.sqrt(), 0.0);
system.dots[0].state[1] = Complex64::new(1.0 / 2.0_f64.sqrt(), 0.0);
let initial_state = system.dots[0].state.clone();
system
.apply_decoherence(1e-6)
.expect("decoherence application should succeed");
let final_state = system.dots[0].state.clone();
let diff = &initial_state - &final_state;
let state_change = diff.iter().map(|x| x.norm_sqr()).sum::<f64>().sqrt();
assert!(state_change.is_finite());
}
#[test]
fn test_fidelity_calculation() {
let params = QuantumDotParams::typical_silicon_dot();
let device_params = DeviceParams::typical_silicon_device();
let dot_configs = vec![(QuantumDotType::SpinQubit, params, [0.0, 0.0])];
let system = SiliconQuantumDotSystem::new(dot_configs, device_params);
let target_state = vec![vec![Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)]];
let fidelity = system.calculate_fidelity(&target_state);
assert!((fidelity - 1.0).abs() < 1e-10); }
#[test]
fn test_coherence_time_average() {
let params = QuantumDotParams::typical_silicon_dot();
let device_params = DeviceParams::typical_silicon_device();
let dot_configs = vec![
(QuantumDotType::SpinQubit, params.clone(), [0.0, 0.0]),
(QuantumDotType::SpinQubit, params, [50.0, 0.0]),
];
let system = SiliconQuantumDotSystem::new(dot_configs, device_params);
let avg_t2 = system.average_coherence_time();
assert!(avg_t2 > 0.0);
assert!(avg_t2.is_finite());
}
}