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}