use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use nalgebra::Complex;
use rand::{thread_rng, Rng};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QuantumMeasurement {
pub bit_string: String,
pub probability: f64,
pub fidelity: f64,
pub entanglement_entropy: f64,
pub measurement_time_ns: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SuperpositionResult {
pub qubits: usize,
pub amplitudes: Vec<(f64, f64)>, pub state_labels: Vec<String>,
pub total_probability: f64,
pub creation_time_ns: u64,
}
#[derive(Debug)]
pub struct SimpleQuantumContainer {
qubits: usize,
amplitudes: Vec<Complex<f64>>,
noise_level: f64,
}
impl SimpleQuantumContainer {
pub fn new(qubits: usize, enable_noise: bool) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
let num_states = 1 << qubits;
let mut amplitudes = vec![Complex::new(0.0, 0.0); num_states];
amplitudes[0] = Complex::new(1.0, 0.0);
let noise_level = if enable_noise { 1e-4 } else { 0.0 };
Ok(Self {
qubits,
amplitudes,
noise_level,
})
}
pub async fn create_superposition(&mut self) -> Result<SuperpositionResult, Box<dyn std::error::Error + Send + Sync>> {
let start_time = std::time::Instant::now();
let num_states = self.amplitudes.len();
for qubit in 0..self.qubits {
self.apply_hadamard(qubit).await?;
}
if self.noise_level > 0.0 {
self.apply_noise().await?;
}
self.normalize_state();
let creation_time_ns = start_time.elapsed().as_nanos() as u64;
let amplitudes: Vec<(f64, f64)> = self.amplitudes.iter()
.map(|c| (c.norm(), c.arg()))
.collect();
let state_labels: Vec<String> = (0..num_states)
.map(|i| format!("{:0width$b}", i, width = self.qubits))
.collect();
let total_probability: f64 = self.amplitudes.iter()
.map(|c| c.norm_sqr())
.sum();
Ok(SuperpositionResult {
qubits: self.qubits,
amplitudes,
state_labels,
total_probability,
creation_time_ns,
})
}
pub async fn measure(&mut self) -> Result<QuantumMeasurement, Box<dyn std::error::Error + Send + Sync>> {
let start_time = std::time::Instant::now();
let mut rng = thread_rng();
let probabilities: Vec<f64> = self.amplitudes.iter()
.map(|c| c.norm_sqr())
.collect();
let random_value: f64 = rng.gen();
let mut cumulative_prob = 0.0;
let mut measured_state = 0;
let mut measurement_probability = 0.0;
for (state_idx, &prob) in probabilities.iter().enumerate() {
cumulative_prob += prob;
if random_value <= cumulative_prob {
measured_state = state_idx;
measurement_probability = prob;
break;
}
}
let bit_string = format!("{:0width$b}", measured_state, width = self.qubits);
let fidelity = measurement_probability;
let entanglement_entropy = self.calculate_entanglement_entropy();
self.collapse_to_state(measured_state);
let measurement_time_ns = start_time.elapsed().as_nanos() as u64;
Ok(QuantumMeasurement {
bit_string,
probability: measurement_probability,
fidelity,
entanglement_entropy,
measurement_time_ns,
})
}
async fn apply_hadamard(&mut self, target_qubit: usize) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
if target_qubit >= self.qubits {
return Err("Target qubit index out of range".into());
}
let num_states = self.amplitudes.len();
let mut new_amplitudes = self.amplitudes.clone();
let h_factor = 1.0 / 2.0_f64.sqrt();
for state in 0..num_states {
if (state >> target_qubit) & 1 == 0 {
let partner_state = state | (1 << target_qubit);
if partner_state < num_states {
let amp0 = self.amplitudes[state];
let amp1 = self.amplitudes[partner_state];
new_amplitudes[state] = h_factor * (amp0 + amp1);
new_amplitudes[partner_state] = h_factor * (amp0 - amp1);
}
}
}
self.amplitudes = new_amplitudes;
Ok(())
}
async fn apply_noise(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let mut rng = thread_rng();
for amplitude in &mut self.amplitudes {
let phase_noise = rng.gen::<f64>() * self.noise_level * 2.0 * std::f64::consts::PI;
*amplitude *= Complex::new(0.0, phase_noise).exp();
let damping = 1.0 - self.noise_level;
*amplitude *= damping;
}
Ok(())
}
fn normalize_state(&mut self) {
let norm_sq: f64 = self.amplitudes.iter().map(|c| c.norm_sqr()).sum();
let norm = norm_sq.sqrt();
if norm > 1e-10 {
for amplitude in &mut self.amplitudes {
*amplitude /= norm;
}
}
}
fn calculate_entanglement_entropy(&self) -> f64 {
if self.qubits <= 1 {
return 0.0;
}
let mut entropy = 0.0;
let num_states = self.amplitudes.len();
for amplitude in &self.amplitudes {
let prob = amplitude.norm_sqr();
if prob > 1e-12 {
entropy -= prob * prob.ln();
}
}
let max_entropy = (num_states as f64).ln();
if max_entropy > 0.0 {
entropy / max_entropy
} else {
0.0
}
}
fn collapse_to_state(&mut self, state: usize) {
for (i, amplitude) in self.amplitudes.iter_mut().enumerate() {
if i == state {
*amplitude = Complex::new(1.0, 0.0);
} else {
*amplitude = Complex::new(0.0, 0.0);
}
}
}
}
pub async fn create_enhanced_quantum_container(
qubits: usize,
enable_noise: bool
) -> Result<SimpleQuantumContainer, Box<dyn std::error::Error + Send + Sync>> {
SimpleQuantumContainer::new(qubits, enable_noise)
}
#[cfg(all(target_arch = "wasm32", feature = "wasm"))]
use wasm_bindgen::prelude::*;
#[cfg(all(target_arch = "wasm32", feature = "wasm"))]
#[wasm_bindgen]
pub async fn quantum_create_enhanced(qubits: usize) -> Result<String, JsValue> {
match create_enhanced_quantum_container(qubits, true).await {
Ok(mut container) => {
match container.create_superposition().await {
Ok(result) => Ok(serde_json::to_string(&result).map_err(|e| JsValue::from_str(&e.to_string()))?),
Err(e) => Err(JsValue::from_str(&format!("Superposition failed: {}", e))),
}
}
Err(e) => Err(JsValue::from_str(&format!("Container creation failed: {}", e))),
}
}
#[cfg(all(target_arch = "wasm32", feature = "wasm"))]
#[wasm_bindgen]
pub async fn quantum_measure_enhanced(qubits: usize) -> Result<String, JsValue> {
match create_enhanced_quantum_container(qubits, true).await {
Ok(mut container) => {
container.create_superposition().await
.map_err(|e| JsValue::from_str(&format!("Superposition failed: {}", e)))?;
match container.measure().await {
Ok(result) => Ok(serde_json::to_string(&result).map_err(|e| JsValue::from_str(&e.to_string()))?),
Err(e) => Err(JsValue::from_str(&format!("Measurement failed: {}", e))),
}
}
Err(e) => Err(JsValue::from_str(&format!("Container creation failed: {}", e))),
}
}