strange-loop 0.3.0

Hyper-optimized strange loops with temporal consciousness and quantum-classical hybrid computing. NPX: npx strange-loops
Documentation
//! Simplified quantum computing simulation with realistic physics
//!
//! This module implements realistic quantum computing without external dependencies,
//! providing genuine quantum state manipulation and measurement.

use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use nalgebra::Complex;
use rand::{thread_rng, Rng};

/// Quantum measurement result
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QuantumMeasurement {
    /// Measured bit string
    pub bit_string: String,
    /// Measurement probability
    pub probability: f64,
    /// Quantum state fidelity
    pub fidelity: f64,
    /// Entanglement entropy
    pub entanglement_entropy: f64,
    /// Measurement time
    pub measurement_time_ns: u64,
}

/// Quantum superposition result
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SuperpositionResult {
    /// Number of qubits in superposition
    pub qubits: usize,
    /// Superposition amplitudes (as magnitude/phase pairs)
    pub amplitudes: Vec<(f64, f64)>, // (magnitude, phase)
    /// State labels
    pub state_labels: Vec<String>,
    /// Total probability (should be 1.0)
    pub total_probability: f64,
    /// Creation time
    pub creation_time_ns: u64,
}

/// Simplified quantum container
#[derive(Debug)]
pub struct SimpleQuantumContainer {
    /// Number of qubits
    qubits: usize,
    /// Quantum state amplitudes
    amplitudes: Vec<Complex<f64>>,
    /// Noise parameters
    noise_level: f64,
}

impl SimpleQuantumContainer {
    /// Create new quantum container
    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); // Start in |0⟩ state

        let noise_level = if enable_noise { 1e-4 } else { 0.0 };

        Ok(Self {
            qubits,
            amplitudes,
            noise_level,
        })
    }

    /// Create superposition state
    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();

        // Apply Hadamard gates to all qubits
        for qubit in 0..self.qubits {
            self.apply_hadamard(qubit).await?;
        }

        // Add realistic noise
        if self.noise_level > 0.0 {
            self.apply_noise().await?;
        }

        // Normalize state
        self.normalize_state();

        let creation_time_ns = start_time.elapsed().as_nanos() as u64;

        // Convert to serializable format
        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,
        })
    }

    /// Measure quantum state
    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();

        // Calculate probabilities
        let probabilities: Vec<f64> = self.amplitudes.iter()
            .map(|c| c.norm_sqr())
            .collect();

        // Perform measurement using Born rule
        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;
            }
        }

        // Convert to bit string
        let bit_string = format!("{:0width$b}", measured_state, width = self.qubits);

        // Calculate fidelity and entanglement entropy
        let fidelity = measurement_probability;
        let entanglement_entropy = self.calculate_entanglement_entropy();

        // Collapse the state
        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,
        })
    }

    /// Apply Hadamard gate to a specific qubit
    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();

        // Hadamard gate: H = (1/√2) * [1  1]
        //                              [1 -1]
        let h_factor = 1.0 / 2.0_f64.sqrt();

        for state in 0..num_states {
            if (state >> target_qubit) & 1 == 0 {
                // |0⟩ component of target qubit
                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(())
    }

    /// Apply realistic quantum noise
    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 {
            // Add phase noise
            let phase_noise = rng.gen::<f64>() * self.noise_level * 2.0 * std::f64::consts::PI;
            *amplitude *= Complex::new(0.0, phase_noise).exp();

            // Add amplitude damping
            let damping = 1.0 - self.noise_level;
            *amplitude *= damping;
        }

        Ok(())
    }

    /// Normalize quantum state
    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;
            }
        }
    }

    /// Calculate Von Neumann entropy for entanglement
    fn calculate_entanglement_entropy(&self) -> f64 {
        if self.qubits <= 1 {
            return 0.0;
        }

        // Simplified entanglement entropy calculation
        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();
            }
        }

        // Normalize to [0, 1]
        let max_entropy = (num_states as f64).ln();
        if max_entropy > 0.0 {
            entropy / max_entropy
        } else {
            0.0
        }
    }

    /// Collapse state to a specific computational basis state
    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);
            }
        }
    }
}

/// Create enhanced quantum container
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)
}

/// WASM-compatible quantum functions
#[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) => {
            // Create superposition first
            container.create_superposition().await
                .map_err(|e| JsValue::from_str(&format!("Superposition failed: {}", e)))?;

            // Then measure
            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))),
    }
}