ruqu_qear/
lib.rs

1//! # ruqu-qear - Quantum Echo-Attention Reservoir
2//!
3//! A scientifically novel library combining quantum reservoir computing with
4//! attention mechanisms for advanced time series processing and prediction.
5//!
6//! ## Overview
7//!
8//! QEAR (Quantum Echo-Attention Reservoir) implements a hybrid computational
9//! model that leverages:
10//!
11//! - **Quantum Reservoir Computing**: Uses simulated quantum dynamics with echo
12//!   state network principles to create rich, high-dimensional feature spaces.
13//!
14//! - **Attention Mechanisms**: Employs multi-head attention to fuse reservoir
15//!   states with input sequences, enabling the model to focus on relevant
16//!   temporal patterns.
17//!
18//! - **Feature Extraction**: Provides comprehensive feature extraction including
19//!   quantum state tomography, expectation values, and classical statistics.
20//!
21//! ## Key Features
22//!
23//! - Simulated quantum reservoir with N qubits (2^N neurons)
24//! - Echo state network dynamics with controllable spectral radius
25//! - Multi-head attention fusion between reservoir and inputs
26//! - Temporal attention for sequence-to-sequence modeling
27//! - Ridge regression and online learning for readout
28//! - Sliding window time series processing
29//! - Hyperparameter optimization via cross-validation
30//!
31//! ## Quick Start
32//!
33//! ```rust
34//! use ruqu_qear::prelude::*;
35//!
36//! // Create a quantum reservoir
37//! let config = ReservoirConfig::new(5)  // 32 neurons (2^5)
38//!     .with_spectral_radius(0.95)
39//!     .with_seed(42);
40//!
41//! let mut reservoir = QuantumReservoir::new(config).unwrap();
42//!
43//! // Process input sequence
44//! let inputs = ndarray::Array2::from_shape_fn((100, 3), |(i, j)| {
45//!     ((i + j) as f64 / 103.0).sin()
46//! });
47//!
48//! let states = reservoir.run(&inputs).unwrap();
49//!
50//! // Extract features
51//! let extractor = FeatureExtractor::default_extractor();
52//! let features = extractor.extract(&states).unwrap();
53//! ```
54//!
55//! ## Time Series Forecasting
56//!
57//! ```rust,no_run
58//! use ruqu_qear::prelude::*;
59//!
60//! // Configure time series processing
61//! let ts_config = TimeSeriesConfig::new(1, 50)  // 1D input, window size 50
62//!     .with_forecast_horizon(10);
63//!
64//! let reservoir_config = ReservoirConfig::new(5);
65//!
66//! let mut processor = TimeSeriesProcessor::new(ts_config, reservoir_config).unwrap();
67//!
68//! // Prepare training data
69//! let data = ndarray::Array2::from_shape_fn((1000, 1), |(i, _)| {
70//!     (i as f64 * 0.1).sin()  // Simple sine wave
71//! });
72//!
73//! let (features, targets) = processor.prepare_training_data(&data).unwrap();
74//!
75//! // Train readout layer
76//! let mut model = RidgeRegression::default_model().unwrap();
77//! // Convert features and targets to 2D arrays for training...
78//! ```
79//!
80//! ## Architecture
81//!
82//! The library is organized into several modules:
83//!
84//! - [`reservoir`]: Quantum echo state reservoir implementation
85//! - [`fusion`]: Attention mechanisms for state fusion
86//! - [`features`]: Feature extraction from reservoir dynamics
87//! - [`timeseries`]: Time series processing utilities
88//! - [`training`]: Training algorithms (ridge regression, online learning)
89//! - [`error`]: Error types and result handling
90//!
91//! ## Scientific Background
92//!
93//! Reservoir computing is a recurrent neural network paradigm where:
94//! 1. A fixed, randomly initialized "reservoir" transforms inputs into a
95//!    high-dimensional space
96//! 2. Only the output layer (readout) is trained
97//!
98//! Echo State Networks (ESN) achieve this by ensuring the reservoir has the
99//! "echo state property" - that the effect of initial conditions vanishes over
100//! time. This is controlled by the spectral radius.
101//!
102//! QEAR extends this by:
103//! 1. Using complex-valued states to simulate quantum amplitudes
104//! 2. Applying quantum-inspired dynamics with phase rotation
105//! 3. Adding attention mechanisms to learn which reservoir states are relevant
106//!
107//! ## References
108//!
109//! - Jaeger, H. (2001). The "echo state" approach to analysing and training
110//!   recurrent neural networks.
111//! - Fujii, K., & Nakajima, K. (2017). Harnessing disordered-ensemble quantum
112//!   dynamics for machine learning.
113//! - Vaswani, A. et al. (2017). Attention is all you need.
114
115#![deny(missing_docs)]
116#![deny(unsafe_code)]
117#![warn(clippy::all)]
118
119pub mod error;
120pub mod features;
121pub mod fusion;
122pub mod reservoir;
123pub mod timeseries;
124pub mod training;
125
126/// Prelude module with commonly used types.
127pub mod prelude {
128    pub use crate::error::{QearError, QearResult};
129    pub use crate::features::{
130        ExpectationComputer, FeatureConfig, FeatureExtractor, QuantumTomography,
131    };
132    pub use crate::fusion::{AttentionConfig, AttentionFusion, TemporalAttention};
133    pub use crate::reservoir::{QuantumReservoir, ReservoirConfig};
134    pub use crate::timeseries::{
135        EncodingMethod, InputEncoder, PredictionHead, SlidingWindow, TimeSeriesConfig,
136        TimeSeriesProcessor,
137    };
138    pub use crate::training::{
139        HyperparameterOptimizer, OnlineLearner, RidgeConfig, RidgeRegression, RidgeSolver,
140    };
141}
142
143// Re-export main types at crate root
144pub use error::{QearError, QearResult};
145pub use features::{ExpectationComputer, FeatureConfig, FeatureExtractor, QuantumTomography};
146pub use fusion::{AttentionConfig, AttentionFusion, TemporalAttention};
147pub use reservoir::{QuantumReservoir, ReservoirConfig};
148pub use timeseries::{
149    EncodingMethod, InputEncoder, PredictionHead, SlidingWindow, TimeSeriesConfig,
150    TimeSeriesProcessor,
151};
152pub use training::{
153    HyperparameterOptimizer, OnlineLearner, RidgeConfig, RidgeRegression, RidgeSolver,
154};
155
156/// Version information for the crate.
157pub const VERSION: &str = env!("CARGO_PKG_VERSION");
158
159/// Crate name.
160pub const CRATE_NAME: &str = env!("CARGO_PKG_NAME");
161
162#[cfg(test)]
163mod tests {
164    use super::*;
165    use ndarray::{Array1, Array2};
166
167    #[test]
168    fn test_version() {
169        assert!(!VERSION.is_empty());
170    }
171
172    #[test]
173    fn test_crate_name() {
174        assert_eq!(CRATE_NAME, "ruqu-qear");
175    }
176
177    #[test]
178    fn test_end_to_end_reservoir_features() {
179        // Create reservoir
180        let config = ReservoirConfig::new(4).with_seed(42);
181        let mut reservoir = QuantumReservoir::new(config).unwrap();
182
183        // Generate input
184        let inputs = Array2::from_shape_fn((50, 3), |(i, j)| ((i + j) as f64 / 53.0).sin());
185
186        // Run through reservoir
187        let states = reservoir.run(&inputs).unwrap();
188        assert_eq!(states.nrows(), 50);
189
190        // Extract features
191        let extractor = FeatureExtractor::default_extractor();
192        let features = extractor.extract(&states).unwrap();
193        assert!(features.ncols() > 0);
194    }
195
196    #[test]
197    fn test_end_to_end_with_attention() {
198        // Create reservoir
199        let reservoir_config = ReservoirConfig::new(4).with_seed(42);
200        let mut reservoir = QuantumReservoir::new(reservoir_config).unwrap();
201
202        // Create attention
203        let attention_config = AttentionConfig::new(32, 4).with_seed(42);
204        let mut attention = AttentionFusion::new(attention_config).unwrap();
205
206        // Generate input
207        let inputs = Array2::from_shape_fn((30, 4), |(i, j)| ((i * j) as f64 / 120.0).cos());
208
209        // Run through reservoir
210        let states = reservoir.run(&inputs).unwrap();
211
212        // Apply attention
213        let fused = attention.forward(&states, &inputs).unwrap();
214        assert_eq!(fused.nrows(), 30);
215    }
216
217    #[test]
218    fn test_end_to_end_training() {
219        // Create simple training data
220        let features = Array2::from_shape_fn((100, 16), |(i, j)| ((i + j) as f64 / 116.0).sin());
221        let targets = Array2::from_shape_fn((100, 1), |(i, _)| {
222            features[[i, 0]] + features[[i, 5]] + features[[i, 10]]
223        });
224
225        // Train model
226        let config = RidgeConfig::new(0.1);
227        let mut model = RidgeRegression::new(config).unwrap();
228        model.fit(&features, &targets).unwrap();
229
230        // Evaluate
231        let score = model.score(&features, &targets).unwrap();
232        assert!(score > 0.5);
233    }
234
235    #[test]
236    fn test_quantum_tomography() {
237        let config = ReservoirConfig::new(4).with_seed(42);
238        let reservoir = QuantumReservoir::new(config).unwrap();
239
240        let tomography = QuantumTomography::new(4);
241        let measurements = tomography.measure(&reservoir).unwrap();
242
243        assert!(measurements.len() > 0);
244    }
245
246    #[test]
247    fn test_expectation_values() {
248        let config = ReservoirConfig::new(3).with_seed(42);
249        let reservoir = QuantumReservoir::new(config).unwrap();
250
251        let computer = ExpectationComputer::new(3);
252        let expectations = computer.compute(&reservoir).unwrap();
253
254        // Probabilities should sum to 1
255        let sum: f64 = expectations.sum();
256        assert!((sum - 1.0).abs() < 1e-6);
257    }
258
259    #[test]
260    fn test_prelude_imports() {
261        use crate::prelude::*;
262
263        let _config: ReservoirConfig = ReservoirConfig::default();
264        let _att_config: AttentionConfig = AttentionConfig::default();
265        let _ridge_config: RidgeConfig = RidgeConfig::default();
266        let _ts_config: TimeSeriesConfig = TimeSeriesConfig::default();
267    }
268}