oxirs_vec/
quantum_search.rs

1//! Quantum-inspired algorithms for vector search optimization.
2//!
3//! This module implements quantum computing principles to enhance vector search
4//! performance through quantum superposition, entanglement, and interference patterns.
5//! These algorithms provide novel optimization approaches that can outperform
6//! classical algorithms in specific scenarios, particularly for high-dimensional
7//! similarity search and complex optimization landscapes.
8
9use crate::random_utils::NormalSampler as Normal;
10use crate::Vector;
11use anyhow::{anyhow, Result};
12use oxirs_core::parallel::*;
13use oxirs_core::simd::SimdOps;
14use scirs2_core::random::{Random, Rng};
15use scirs2_core::rngs::StdRng;
16use serde::{Deserialize, Serialize};
17use std::collections::HashMap;
18use std::sync::{Arc, RwLock};
19use tracing::{debug, info, span, Level};
20
21/// Quantum-inspired search configuration
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct QuantumSearchConfig {
24    /// Number of quantum superposition states
25    pub superposition_states: usize,
26    /// Entanglement strength between vectors
27    pub entanglement_strength: f32,
28    /// Interference pattern amplification factor
29    pub interference_amplitude: f32,
30    /// Quantum measurement probability threshold
31    pub measurement_threshold: f32,
32    /// Maximum quantum search iterations
33    pub max_iterations: usize,
34    /// Enable quantum tunneling optimization
35    pub enable_tunneling: bool,
36    /// Quantum decoherence rate
37    pub decoherence_rate: f32,
38}
39
40impl Default for QuantumSearchConfig {
41    fn default() -> Self {
42        Self {
43            superposition_states: 64,
44            entanglement_strength: 0.7,
45            interference_amplitude: 1.2,
46            measurement_threshold: 0.1,
47            max_iterations: 100,
48            enable_tunneling: true,
49            decoherence_rate: 0.05,
50        }
51    }
52}
53
54/// Quantum state representation for vector search
55#[derive(Debug, Clone)]
56pub struct QuantumState {
57    /// Amplitude coefficients for superposition states
58    pub amplitudes: Vec<f32>,
59    /// Phase information for quantum interference
60    pub phases: Vec<f32>,
61    /// Entanglement matrix between states
62    pub entanglement_matrix: Vec<Vec<f32>>,
63    /// Probability distribution over states
64    pub probabilities: Vec<f32>,
65}
66
67impl QuantumState {
68    /// Create a new quantum state with given number of states
69    pub fn new(num_states: usize) -> Self {
70        let amplitudes = vec![1.0 / (num_states as f32).sqrt(); num_states];
71        let phases = vec![0.0; num_states];
72        let entanglement_matrix = vec![vec![0.0; num_states]; num_states];
73        let probabilities = vec![1.0 / num_states as f32; num_states];
74
75        Self {
76            amplitudes,
77            phases,
78            entanglement_matrix,
79            probabilities,
80        }
81    }
82
83    /// Apply quantum superposition to create multiple search paths
84    pub fn apply_superposition(&mut self, config: &QuantumSearchConfig) {
85        let num_states = self.amplitudes.len();
86
87        for i in 0..num_states {
88            // Apply Hadamard-like transformation for superposition
89            let angle = std::f32::consts::PI * i as f32 / num_states as f32;
90            self.amplitudes[i] = (angle.cos() * config.interference_amplitude).abs();
91            self.phases[i] = angle.sin() * config.interference_amplitude;
92        }
93
94        self.normalize();
95    }
96
97    /// Create entanglement between quantum states
98    pub fn create_entanglement(&mut self, config: &QuantumSearchConfig) {
99        let num_states = self.amplitudes.len();
100
101        for i in 0..num_states {
102            for j in (i + 1)..num_states {
103                // Create entanglement based on state similarity
104                let entanglement =
105                    config.entanglement_strength * (self.amplitudes[i] * self.amplitudes[j]).sqrt();
106
107                self.entanglement_matrix[i][j] = entanglement;
108                self.entanglement_matrix[j][i] = entanglement;
109            }
110        }
111    }
112
113    /// Apply quantum interference patterns
114    pub fn apply_interference(&mut self, target_similarity: f32) {
115        let num_states = self.amplitudes.len();
116
117        for i in 0..num_states {
118            // Constructive interference for high similarity states
119            if self.probabilities[i] > target_similarity {
120                self.amplitudes[i] *= 1.0 + target_similarity;
121                self.phases[i] += std::f32::consts::PI / 4.0;
122            } else {
123                // Destructive interference for low similarity states
124                self.amplitudes[i] *= 1.0 - target_similarity * 0.5;
125                self.phases[i] -= std::f32::consts::PI / 4.0;
126            }
127        }
128
129        self.normalize();
130    }
131
132    /// Simulate quantum tunneling for optimization landscape exploration
133    pub fn quantum_tunneling(&mut self, barrier_height: f32) -> Vec<usize> {
134        let mut tunneling_states = Vec::new();
135
136        for i in 0..self.amplitudes.len() {
137            // Quantum tunneling probability based on barrier height
138            let tunneling_prob = (-2.0 * barrier_height).exp();
139
140            if self.probabilities[i] * tunneling_prob > 0.1 {
141                tunneling_states.push(i);
142                // Boost amplitude for tunneling states
143                self.amplitudes[i] *= (1.0 + tunneling_prob).sqrt();
144            }
145        }
146
147        self.normalize();
148        tunneling_states
149    }
150
151    /// Measure quantum state and collapse to classical result
152    pub fn measure(&mut self, config: &QuantumSearchConfig) -> Vec<usize> {
153        self.update_probabilities();
154
155        let mut measured_states = Vec::new();
156
157        for (i, &prob) in self.probabilities.iter().enumerate() {
158            if prob > config.measurement_threshold {
159                measured_states.push(i);
160            }
161        }
162
163        // Apply decoherence
164        for amplitude in &mut self.amplitudes {
165            *amplitude *= 1.0 - config.decoherence_rate;
166        }
167
168        measured_states
169    }
170
171    /// Update probability distribution from amplitudes
172    fn update_probabilities(&mut self) {
173        for (i, prob) in self.probabilities.iter_mut().enumerate() {
174            *prob = self.amplitudes[i].powi(2);
175        }
176    }
177
178    /// Normalize quantum state with SIMD optimization
179    fn normalize(&mut self) {
180        // Use SIMD for computing norm
181        let norm = f32::norm(&self.amplitudes);
182
183        if norm > 0.0 {
184            // Scale vector to normalize (no SIMD scale available, use scalar)
185            for amplitude in &mut self.amplitudes {
186                *amplitude /= norm;
187            }
188        }
189
190        self.update_probabilities();
191    }
192
193    /// Enhanced quantum tunneling with better barrier modeling
194    pub fn enhanced_quantum_tunneling(&mut self, barrier_profile: &[f32]) -> Result<Vec<usize>> {
195        if barrier_profile.len() != self.amplitudes.len() {
196            return Err(anyhow!(
197                "Barrier profile length must match number of quantum states"
198            ));
199        }
200
201        let mut tunneling_states = Vec::new();
202
203        #[allow(clippy::needless_range_loop)]
204        for i in 0..self.amplitudes.len() {
205            let barrier_height = barrier_profile[i];
206
207            // More sophisticated tunneling probability calculation
208            let transmission_coefficient = if barrier_height > 0.0 {
209                let tunneling_width = 1.0; // Simplified barrier width
210                (-2.0 * (2.0 * barrier_height).sqrt() * tunneling_width).exp()
211            } else {
212                1.0 // No barrier
213            };
214
215            let tunneling_prob = self.probabilities[i] * transmission_coefficient;
216
217            if tunneling_prob > 0.05 {
218                tunneling_states.push(i);
219                // Enhance amplitude for successful tunneling
220                self.amplitudes[i] *= (1.0 + transmission_coefficient).sqrt();
221            }
222        }
223
224        self.normalize();
225        Ok(tunneling_states)
226    }
227}
228
229/// Quantum-inspired vector search algorithm
230#[derive(Debug)]
231pub struct QuantumVectorSearch {
232    config: QuantumSearchConfig,
233    quantum_states: Arc<RwLock<HashMap<String, QuantumState>>>,
234    search_history: Arc<RwLock<Vec<QuantumSearchResult>>>,
235    optimization_cache: Arc<RwLock<HashMap<String, f32>>>,
236    rng: Arc<RwLock<Random<StdRng>>>,
237}
238
239/// Result of quantum-inspired search with quantum metrics
240#[derive(Debug, Clone, Serialize, Deserialize)]
241pub struct QuantumSearchResult {
242    pub vector_id: String,
243    pub similarity: f32,
244    pub quantum_probability: f32,
245    pub entanglement_score: f32,
246    pub interference_pattern: f32,
247    pub tunneling_advantage: f32,
248    pub quantum_confidence: f32,
249}
250
251impl QuantumVectorSearch {
252    /// Create a new quantum vector search instance
253    pub fn new(config: QuantumSearchConfig) -> Self {
254        Self {
255            config,
256            quantum_states: Arc::new(RwLock::new(HashMap::new())),
257            search_history: Arc::new(RwLock::new(Vec::new())),
258            optimization_cache: Arc::new(RwLock::new(HashMap::new())),
259            rng: Arc::new(RwLock::new(Random::seed(42))),
260        }
261    }
262
263    /// Create with default configuration
264    pub fn with_default_config() -> Self {
265        Self::new(QuantumSearchConfig::default())
266    }
267
268    /// Create with seeded random number generator for reproducible results
269    pub fn with_seed(config: QuantumSearchConfig, seed: u64) -> Self {
270        Self {
271            config,
272            quantum_states: Arc::new(RwLock::new(HashMap::new())),
273            search_history: Arc::new(RwLock::new(Vec::new())),
274            optimization_cache: Arc::new(RwLock::new(HashMap::new())),
275            rng: Arc::new(RwLock::new(Random::seed(seed))),
276        }
277    }
278
279    /// Perform quantum-inspired similarity search
280    pub async fn quantum_similarity_search(
281        &self,
282        query_vector: &Vector,
283        candidate_vectors: &[(String, Vector)],
284        k: usize,
285    ) -> Result<Vec<QuantumSearchResult>> {
286        let span = span!(Level::DEBUG, "quantum_similarity_search");
287        let _enter = span.enter();
288
289        let query_id = self.generate_query_id(query_vector);
290
291        // Initialize quantum state for this search
292        let mut quantum_state = QuantumState::new(self.config.superposition_states);
293        quantum_state.apply_superposition(&self.config);
294        quantum_state.create_entanglement(&self.config);
295
296        let mut results = Vec::new();
297        let query_f32 = query_vector.as_f32();
298
299        // Quantum-enhanced similarity computation
300        for (candidate_id, candidate_vector) in candidate_vectors {
301            let candidate_f32 = candidate_vector.as_f32();
302
303            // Classical similarity computation
304            let classical_similarity = self.compute_cosine_similarity(&query_f32, &candidate_f32);
305
306            // Apply quantum interference based on similarity
307            quantum_state.apply_interference(classical_similarity);
308
309            // Quantum tunneling for exploration
310            let tunneling_states = if self.config.enable_tunneling {
311                quantum_state.quantum_tunneling(1.0 - classical_similarity)
312            } else {
313                Vec::new()
314            };
315
316            // Measure quantum state
317            let measured_states = quantum_state.measure(&self.config);
318
319            // Compute quantum-enhanced metrics
320            let quantum_probability = quantum_state.probabilities.iter().sum::<f32>()
321                / quantum_state.probabilities.len() as f32;
322            let entanglement_score = self.compute_entanglement_score(&quantum_state);
323            let interference_pattern = self.compute_interference_pattern(&quantum_state);
324            let tunneling_advantage = if tunneling_states.is_empty() {
325                0.0
326            } else {
327                tunneling_states.len() as f32 / self.config.superposition_states as f32
328            };
329
330            // Quantum-enhanced similarity score
331            let quantum_similarity = classical_similarity * (1.0 + quantum_probability * 0.3);
332            let quantum_confidence =
333                self.compute_quantum_confidence(&quantum_state, &measured_states);
334
335            results.push(QuantumSearchResult {
336                vector_id: candidate_id.clone(),
337                similarity: quantum_similarity,
338                quantum_probability,
339                entanglement_score,
340                interference_pattern,
341                tunneling_advantage,
342                quantum_confidence,
343            });
344        }
345
346        // Sort by quantum-enhanced similarity
347        results.sort_by(|a, b| b.similarity.partial_cmp(&a.similarity).unwrap());
348        results.truncate(k);
349
350        // Store quantum state for future use
351        {
352            let mut states = self.quantum_states.write().unwrap();
353            states.insert(query_id, quantum_state);
354        }
355
356        // Store search result in history
357        {
358            let mut history = self.search_history.write().unwrap();
359            history.extend(results.clone());
360        }
361
362        info!(
363            "Quantum similarity search completed with {} results",
364            results.len()
365        );
366        Ok(results)
367    }
368
369    /// Parallel quantum-inspired similarity search for improved performance
370    pub async fn parallel_quantum_similarity_search(
371        &self,
372        query_vector: &Vector,
373        candidate_vectors: &[(String, Vector)],
374        k: usize,
375    ) -> Result<Vec<QuantumSearchResult>> {
376        let span = span!(Level::DEBUG, "parallel_quantum_similarity_search");
377        let _enter = span.enter();
378
379        if candidate_vectors.is_empty() {
380            return Ok(Vec::new());
381        }
382
383        let _query_id = self.generate_query_id(query_vector);
384        let query_f32 = query_vector.as_f32();
385
386        // Use parallel processing for large datasets
387        let chunk_size = std::cmp::max(candidate_vectors.len() / num_cpus::get(), 1);
388
389        let results: Result<Vec<Vec<QuantumSearchResult>>> = candidate_vectors
390            .par_chunks(chunk_size)
391            .map(|chunk| -> Result<Vec<QuantumSearchResult>> {
392                let mut chunk_results = Vec::new();
393                let mut quantum_state = QuantumState::new(self.config.superposition_states);
394                quantum_state.apply_superposition(&self.config);
395                quantum_state.create_entanglement(&self.config);
396
397                for (candidate_id, candidate_vector) in chunk {
398                    let candidate_f32 = candidate_vector.as_f32();
399
400                    // Classical similarity computation with SIMD optimization
401                    let classical_similarity =
402                        self.compute_cosine_similarity(&query_f32, &candidate_f32);
403
404                    // Apply quantum interference
405                    quantum_state.apply_interference(classical_similarity);
406
407                    // Quantum tunneling if enabled
408                    let tunneling_advantage = if self.config.enable_tunneling {
409                        let barrier_height =
410                            vec![1.0 - classical_similarity; self.config.superposition_states];
411                        match quantum_state.enhanced_quantum_tunneling(&barrier_height) {
412                            Ok(tunneling_states) => {
413                                if tunneling_states.is_empty() {
414                                    0.0
415                                } else {
416                                    tunneling_states.len() as f32
417                                        / self.config.superposition_states as f32
418                                }
419                            }
420                            Err(_) => 0.0,
421                        }
422                    } else {
423                        0.0
424                    };
425
426                    // Measure quantum state
427                    let measured_states = quantum_state.measure(&self.config);
428
429                    // Compute quantum-enhanced metrics
430                    let quantum_probability = quantum_state.probabilities.iter().sum::<f32>()
431                        / quantum_state.probabilities.len() as f32;
432                    let entanglement_score = self.compute_entanglement_score(&quantum_state);
433                    let interference_pattern = self.compute_interference_pattern(&quantum_state);
434                    let quantum_confidence =
435                        self.compute_quantum_confidence(&quantum_state, &measured_states);
436
437                    // Enhanced quantum similarity score with better weighting
438                    let quantum_enhancement = quantum_probability * 0.3
439                        + entanglement_score * 0.1
440                        + tunneling_advantage * 0.2;
441                    let quantum_similarity = classical_similarity * (1.0 + quantum_enhancement);
442
443                    chunk_results.push(QuantumSearchResult {
444                        vector_id: candidate_id.clone(),
445                        similarity: quantum_similarity,
446                        quantum_probability,
447                        entanglement_score,
448                        interference_pattern,
449                        tunneling_advantage,
450                        quantum_confidence,
451                    });
452                }
453
454                Ok(chunk_results)
455            })
456            .collect();
457
458        let mut all_results: Vec<QuantumSearchResult> = results?.into_iter().flatten().collect();
459
460        // Sort by quantum-enhanced similarity
461        all_results.sort_by(|a, b| b.similarity.partial_cmp(&a.similarity).unwrap());
462        all_results.truncate(k);
463
464        // Store search result in history
465        {
466            let mut history = self.search_history.write().unwrap();
467            history.extend(all_results.clone());
468        }
469
470        info!(
471            "Parallel quantum similarity search completed with {} results",
472            all_results.len()
473        );
474        Ok(all_results)
475    }
476
477    /// Perform quantum amplitude amplification for targeted search
478    pub fn quantum_amplitude_amplification(
479        &self,
480        target_similarity: f32,
481        quantum_state: &mut QuantumState,
482        iterations: usize,
483    ) -> Result<()> {
484        for iteration in 0..iterations {
485            // Oracle operation: mark target states
486            for (i, &prob) in quantum_state.probabilities.iter().enumerate() {
487                if prob >= target_similarity {
488                    quantum_state.amplitudes[i] *= -1.0; // Phase flip
489                }
490            }
491
492            // Diffusion operation: inversion about average
493            let average_amplitude: f32 = quantum_state.amplitudes.iter().sum::<f32>()
494                / quantum_state.amplitudes.len() as f32;
495
496            for amplitude in &mut quantum_state.amplitudes {
497                *amplitude = 2.0 * average_amplitude - *amplitude;
498            }
499
500            quantum_state.normalize();
501
502            debug!(
503                "Amplitude amplification iteration {} completed",
504                iteration + 1
505            );
506        }
507
508        Ok(())
509    }
510
511    /// Quantum annealing for optimization landscape exploration
512    pub fn quantum_annealing_optimization(
513        &self,
514        cost_function: impl Fn(&[f32]) -> f32,
515        initial_state: &[f32],
516        temperature_schedule: &[f32],
517    ) -> Result<Vec<f32>> {
518        let mut current_state = initial_state.to_vec();
519        let mut best_state = current_state.clone();
520        let mut best_cost = cost_function(&current_state);
521
522        for &temperature in temperature_schedule {
523            // Quantum fluctuations
524            for item in &mut current_state {
525                let quantum_fluctuation = self.generate_quantum_fluctuation(temperature);
526                *item += quantum_fluctuation;
527            }
528
529            let current_cost = cost_function(&current_state);
530
531            // Quantum acceptance probability
532            let accept_prob = if current_cost < best_cost {
533                1.0
534            } else {
535                (-(current_cost - best_cost) / temperature).exp()
536            };
537
538            if self.generate_random() < accept_prob {
539                best_state = current_state.clone();
540                best_cost = current_cost;
541            }
542
543            debug!(
544                "Quantum annealing: temperature={}, cost={}",
545                temperature, current_cost
546            );
547        }
548
549        Ok(best_state)
550    }
551
552    /// Get quantum search statistics
553    pub fn get_quantum_statistics(&self) -> QuantumSearchStatistics {
554        let history = self.search_history.read().unwrap();
555
556        let total_searches = history.len();
557        let avg_quantum_probability = if total_searches > 0 {
558            history.iter().map(|r| r.quantum_probability).sum::<f32>() / total_searches as f32
559        } else {
560            0.0
561        };
562
563        let avg_entanglement_score = if total_searches > 0 {
564            history.iter().map(|r| r.entanglement_score).sum::<f32>() / total_searches as f32
565        } else {
566            0.0
567        };
568
569        let avg_quantum_confidence = if total_searches > 0 {
570            history.iter().map(|r| r.quantum_confidence).sum::<f32>() / total_searches as f32
571        } else {
572            0.0
573        };
574
575        QuantumSearchStatistics {
576            total_searches,
577            avg_quantum_probability,
578            avg_entanglement_score,
579            avg_quantum_confidence,
580            superposition_states: self.config.superposition_states,
581            entanglement_strength: self.config.entanglement_strength,
582        }
583    }
584
585    // Helper methods
586
587    fn generate_query_id(&self, vector: &Vector) -> String {
588        use std::collections::hash_map::DefaultHasher;
589        use std::hash::{Hash, Hasher};
590
591        let mut hasher = DefaultHasher::new();
592        for value in vector.as_f32() {
593            value.to_bits().hash(&mut hasher);
594        }
595        format!("quantum_query_{:x}", hasher.finish())
596    }
597
598    fn compute_cosine_similarity(&self, a: &[f32], b: &[f32]) -> f32 {
599        if a.len() != b.len() {
600            return 0.0;
601        }
602
603        // Use SIMD optimization via oxirs-core for better performance
604        // Note: SimdOps provides cosine_distance, so we convert to similarity
605        let cosine_distance = f32::cosine_distance(a, b);
606        1.0 - cosine_distance
607    }
608
609    fn compute_entanglement_score(&self, quantum_state: &QuantumState) -> f32 {
610        let mut entanglement_score = 0.0;
611        let num_states = quantum_state.entanglement_matrix.len();
612
613        for i in 0..num_states {
614            for j in (i + 1)..num_states {
615                entanglement_score += quantum_state.entanglement_matrix[i][j].abs();
616            }
617        }
618
619        entanglement_score / (num_states * (num_states - 1) / 2) as f32
620    }
621
622    fn compute_interference_pattern(&self, quantum_state: &QuantumState) -> f32 {
623        let mut interference = 0.0;
624
625        for i in 0..quantum_state.amplitudes.len() {
626            let amplitude = quantum_state.amplitudes[i];
627            let phase = quantum_state.phases[i];
628            interference += amplitude * phase.cos();
629        }
630
631        interference / quantum_state.amplitudes.len() as f32
632    }
633
634    fn compute_quantum_confidence(
635        &self,
636        quantum_state: &QuantumState,
637        measured_states: &[usize],
638    ) -> f32 {
639        if measured_states.is_empty() {
640            return 0.0;
641        }
642
643        let measured_probability: f32 = measured_states
644            .iter()
645            .map(|&i| quantum_state.probabilities[i])
646            .sum();
647
648        // Confidence based on measurement certainty
649        let max_probability = quantum_state
650            .probabilities
651            .iter()
652            .max_by(|a, b| a.partial_cmp(b).unwrap())
653            .unwrap_or(&0.0);
654
655        (measured_probability * max_probability).sqrt()
656    }
657
658    fn generate_quantum_fluctuation(&self, temperature: f32) -> f32 {
659        // Simulate quantum fluctuation using thermal noise with proper Gaussian distribution
660        let mut rng = self.rng.write().unwrap();
661
662        // Use proper normal distribution for quantum fluctuations
663        let normal =
664            Normal::new(0.0, temperature.sqrt()).unwrap_or_else(|_| Normal::new(0.0, 1.0).unwrap());
665        normal.sample(&mut *rng)
666    }
667
668    #[allow(deprecated)]
669    fn generate_random(&self) -> f32 {
670        // Use proper random number generator
671        let mut rng = self.rng.write().unwrap();
672        rng.gen_range(0.0..1.0)
673    }
674}
675
676/// Statistics for quantum search operations
677#[derive(Debug, Clone, Serialize, Deserialize)]
678pub struct QuantumSearchStatistics {
679    pub total_searches: usize,
680    pub avg_quantum_probability: f32,
681    pub avg_entanglement_score: f32,
682    pub avg_quantum_confidence: f32,
683    pub superposition_states: usize,
684    pub entanglement_strength: f32,
685}
686
687#[cfg(test)]
688mod tests {
689    use super::*;
690
691    #[test]
692    fn test_quantum_state_creation() {
693        let quantum_state = QuantumState::new(8);
694        assert_eq!(quantum_state.amplitudes.len(), 8);
695        assert_eq!(quantum_state.phases.len(), 8);
696        assert_eq!(quantum_state.entanglement_matrix.len(), 8);
697        assert_eq!(quantum_state.probabilities.len(), 8);
698    }
699
700    #[test]
701    fn test_quantum_superposition() {
702        let mut quantum_state = QuantumState::new(4);
703        let config = QuantumSearchConfig::default();
704
705        quantum_state.apply_superposition(&config);
706
707        // Check that amplitudes are normalized
708        let norm: f32 = quantum_state.amplitudes.iter().map(|a| a.powi(2)).sum();
709        assert!((norm - 1.0).abs() < 1e-6);
710    }
711
712    #[test]
713    fn test_quantum_entanglement() {
714        let mut quantum_state = QuantumState::new(4);
715        let config = QuantumSearchConfig::default();
716
717        quantum_state.create_entanglement(&config);
718
719        // Check that entanglement matrix is symmetric
720        for i in 0..4 {
721            for j in 0..4 {
722                assert_eq!(
723                    quantum_state.entanglement_matrix[i][j],
724                    quantum_state.entanglement_matrix[j][i]
725                );
726            }
727        }
728    }
729
730    #[tokio::test]
731    async fn test_quantum_vector_search() {
732        let quantum_search = QuantumVectorSearch::with_seed(QuantumSearchConfig::default(), 42);
733
734        let query_vector = Vector::new(vec![1.0, 0.0, 0.0]);
735        let candidates = vec![
736            ("vec1".to_string(), Vector::new(vec![0.9, 0.1, 0.0])),
737            ("vec2".to_string(), Vector::new(vec![0.0, 1.0, 0.0])),
738            ("vec3".to_string(), Vector::new(vec![0.8, 0.0, 0.6])),
739        ];
740
741        let results = quantum_search
742            .quantum_similarity_search(&query_vector, &candidates, 2)
743            .await
744            .unwrap();
745
746        assert_eq!(results.len(), 2);
747        assert!(results[0].similarity >= results[1].similarity);
748        assert!(results[0].quantum_confidence >= 0.0);
749        assert!(results[0].quantum_confidence <= 1.0);
750    }
751
752    #[tokio::test]
753    async fn test_parallel_quantum_vector_search() {
754        let quantum_search = QuantumVectorSearch::with_seed(QuantumSearchConfig::default(), 42);
755
756        let query_vector = Vector::new(vec![1.0, 0.0, 0.0]);
757        let candidates = vec![
758            ("vec1".to_string(), Vector::new(vec![0.9, 0.1, 0.0])),
759            ("vec2".to_string(), Vector::new(vec![0.0, 1.0, 0.0])),
760            ("vec3".to_string(), Vector::new(vec![0.8, 0.0, 0.6])),
761            ("vec4".to_string(), Vector::new(vec![0.7, 0.7, 0.0])),
762            ("vec5".to_string(), Vector::new(vec![0.5, 0.5, 0.7])),
763        ];
764
765        let results = quantum_search
766            .parallel_quantum_similarity_search(&query_vector, &candidates, 3)
767            .await
768            .unwrap();
769
770        assert_eq!(results.len(), 3);
771        assert!(results[0].similarity >= results[1].similarity);
772        assert!(results[1].similarity >= results[2].similarity);
773        assert!(results[0].quantum_confidence >= 0.0);
774        assert!(results[0].quantum_confidence <= 1.0);
775    }
776
777    #[test]
778    fn test_quantum_amplitude_amplification() {
779        let quantum_search = QuantumVectorSearch::with_default_config();
780        let mut quantum_state = QuantumState::new(8);
781
782        let result = quantum_search.quantum_amplitude_amplification(0.5, &mut quantum_state, 3);
783        assert!(result.is_ok());
784
785        // Check that amplitudes are still normalized
786        let norm: f32 = quantum_state.amplitudes.iter().map(|a| a.powi(2)).sum();
787        assert!((norm - 1.0).abs() < 1e-6);
788    }
789
790    #[test]
791    fn test_quantum_annealing() {
792        let quantum_search = QuantumVectorSearch::with_default_config();
793
794        // Simple quadratic cost function
795        let cost_fn = |state: &[f32]| -> f32 { state.iter().map(|x| (x - 0.5).powi(2)).sum() };
796
797        let initial_state = vec![0.0, 1.0, 0.2];
798        let temperature_schedule = vec![1.0, 0.5, 0.1];
799
800        let result = quantum_search.quantum_annealing_optimization(
801            cost_fn,
802            &initial_state,
803            &temperature_schedule,
804        );
805        assert!(result.is_ok());
806
807        let optimized_state = result.unwrap();
808        assert_eq!(optimized_state.len(), initial_state.len());
809    }
810
811    #[test]
812    fn test_quantum_tunneling() {
813        let mut quantum_state = QuantumState::new(8);
814        let tunneling_states = quantum_state.quantum_tunneling(0.8);
815
816        // Should return some states that can tunnel
817        assert!(tunneling_states.len() <= 8);
818
819        // Check all returned states are valid indices
820        for state in tunneling_states {
821            assert!(state < 8);
822        }
823    }
824
825    #[test]
826    fn test_quantum_measurement() {
827        let mut quantum_state = QuantumState::new(4);
828        let config = QuantumSearchConfig::default();
829
830        // Set up some probability distribution
831        quantum_state.amplitudes = vec![0.6, 0.4, 0.3, 0.5];
832        quantum_state.normalize();
833
834        let measured_states = quantum_state.measure(&config);
835
836        // Should return states above threshold
837        assert!(!measured_states.is_empty());
838        for state in measured_states {
839            assert!(state < 4);
840        }
841    }
842
843    #[test]
844    fn test_enhanced_quantum_tunneling() {
845        let mut quantum_state = QuantumState::new(8);
846
847        // Set up initial state
848        quantum_state.amplitudes = vec![0.3, 0.4, 0.2, 0.5, 0.1, 0.6, 0.3, 0.4];
849        quantum_state.normalize();
850
851        // Create barrier profile (higher values = stronger barriers)
852        let barrier_profile = vec![0.9, 0.1, 0.8, 0.2, 0.7, 0.3, 0.6, 0.4];
853
854        let tunneling_result = quantum_state.enhanced_quantum_tunneling(&barrier_profile);
855        assert!(tunneling_result.is_ok());
856
857        let tunneling_states = tunneling_result.unwrap();
858
859        // Should return some states that can tunnel (those with lower barriers)
860        assert!(!tunneling_states.is_empty());
861
862        // Check all returned states are valid indices
863        for state in tunneling_states {
864            assert!(state < 8);
865        }
866    }
867
868    #[test]
869    fn test_quantum_statistics() {
870        let quantum_search = QuantumVectorSearch::with_default_config();
871        let stats = quantum_search.get_quantum_statistics();
872
873        assert_eq!(stats.total_searches, 0);
874        assert_eq!(stats.superposition_states, 64);
875        assert_eq!(stats.entanglement_strength, 0.7);
876    }
877}