quantrs2_device/neutral_atom/
mod.rs

1//! Neutral atom quantum computing device interfaces
2//!
3//! This module provides support for neutral atom quantum computers, including
4//! Rydberg atom systems, optical tweezer arrays, and neutral atom gate operations.
5
6use crate::{CircuitExecutor, CircuitResult, DeviceError, DeviceResult, QuantumDevice};
7use quantrs2_circuit::prelude::Circuit;
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10use std::time::Duration;
11
12pub mod client;
13pub mod config;
14pub mod device;
15pub mod gate_operations;
16pub mod protocols;
17pub mod rydberg;
18pub mod tweezer_arrays;
19
20pub use client::NeutralAtomClient;
21pub use device::NeutralAtomDevice;
22
23/// Types of neutral atom quantum computing systems
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
25pub enum NeutralAtomSystemType {
26    /// Rydberg atom systems
27    Rydberg,
28    /// Optical tweezer arrays
29    OpticalTweezer,
30    /// Magnetic trap arrays
31    MagneticTrap,
32    /// Hybrid neutral atom systems
33    Hybrid,
34}
35
36/// Neutral atom state encoding
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
38pub enum AtomStateEncoding {
39    /// Ground and excited states
40    GroundExcited,
41    /// Hyperfine states
42    Hyperfine,
43    /// Clock states
44    Clock,
45    /// Zeeman states
46    Zeeman,
47}
48
49/// Configuration for neutral atom quantum devices
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct NeutralAtomDeviceConfig {
52    /// Type of neutral atom system
53    pub system_type: NeutralAtomSystemType,
54    /// Number of atoms in the array
55    pub atom_count: usize,
56    /// Atom spacing in micrometers
57    pub atom_spacing: f64,
58    /// State encoding scheme
59    pub state_encoding: AtomStateEncoding,
60    /// Rydberg blockade radius in micrometers
61    pub blockade_radius: Option<f64>,
62    /// Laser wavelength in nanometers
63    pub laser_wavelength: Option<f64>,
64    /// Trap depth in microkelvin
65    pub trap_depth: Option<f64>,
66    /// Gate fidelity
67    pub gate_fidelity: Option<f64>,
68    /// Measurement fidelity
69    pub measurement_fidelity: Option<f64>,
70    /// Loading efficiency
71    pub loading_efficiency: Option<f64>,
72    /// Maximum execution time
73    pub max_execution_time: Option<Duration>,
74    /// Enable hardware acceleration
75    pub hardware_acceleration: bool,
76    /// Custom hardware parameters
77    pub hardware_params: HashMap<String, String>,
78}
79
80impl Default for NeutralAtomDeviceConfig {
81    fn default() -> Self {
82        Self {
83            system_type: NeutralAtomSystemType::Rydberg,
84            atom_count: 100,
85            atom_spacing: 5.0,
86            state_encoding: AtomStateEncoding::GroundExcited,
87            blockade_radius: Some(8.0),
88            laser_wavelength: Some(480.0),
89            trap_depth: Some(1000.0),
90            gate_fidelity: Some(0.995),
91            measurement_fidelity: Some(0.99),
92            loading_efficiency: Some(0.95),
93            max_execution_time: Some(Duration::from_secs(60)),
94            hardware_acceleration: true,
95            hardware_params: HashMap::new(),
96        }
97    }
98}
99
100/// Result of neutral atom quantum circuit execution
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct NeutralAtomCircuitResult {
103    /// Standard circuit result
104    pub circuit_result: CircuitResult,
105    /// Neutral atom-specific results
106    pub neutral_atom_data: NeutralAtomMeasurementData,
107    /// Execution metadata
108    pub execution_metadata: NeutralAtomExecutionMetadata,
109}
110
111/// Neutral atom measurement data
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct NeutralAtomMeasurementData {
114    /// Atom positions in the array
115    pub atom_positions: Vec<(f64, f64, f64)>,
116    /// Atom state measurements
117    pub atom_states: Vec<String>,
118    /// Rydberg excitation patterns
119    pub rydberg_patterns: Vec<Vec<bool>>,
120    /// Correlation measurements
121    pub correlations: HashMap<String, f64>,
122    /// Fidelity estimates
123    pub fidelities: HashMap<String, f64>,
124    /// Loading success rates
125    pub loading_success: Vec<bool>,
126}
127
128/// Neutral atom execution metadata
129#[derive(Debug, Clone, Serialize, Deserialize)]
130pub struct NeutralAtomExecutionMetadata {
131    /// System type used
132    pub system_type: NeutralAtomSystemType,
133    /// Number of atoms used
134    pub atoms_used: usize,
135    /// Actual execution time
136    pub execution_time: Duration,
137    /// Gate sequence applied
138    pub gate_sequence: Vec<String>,
139    /// Optimization applied
140    pub optimizations_applied: Vec<String>,
141    /// Temperature during execution
142    pub temperature: Option<f64>,
143    /// Laser power used
144    pub laser_power: Option<f64>,
145}
146
147impl Default for NeutralAtomMeasurementData {
148    fn default() -> Self {
149        Self {
150            atom_positions: Vec::new(),
151            atom_states: Vec::new(),
152            rydberg_patterns: Vec::new(),
153            correlations: HashMap::new(),
154            fidelities: HashMap::new(),
155            loading_success: Vec::new(),
156        }
157    }
158}
159
160impl Default for NeutralAtomExecutionMetadata {
161    fn default() -> Self {
162        Self {
163            system_type: NeutralAtomSystemType::Rydberg,
164            atoms_used: 0,
165            execution_time: Duration::from_millis(0),
166            gate_sequence: Vec::new(),
167            optimizations_applied: Vec::new(),
168            temperature: None,
169            laser_power: None,
170        }
171    }
172}
173
174/// Trait for neutral atom quantum devices
175#[async_trait::async_trait]
176pub trait NeutralAtomQuantumDevice: QuantumDevice + CircuitExecutor {
177    /// Get the neutral atom system type
178    async fn system_type(&self) -> DeviceResult<NeutralAtomSystemType>;
179
180    /// Get the number of atoms in the array
181    async fn atom_count(&self) -> DeviceResult<usize>;
182
183    /// Get the atom spacing
184    async fn atom_spacing(&self) -> DeviceResult<f64>;
185
186    /// Get the state encoding scheme
187    async fn state_encoding(&self) -> DeviceResult<AtomStateEncoding>;
188
189    /// Get the Rydberg blockade radius
190    async fn blockade_radius(&self) -> DeviceResult<Option<f64>>;
191
192    /// Check if Rydberg gates are supported
193    async fn supports_rydberg_gates(&self) -> DeviceResult<bool>;
194
195    /// Check if optical tweezer manipulation is supported
196    async fn supports_tweezer_manipulation(&self) -> DeviceResult<bool>;
197
198    /// Get loading efficiency
199    async fn loading_efficiency(&self) -> DeviceResult<f64>;
200
201    /// Get gate fidelity
202    async fn gate_fidelity(&self) -> DeviceResult<f64>;
203
204    /// Execute a neutral atom circuit with detailed results
205    async fn execute_neutral_atom_circuit<const N: usize>(
206        &self,
207        circuit: &Circuit<N>,
208        shots: usize,
209        config: Option<NeutralAtomDeviceConfig>,
210    ) -> DeviceResult<NeutralAtomCircuitResult>;
211
212    /// Load atoms into the trap array
213    async fn load_atoms(&self, positions: &[(f64, f64, f64)]) -> DeviceResult<Vec<bool>>;
214
215    /// Move atoms using optical tweezers
216    async fn move_atoms(
217        &self,
218        atom_indices: &[usize],
219        new_positions: &[(f64, f64, f64)],
220    ) -> DeviceResult<()>;
221
222    /// Perform Rydberg excitation
223    async fn rydberg_excitation(
224        &self,
225        atom_indices: &[usize],
226        excitation_time: Duration,
227        laser_power: f64,
228    ) -> DeviceResult<Vec<bool>>;
229
230    /// Perform global Rydberg operations
231    async fn global_rydberg_operation(
232        &self,
233        operation: &str,
234        parameters: &HashMap<String, f64>,
235    ) -> DeviceResult<()>;
236
237    /// Measure atom states
238    async fn measure_atom_states(&self, atom_indices: &[usize]) -> DeviceResult<Vec<String>>;
239
240    /// Calculate atom correlations
241    async fn calculate_atom_correlations(
242        &self,
243        atom_pairs: &[(usize, usize)],
244        correlation_type: &str,
245    ) -> DeviceResult<HashMap<String, f64>>;
246
247    /// Estimate state fidelity
248    async fn estimate_fidelity(
249        &self,
250        target_state: &str,
251        measurement_data: &NeutralAtomMeasurementData,
252    ) -> DeviceResult<f64>;
253}
254
255/// Create a neutral atom quantum device
256pub fn create_neutral_atom_device(
257    client: NeutralAtomClient,
258    device_id: String,
259    config: NeutralAtomDeviceConfig,
260) -> DeviceResult<NeutralAtomDevice> {
261    Ok(NeutralAtomDevice::new(client, device_id, config))
262}
263
264/// Validate neutral atom device configuration
265pub fn validate_neutral_atom_config(config: &NeutralAtomDeviceConfig) -> DeviceResult<()> {
266    if config.atom_count == 0 {
267        return Err(DeviceError::InvalidInput(
268            "Atom count must be greater than 0".to_string(),
269        ));
270    }
271
272    if config.atom_spacing <= 0.0 {
273        return Err(DeviceError::InvalidInput(
274            "Atom spacing must be positive".to_string(),
275        ));
276    }
277
278    if let Some(blockade_radius) = config.blockade_radius {
279        if blockade_radius <= 0.0 {
280            return Err(DeviceError::InvalidInput(
281                "Blockade radius must be positive".to_string(),
282            ));
283        }
284    }
285
286    if let Some(fidelity) = config.gate_fidelity {
287        if fidelity < 0.0 || fidelity > 1.0 {
288            return Err(DeviceError::InvalidInput(
289                "Gate fidelity must be between 0 and 1".to_string(),
290            ));
291        }
292    }
293
294    if let Some(efficiency) = config.loading_efficiency {
295        if efficiency < 0.0 || efficiency > 1.0 {
296            return Err(DeviceError::InvalidInput(
297                "Loading efficiency must be between 0 and 1".to_string(),
298            ));
299        }
300    }
301
302    Ok(())
303}
304
305/// Neutral atom gate operations
306pub mod gates {
307    use super::*;
308
309    /// Rydberg excitation gate parameters
310    #[derive(Debug, Clone, Serialize, Deserialize)]
311    pub struct RydbergExcitationGate {
312        pub atom_index: usize,
313        pub excitation_time: Duration,
314        pub laser_power: f64,
315        pub detuning: f64,
316    }
317
318    /// Rydberg blockade gate parameters
319    #[derive(Debug, Clone, Serialize, Deserialize)]
320    pub struct RydbergBlockadeGate {
321        pub control_atom: usize,
322        pub target_atom: usize,
323        pub blockade_strength: f64,
324        pub interaction_time: Duration,
325    }
326
327    /// Global Rydberg gate parameters
328    #[derive(Debug, Clone, Serialize, Deserialize)]
329    pub struct GlobalRydbergGate {
330        pub operation_type: String,
331        pub laser_power: f64,
332        pub pulse_duration: Duration,
333        pub phase: f64,
334    }
335
336    /// Optical tweezer movement parameters
337    #[derive(Debug, Clone, Serialize, Deserialize)]
338    pub struct TweezerMovementGate {
339        pub atom_index: usize,
340        pub start_position: (f64, f64, f64),
341        pub end_position: (f64, f64, f64),
342        pub movement_time: Duration,
343    }
344
345    /// Hyperfine state manipulation parameters
346    #[derive(Debug, Clone, Serialize, Deserialize)]
347    pub struct HyperfineGate {
348        pub atom_index: usize,
349        pub target_state: String,
350        pub microwave_frequency: f64,
351        pub pulse_duration: Duration,
352    }
353}
354
355#[cfg(test)]
356mod tests {
357    use super::*;
358
359    #[test]
360    fn test_neutral_atom_config_validation() {
361        let valid_config = NeutralAtomDeviceConfig::default();
362        assert!(validate_neutral_atom_config(&valid_config).is_ok());
363
364        let invalid_config = NeutralAtomDeviceConfig {
365            atom_count: 0,
366            ..Default::default()
367        };
368        assert!(validate_neutral_atom_config(&invalid_config).is_err());
369    }
370
371    #[test]
372    fn test_neutral_atom_system_types() {
373        let rydberg_system = NeutralAtomSystemType::Rydberg;
374        assert_eq!(rydberg_system, NeutralAtomSystemType::Rydberg);
375
376        let tweezer_system = NeutralAtomSystemType::OpticalTweezer;
377        assert_eq!(tweezer_system, NeutralAtomSystemType::OpticalTweezer);
378    }
379
380    #[test]
381    fn test_atom_state_encoding() {
382        let ground_excited = AtomStateEncoding::GroundExcited;
383        assert_eq!(ground_excited, AtomStateEncoding::GroundExcited);
384
385        let hyperfine = AtomStateEncoding::Hyperfine;
386        assert_eq!(hyperfine, AtomStateEncoding::Hyperfine);
387    }
388}