1use ndarray::{s, Array1, Array2, Array3, ArrayView1, ArrayView2, Axis};
28use num_complex::Complex64;
29use rand::{thread_rng, Rng};
30use scirs2_core::parallel_ops::*;
31use serde::{Deserialize, Serialize};
32use std::collections::{HashMap, VecDeque};
33use std::f64::consts::PI;
34use std::sync::{Arc, Mutex};
35
36use crate::circuit_interfaces::{
37 CircuitInterface, InterfaceCircuit, InterfaceGate, InterfaceGateType,
38};
39use crate::error::Result;
40use crate::scirs2_integration::SciRS2Backend;
41use crate::statevector::StateVectorSimulator;
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
45pub enum QuantumReservoirArchitecture {
46 RandomCircuit,
48 SpinChain,
50 TransverseFieldIsing,
52 SmallWorld,
54 FullyConnected,
56 ScaleFree,
58 HierarchicalModular,
60 AdaptiveTopology,
62 QuantumCellularAutomaton,
64 Ring,
66 Grid,
68 Tree,
70 Hypergraph,
72 TensorNetwork,
74 Custom,
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
80pub enum ReservoirDynamics {
81 Unitary,
83 Open,
85 NISQ,
87 Adiabatic,
89 Floquet,
91 QuantumWalk,
93 ContinuousTime,
95 DigitalQuantum,
97 Variational,
99 HamiltonianLearning,
101 ManyBodyLocalized,
103 QuantumChaotic,
105}
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
109pub enum InputEncoding {
110 Amplitude,
112 Phase,
114 BasisState,
116 Coherent,
118 Squeezed,
120 Angle,
122 IQP,
124 DataReUploading,
126 QuantumFeatureMap,
128 VariationalEncoding,
130 TemporalEncoding,
132 FourierEncoding,
134 WaveletEncoding,
136 HaarRandom,
138 GraphEncoding,
140}
141
142#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
144pub enum OutputMeasurement {
145 PauliExpectation,
147 Probability,
149 Correlations,
151 Entanglement,
153 Fidelity,
155 QuantumFisherInformation,
157 Variance,
159 HigherOrderMoments,
161 SpectralProperties,
163 QuantumCoherence,
165 Purity,
167 QuantumMutualInformation,
169 ProcessTomography,
171 TemporalCorrelations,
173 NonLinearReadout,
175}
176
177#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
179pub enum LearningAlgorithm {
180 Ridge,
182 LASSO,
184 ElasticNet,
186 RecursiveLeastSquares,
188 KalmanFilter,
190 ExtendedKalmanFilter,
192 NeuralNetwork,
194 SupportVectorRegression,
196 GaussianProcess,
198 RandomForest,
200 GradientBoosting,
202 OnlineGradientDescent,
204 Adam,
206 MetaLearning,
208}
209
210#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
212pub enum ActivationFunction {
213 ReLU,
215 LeakyReLU,
217 ELU,
219 Sigmoid,
221 Tanh,
223 Swish,
225 GELU,
227 Linear,
229}
230
231#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
233pub enum MemoryKernel {
234 Exponential,
236 PowerLaw,
238 Gaussian,
240 Polynomial,
242 Rational,
244 Sinusoidal,
246 Custom,
248}
249
250#[derive(Debug, Clone, Serialize, Deserialize)]
252pub struct QuantumReservoirConfig {
253 pub num_qubits: usize,
255 pub architecture: QuantumReservoirArchitecture,
257 pub dynamics: ReservoirDynamics,
259 pub input_encoding: InputEncoding,
261 pub output_measurement: OutputMeasurement,
263 pub learning_config: AdvancedLearningConfig,
265 pub time_series_config: TimeSeriesConfig,
267 pub memory_config: MemoryAnalysisConfig,
269 pub time_step: f64,
271 pub evolution_steps: usize,
273 pub coupling_strength: f64,
275 pub noise_level: f64,
277 pub memory_capacity: usize,
279 pub adaptive_learning: bool,
281 pub learning_rate: f64,
283 pub washout_period: usize,
285 pub random_seed: Option<u64>,
287 pub enable_qec: bool,
289 pub precision: f64,
291}
292
293impl Default for QuantumReservoirConfig {
294 fn default() -> Self {
295 Self {
296 num_qubits: 8,
297 architecture: QuantumReservoirArchitecture::RandomCircuit,
298 dynamics: ReservoirDynamics::Unitary,
299 input_encoding: InputEncoding::Amplitude,
300 output_measurement: OutputMeasurement::PauliExpectation,
301 learning_config: AdvancedLearningConfig::default(),
302 time_series_config: TimeSeriesConfig::default(),
303 memory_config: MemoryAnalysisConfig::default(),
304 time_step: 0.1,
305 evolution_steps: 10,
306 coupling_strength: 1.0,
307 noise_level: 0.01,
308 memory_capacity: 100,
309 adaptive_learning: true,
310 learning_rate: 0.01,
311 washout_period: 50,
312 random_seed: None,
313 enable_qec: false,
314 precision: 1e-8,
315 }
316 }
317}
318
319#[derive(Debug, Clone, Serialize, Deserialize)]
321pub struct AdvancedLearningConfig {
322 pub algorithm: LearningAlgorithm,
324 pub regularization: f64,
326 pub l1_ratio: f64,
328 pub forgetting_factor: f64,
330 pub process_noise: f64,
332 pub measurement_noise: f64,
334 pub nn_architecture: Vec<usize>,
336 pub nn_activation: ActivationFunction,
338 pub epochs: usize,
340 pub batch_size: usize,
342 pub early_stopping_patience: usize,
344 pub cv_folds: usize,
346 pub enable_ensemble: bool,
348 pub ensemble_size: usize,
350}
351
352impl Default for AdvancedLearningConfig {
353 fn default() -> Self {
354 Self {
355 algorithm: LearningAlgorithm::Ridge,
356 regularization: 1e-6,
357 l1_ratio: 0.5,
358 forgetting_factor: 0.99,
359 process_noise: 1e-4,
360 measurement_noise: 1e-3,
361 nn_architecture: vec![64, 32, 16],
362 nn_activation: ActivationFunction::ReLU,
363 epochs: 100,
364 batch_size: 32,
365 early_stopping_patience: 10,
366 cv_folds: 5,
367 enable_ensemble: false,
368 ensemble_size: 5,
369 }
370 }
371}
372
373#[derive(Debug, Clone, Serialize, Deserialize)]
375pub struct TimeSeriesConfig {
376 pub enable_arima: bool,
378 pub ar_order: usize,
380 pub ma_order: usize,
382 pub diff_order: usize,
384 pub enable_nar: bool,
386 pub nar_order: usize,
388 pub memory_kernel: MemoryKernel,
390 pub kernel_params: Vec<f64>,
392 pub enable_seasonal: bool,
394 pub seasonal_period: usize,
396 pub enable_changepoint: bool,
398 pub anomaly_threshold: f64,
400}
401
402impl Default for TimeSeriesConfig {
403 fn default() -> Self {
404 Self {
405 enable_arima: true,
406 ar_order: 2,
407 ma_order: 1,
408 diff_order: 1,
409 enable_nar: true,
410 nar_order: 3,
411 memory_kernel: MemoryKernel::Exponential,
412 kernel_params: vec![0.9, 0.1],
413 enable_seasonal: false,
414 seasonal_period: 12,
415 enable_changepoint: false,
416 anomaly_threshold: 2.0,
417 }
418 }
419}
420
421#[derive(Debug, Clone, Serialize, Deserialize)]
423pub struct MemoryAnalysisConfig {
424 pub enable_capacity_estimation: bool,
426 pub capacity_tasks: Vec<MemoryTask>,
428 pub enable_nonlinear: bool,
430 pub nonlinearity_orders: Vec<usize>,
432 pub enable_temporal_correlation: bool,
434 pub correlation_lags: Vec<usize>,
436 pub enable_ipc: bool,
438 pub ipc_functions: Vec<IPCFunction>,
440 pub enable_entropy: bool,
442}
443
444impl Default for MemoryAnalysisConfig {
445 fn default() -> Self {
446 Self {
447 enable_capacity_estimation: true,
448 capacity_tasks: vec![
449 MemoryTask::DelayLine,
450 MemoryTask::TemporalXOR,
451 MemoryTask::Parity,
452 ],
453 enable_nonlinear: true,
454 nonlinearity_orders: vec![2, 3, 4],
455 enable_temporal_correlation: true,
456 correlation_lags: (1..=20).collect(),
457 enable_ipc: true,
458 ipc_functions: vec![
459 IPCFunction::Linear,
460 IPCFunction::Quadratic,
461 IPCFunction::Cubic,
462 ],
463 enable_entropy: true,
464 }
465 }
466}
467
468#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
470pub enum MemoryTask {
471 DelayLine,
473 TemporalXOR,
475 Parity,
477 SequencePrediction,
479 PatternCompletion,
481 TemporalIntegration,
483}
484
485#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
487pub enum IPCFunction {
488 Linear,
490 Quadratic,
492 Cubic,
494 Sine,
496 Product,
498 XOR,
500}
501
502#[derive(Debug, Clone)]
504pub struct QuantumReservoirState {
505 pub state_vector: Array1<Complex64>,
507 pub state_history: VecDeque<Array1<Complex64>>,
509 pub observables: HashMap<String, f64>,
511 pub correlations: Array2<f64>,
513 pub higher_order_correlations: HashMap<String, f64>,
515 pub entanglement_measures: HashMap<String, f64>,
517 pub memory_metrics: MemoryMetrics,
519 pub time_index: usize,
521 pub last_update: f64,
523 pub activity_level: f64,
525 pub performance_history: VecDeque<f64>,
527}
528
529#[derive(Debug, Clone, Default, Serialize, Deserialize)]
531pub struct MemoryMetrics {
532 pub linear_capacity: f64,
534 pub nonlinear_capacity: f64,
536 pub total_capacity: f64,
538 pub processing_capacity: f64,
540 pub correlation_length: f64,
542 pub decay_rate: f64,
544 pub efficiency: f64,
546}
547
548impl QuantumReservoirState {
549 pub fn new(num_qubits: usize, memory_capacity: usize) -> Self {
551 let state_size = 1 << num_qubits;
552 let mut state_vector = Array1::zeros(state_size);
553 state_vector[0] = Complex64::new(1.0, 0.0); Self {
556 state_vector,
557 state_history: VecDeque::with_capacity(memory_capacity),
558 observables: HashMap::new(),
559 correlations: Array2::zeros((num_qubits, num_qubits)),
560 higher_order_correlations: HashMap::new(),
561 entanglement_measures: HashMap::new(),
562 memory_metrics: MemoryMetrics::default(),
563 time_index: 0,
564 last_update: 0.0,
565 activity_level: 0.0,
566 performance_history: VecDeque::with_capacity(1000),
567 }
568 }
569
570 pub fn update_state(&mut self, new_state: Array1<Complex64>, timestamp: f64) {
572 self.state_history.push_back(self.state_vector.clone());
574 if self.state_history.len() > self.state_history.capacity() {
575 self.state_history.pop_front();
576 }
577
578 self.state_vector = new_state;
580 self.time_index += 1;
581 self.last_update = timestamp;
582
583 self.update_activity_level();
585 }
586
587 fn update_activity_level(&mut self) {
589 let activity = self.state_vector.iter().map(|x| x.norm_sqr()).sum::<f64>()
590 / self.state_vector.len() as f64;
591
592 let alpha = 0.1;
594 self.activity_level = alpha * activity + (1.0 - alpha) * self.activity_level;
595 }
596
597 pub fn calculate_memory_decay(&self) -> f64 {
599 if self.state_history.len() < 2 {
600 return 0.0;
601 }
602
603 let mut total_decay = 0.0;
604 let current_state = &self.state_vector;
605
606 for (i, past_state) in self.state_history.iter().enumerate() {
607 let fidelity = self.calculate_fidelity(current_state, past_state);
608 let time_diff = (self.state_history.len() - i) as f64;
609 total_decay += fidelity * (-time_diff * 0.1).exp();
610 }
611
612 total_decay / self.state_history.len() as f64
613 }
614
615 fn calculate_fidelity(&self, state1: &Array1<Complex64>, state2: &Array1<Complex64>) -> f64 {
617 let overlap = state1
618 .iter()
619 .zip(state2.iter())
620 .map(|(a, b)| a.conj() * b)
621 .sum::<Complex64>();
622 overlap.norm_sqr()
623 }
624}
625
626#[derive(Debug, Clone)]
628pub struct ReservoirTrainingData {
629 pub inputs: Vec<Array1<f64>>,
631 pub targets: Vec<Array1<f64>>,
633 pub timestamps: Vec<f64>,
635 pub features: Option<Vec<Array1<f64>>>,
637 pub labels: Option<Vec<usize>>,
639 pub sequence_lengths: Option<Vec<usize>>,
641 pub missing_mask: Option<Vec<Array1<bool>>>,
643 pub sample_weights: Option<Vec<f64>>,
645 pub metadata: Option<Vec<HashMap<String, String>>>,
647}
648
649impl ReservoirTrainingData {
650 pub fn new(inputs: Vec<Array1<f64>>, targets: Vec<Array1<f64>>, timestamps: Vec<f64>) -> Self {
652 Self {
653 inputs,
654 targets,
655 timestamps,
656 features: None,
657 labels: None,
658 sequence_lengths: None,
659 missing_mask: None,
660 sample_weights: None,
661 metadata: None,
662 }
663 }
664
665 pub fn with_features(mut self, features: Vec<Array1<f64>>) -> Self {
667 self.features = Some(features);
668 self
669 }
670
671 pub fn with_labels(mut self, labels: Vec<usize>) -> Self {
673 self.labels = Some(labels);
674 self
675 }
676
677 pub fn with_weights(mut self, weights: Vec<f64>) -> Self {
679 self.sample_weights = Some(weights);
680 self
681 }
682
683 pub fn len(&self) -> usize {
685 self.inputs.len()
686 }
687
688 pub fn is_empty(&self) -> bool {
690 self.inputs.is_empty()
691 }
692
693 pub fn train_test_split(&self, test_ratio: f64) -> (Self, Self) {
695 let test_size = (self.len() as f64 * test_ratio) as usize;
696 let train_size = self.len() - test_size;
697
698 let train_data = Self {
699 inputs: self.inputs[..train_size].to_vec(),
700 targets: self.targets[..train_size].to_vec(),
701 timestamps: self.timestamps[..train_size].to_vec(),
702 features: self.features.as_ref().map(|f| f[..train_size].to_vec()),
703 labels: self.labels.as_ref().map(|l| l[..train_size].to_vec()),
704 sequence_lengths: self
705 .sequence_lengths
706 .as_ref()
707 .map(|s| s[..train_size].to_vec()),
708 missing_mask: self.missing_mask.as_ref().map(|m| m[..train_size].to_vec()),
709 sample_weights: self
710 .sample_weights
711 .as_ref()
712 .map(|w| w[..train_size].to_vec()),
713 metadata: self.metadata.as_ref().map(|m| m[..train_size].to_vec()),
714 };
715
716 let test_data = Self {
717 inputs: self.inputs[train_size..].to_vec(),
718 targets: self.targets[train_size..].to_vec(),
719 timestamps: self.timestamps[train_size..].to_vec(),
720 features: self.features.as_ref().map(|f| f[train_size..].to_vec()),
721 labels: self.labels.as_ref().map(|l| l[train_size..].to_vec()),
722 sequence_lengths: self
723 .sequence_lengths
724 .as_ref()
725 .map(|s| s[train_size..].to_vec()),
726 missing_mask: self.missing_mask.as_ref().map(|m| m[train_size..].to_vec()),
727 sample_weights: self
728 .sample_weights
729 .as_ref()
730 .map(|w| w[train_size..].to_vec()),
731 metadata: self.metadata.as_ref().map(|m| m[train_size..].to_vec()),
732 };
733
734 (train_data, test_data)
735 }
736}
737
738#[derive(Debug, Clone)]
740pub struct TrainingExample {
741 pub input: Array1<f64>,
743 pub reservoir_state: Array1<f64>,
745 pub features: Array1<f64>,
747 pub target: Array1<f64>,
749 pub prediction: Array1<f64>,
751 pub error: f64,
753 pub confidence: f64,
755 pub timestamp: f64,
757 pub metadata: HashMap<String, f64>,
759}
760
761#[derive(Debug, Clone, Default, Serialize, Deserialize)]
763pub struct ReservoirMetrics {
764 pub training_examples: usize,
766 pub prediction_accuracy: f64,
768 pub memory_capacity: f64,
770 pub nonlinear_memory_capacity: f64,
772 pub processing_capacity: f64,
774 pub generalization_error: f64,
776 pub echo_state_property: f64,
778 pub avg_processing_time_ms: f64,
780 pub quantum_resource_usage: f64,
782 pub temporal_correlation_length: f64,
784 pub reservoir_efficiency: f64,
786 pub adaptation_rate: f64,
788 pub plasticity_level: f64,
790 pub hardware_utilization: f64,
792 pub error_mitigation_overhead: f64,
794 pub quantum_advantage: f64,
796 pub computational_complexity: f64,
798}
799
800pub struct QuantumReservoirComputerEnhanced {
802 config: QuantumReservoirConfig,
804 reservoir_state: QuantumReservoirState,
806 reservoir_circuit: InterfaceCircuit,
808 input_coupling_circuit: InterfaceCircuit,
810 output_weights: Array2<f64>,
812 time_series_predictor: Option<TimeSeriesPredictor>,
814 memory_analyzer: MemoryAnalyzer,
816 simulator: StateVectorSimulator,
818 circuit_interface: CircuitInterface,
820 metrics: ReservoirMetrics,
822 training_history: VecDeque<TrainingExample>,
824 backend: Option<SciRS2Backend>,
826 rng: Arc<Mutex<rand::rngs::ThreadRng>>,
828}
829
830#[derive(Debug, Clone, Serialize, Deserialize)]
832pub struct TimeSeriesPredictor {
833 pub arima_params: ARIMAParams,
835 pub nar_state: NARState,
837 pub kernel_weights: Array1<f64>,
839 pub trend_model: TrendModel,
841}
842
843#[derive(Debug, Clone, Serialize, Deserialize)]
845pub struct ARIMAParams {
846 pub ar_coeffs: Array1<f64>,
848 pub ma_coeffs: Array1<f64>,
850 pub diff_order: usize,
852 pub residuals: VecDeque<f64>,
854 pub variance: f64,
856}
857
858#[derive(Debug, Clone, Serialize, Deserialize)]
860pub struct NARState {
861 pub order: usize,
863 pub coeffs: Array2<f64>,
865 pub history: VecDeque<f64>,
867 pub activation: ActivationFunction,
869}
870
871#[derive(Debug, Clone, Serialize, Deserialize)]
873pub struct TrendModel {
874 pub params: Vec<f64>,
876 pub strength: f64,
878 pub direction: f64,
880}
881
882#[derive(Debug)]
884pub struct MemoryAnalyzer {
885 pub config: MemoryAnalysisConfig,
887 pub capacity_estimates: HashMap<String, f64>,
889 pub nonlinearity_measures: HashMap<usize, f64>,
891 pub temporal_correlations: Array2<f64>,
893 pub ipc_metrics: HashMap<String, f64>,
895}
896
897impl QuantumReservoirComputerEnhanced {
898 pub fn new(config: QuantumReservoirConfig) -> Result<Self> {
900 let circuit_interface = CircuitInterface::new(Default::default())?;
901 let simulator = StateVectorSimulator::new();
902
903 let reservoir_state = QuantumReservoirState::new(config.num_qubits, config.memory_capacity);
904
905 let reservoir_circuit = Self::generate_reservoir_circuit(&config)?;
907
908 let input_coupling_circuit = Self::generate_input_coupling_circuit(&config)?;
910
911 let output_size = Self::calculate_output_size(&config);
913 let feature_size = Self::calculate_feature_size(&config);
914 let mut output_weights = Array2::zeros((output_size, feature_size));
915
916 let scale = (2.0 / (output_size + feature_size) as f64).sqrt();
918 for elem in output_weights.iter_mut() {
919 *elem = (fastrand::f64() - 0.5) * 2.0 * scale;
920 }
921
922 let time_series_predictor =
924 if config.time_series_config.enable_arima || config.time_series_config.enable_nar {
925 Some(TimeSeriesPredictor::new(&config.time_series_config))
926 } else {
927 None
928 };
929
930 let memory_analyzer = MemoryAnalyzer::new(config.memory_config.clone());
932
933 Ok(Self {
934 config,
935 reservoir_state,
936 reservoir_circuit,
937 input_coupling_circuit,
938 output_weights,
939 time_series_predictor,
940 memory_analyzer,
941 simulator,
942 circuit_interface,
943 metrics: ReservoirMetrics::default(),
944 training_history: VecDeque::with_capacity(10000),
945 backend: None,
946 rng: Arc::new(Mutex::new(rand::thread_rng())),
947 })
948 }
949
950 fn generate_reservoir_circuit(config: &QuantumReservoirConfig) -> Result<InterfaceCircuit> {
952 let mut circuit = InterfaceCircuit::new(config.num_qubits, 0);
953
954 match config.architecture {
955 QuantumReservoirArchitecture::RandomCircuit => {
956 Self::generate_random_circuit(&mut circuit, config)?;
957 }
958 QuantumReservoirArchitecture::SpinChain => {
959 Self::generate_spin_chain_circuit(&mut circuit, config)?;
960 }
961 QuantumReservoirArchitecture::TransverseFieldIsing => {
962 Self::generate_tfim_circuit(&mut circuit, config)?;
963 }
964 QuantumReservoirArchitecture::SmallWorld => {
965 Self::generate_small_world_circuit(&mut circuit, config)?;
966 }
967 QuantumReservoirArchitecture::FullyConnected => {
968 Self::generate_fully_connected_circuit(&mut circuit, config)?;
969 }
970 QuantumReservoirArchitecture::ScaleFree => {
971 Self::generate_scale_free_circuit(&mut circuit, config)?;
972 }
973 QuantumReservoirArchitecture::HierarchicalModular => {
974 Self::generate_hierarchical_circuit(&mut circuit, config)?;
975 }
976 QuantumReservoirArchitecture::Ring => {
977 Self::generate_ring_circuit(&mut circuit, config)?;
978 }
979 QuantumReservoirArchitecture::Grid => {
980 Self::generate_grid_circuit(&mut circuit, config)?;
981 }
982 _ => {
983 Self::generate_random_circuit(&mut circuit, config)?;
985 }
986 }
987
988 Ok(circuit)
989 }
990
991 fn generate_random_circuit(
993 circuit: &mut InterfaceCircuit,
994 config: &QuantumReservoirConfig,
995 ) -> Result<()> {
996 let depth = config.evolution_steps;
997
998 for _ in 0..depth {
999 for qubit in 0..config.num_qubits {
1001 let angle = fastrand::f64() * 2.0 * PI;
1002 let gate_type = match fastrand::usize(0..3) {
1003 0 => InterfaceGateType::RX(angle),
1004 1 => InterfaceGateType::RY(angle),
1005 _ => InterfaceGateType::RZ(angle),
1006 };
1007 circuit.add_gate(InterfaceGate::new(gate_type, vec![qubit]));
1008 }
1009
1010 for _ in 0..(config.num_qubits / 2) {
1012 let qubit1 = fastrand::usize(0..config.num_qubits);
1013 let qubit2 = fastrand::usize(0..config.num_qubits);
1014 if qubit1 != qubit2 {
1015 circuit.add_gate(InterfaceGate::new(
1016 InterfaceGateType::CNOT,
1017 vec![qubit1, qubit2],
1018 ));
1019 }
1020 }
1021 }
1022
1023 Ok(())
1024 }
1025
1026 fn generate_spin_chain_circuit(
1028 circuit: &mut InterfaceCircuit,
1029 config: &QuantumReservoirConfig,
1030 ) -> Result<()> {
1031 let coupling = config.coupling_strength;
1032
1033 for _ in 0..config.evolution_steps {
1034 for i in 0..config.num_qubits - 1 {
1036 circuit.add_gate(InterfaceGate::new(
1038 InterfaceGateType::RZ(coupling * config.time_step),
1039 vec![i],
1040 ));
1041 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1042 circuit.add_gate(InterfaceGate::new(
1043 InterfaceGateType::RZ(coupling * config.time_step),
1044 vec![i + 1],
1045 ));
1046 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1047 }
1048 }
1049
1050 Ok(())
1051 }
1052
1053 fn generate_tfim_circuit(
1055 circuit: &mut InterfaceCircuit,
1056 config: &QuantumReservoirConfig,
1057 ) -> Result<()> {
1058 let coupling = config.coupling_strength;
1059 let field = coupling * 0.5; for _ in 0..config.evolution_steps {
1062 for qubit in 0..config.num_qubits {
1064 circuit.add_gate(InterfaceGate::new(
1065 InterfaceGateType::RX(field * config.time_step),
1066 vec![qubit],
1067 ));
1068 }
1069
1070 for i in 0..config.num_qubits - 1 {
1072 circuit.add_gate(InterfaceGate::new(
1073 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1074 vec![i],
1075 ));
1076 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1077 circuit.add_gate(InterfaceGate::new(
1078 InterfaceGateType::RZ(coupling * config.time_step),
1079 vec![i + 1],
1080 ));
1081 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1082 circuit.add_gate(InterfaceGate::new(
1083 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1084 vec![i],
1085 ));
1086 }
1087 }
1088
1089 Ok(())
1090 }
1091
1092 fn generate_small_world_circuit(
1094 circuit: &mut InterfaceCircuit,
1095 config: &QuantumReservoirConfig,
1096 ) -> Result<()> {
1097 let coupling = config.coupling_strength;
1098 let rewiring_prob = 0.1; for _ in 0..config.evolution_steps {
1101 for i in 0..config.num_qubits {
1103 let next = (i + 1) % config.num_qubits;
1104
1105 let target = if fastrand::f64() < rewiring_prob {
1107 fastrand::usize(0..config.num_qubits)
1108 } else {
1109 next
1110 };
1111
1112 if target != i {
1113 circuit.add_gate(InterfaceGate::new(
1114 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1115 vec![i],
1116 ));
1117 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, target]));
1118 circuit.add_gate(InterfaceGate::new(
1119 InterfaceGateType::RZ(coupling * config.time_step),
1120 vec![target],
1121 ));
1122 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, target]));
1123 circuit.add_gate(InterfaceGate::new(
1124 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1125 vec![i],
1126 ));
1127 }
1128 }
1129 }
1130
1131 Ok(())
1132 }
1133
1134 fn generate_fully_connected_circuit(
1136 circuit: &mut InterfaceCircuit,
1137 config: &QuantumReservoirConfig,
1138 ) -> Result<()> {
1139 let coupling = config.coupling_strength / config.num_qubits as f64; for _ in 0..config.evolution_steps {
1142 for i in 0..config.num_qubits {
1144 for j in i + 1..config.num_qubits {
1145 circuit.add_gate(InterfaceGate::new(
1146 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1147 vec![i],
1148 ));
1149 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1150 circuit.add_gate(InterfaceGate::new(
1151 InterfaceGateType::RZ(coupling * config.time_step),
1152 vec![j],
1153 ));
1154 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1155 circuit.add_gate(InterfaceGate::new(
1156 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1157 vec![i],
1158 ));
1159 }
1160 }
1161 }
1162
1163 Ok(())
1164 }
1165
1166 fn generate_scale_free_circuit(
1168 circuit: &mut InterfaceCircuit,
1169 config: &QuantumReservoirConfig,
1170 ) -> Result<()> {
1171 let mut degree_dist = vec![1; config.num_qubits];
1173 let coupling = config.coupling_strength;
1174
1175 for _ in 0..config.evolution_steps {
1176 for i in 0..config.num_qubits {
1178 let total_degree: usize = degree_dist.iter().sum();
1180 let prob_threshold = degree_dist[i] as f64 / total_degree as f64;
1181
1182 if fastrand::f64() < prob_threshold {
1183 let j = fastrand::usize(0..config.num_qubits);
1184 if i != j {
1185 circuit.add_gate(InterfaceGate::new(
1187 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1188 vec![i],
1189 ));
1190 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1191 circuit.add_gate(InterfaceGate::new(
1192 InterfaceGateType::RZ(coupling * config.time_step),
1193 vec![j],
1194 ));
1195 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1196
1197 degree_dist[i] += 1;
1199 degree_dist[j] += 1;
1200 }
1201 }
1202 }
1203 }
1204
1205 Ok(())
1206 }
1207
1208 fn generate_hierarchical_circuit(
1210 circuit: &mut InterfaceCircuit,
1211 config: &QuantumReservoirConfig,
1212 ) -> Result<()> {
1213 let coupling = config.coupling_strength;
1214 let module_size = (config.num_qubits as f64).sqrt() as usize;
1215
1216 for _ in 0..config.evolution_steps {
1217 for module in 0..(config.num_qubits / module_size) {
1219 let start = module * module_size;
1220 let end = ((module + 1) * module_size).min(config.num_qubits);
1221
1222 for i in start..end {
1223 for j in (i + 1)..end {
1224 circuit.add_gate(InterfaceGate::new(
1225 InterfaceGateType::RZ(coupling * config.time_step),
1226 vec![i],
1227 ));
1228 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1229 }
1230 }
1231 }
1232
1233 for i in 0..config.num_qubits {
1235 let j = fastrand::usize(0..config.num_qubits);
1236 if i / module_size != j / module_size && i != j {
1237 circuit.add_gate(InterfaceGate::new(
1238 InterfaceGateType::RZ(coupling * config.time_step * 0.3),
1239 vec![i],
1240 ));
1241 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1242 }
1243 }
1244 }
1245
1246 Ok(())
1247 }
1248
1249 fn generate_ring_circuit(
1251 circuit: &mut InterfaceCircuit,
1252 config: &QuantumReservoirConfig,
1253 ) -> Result<()> {
1254 let coupling = config.coupling_strength;
1255
1256 for _ in 0..config.evolution_steps {
1257 for i in 0..config.num_qubits {
1259 let j = (i + 1) % config.num_qubits;
1260
1261 circuit.add_gate(InterfaceGate::new(
1262 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1263 vec![i],
1264 ));
1265 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1266 circuit.add_gate(InterfaceGate::new(
1267 InterfaceGateType::RZ(coupling * config.time_step),
1268 vec![j],
1269 ));
1270 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1271 }
1272
1273 if fastrand::f64() < 0.1 {
1275 let i = fastrand::usize(0..config.num_qubits);
1276 let j = fastrand::usize(0..config.num_qubits);
1277 if i != j && (i as i32 - j as i32).abs() > 2 {
1278 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1279 }
1280 }
1281 }
1282
1283 Ok(())
1284 }
1285
1286 fn generate_grid_circuit(
1288 circuit: &mut InterfaceCircuit,
1289 config: &QuantumReservoirConfig,
1290 ) -> Result<()> {
1291 let coupling = config.coupling_strength;
1292 let grid_size = (config.num_qubits as f64).sqrt() as usize;
1293
1294 for _ in 0..config.evolution_steps {
1295 for i in 0..grid_size {
1297 for j in 0..grid_size {
1298 let current = i * grid_size + j;
1299 if current >= config.num_qubits {
1300 break;
1301 }
1302
1303 if j + 1 < grid_size {
1305 let neighbor = i * grid_size + j + 1;
1306 if neighbor < config.num_qubits {
1307 circuit.add_gate(InterfaceGate::new(
1308 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1309 vec![current],
1310 ));
1311 circuit.add_gate(InterfaceGate::new(
1312 InterfaceGateType::CNOT,
1313 vec![current, neighbor],
1314 ));
1315 }
1316 }
1317
1318 if i + 1 < grid_size {
1320 let neighbor = (i + 1) * grid_size + j;
1321 if neighbor < config.num_qubits {
1322 circuit.add_gate(InterfaceGate::new(
1323 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1324 vec![current],
1325 ));
1326 circuit.add_gate(InterfaceGate::new(
1327 InterfaceGateType::CNOT,
1328 vec![current, neighbor],
1329 ));
1330 }
1331 }
1332 }
1333 }
1334 }
1335
1336 Ok(())
1337 }
1338
1339 fn generate_input_coupling_circuit(
1341 config: &QuantumReservoirConfig,
1342 ) -> Result<InterfaceCircuit> {
1343 let mut circuit = InterfaceCircuit::new(config.num_qubits, 0);
1344
1345 match config.input_encoding {
1346 InputEncoding::Amplitude => {
1347 for qubit in 0..config.num_qubits {
1349 circuit.add_gate(InterfaceGate::new(
1350 InterfaceGateType::RY(0.0), vec![qubit],
1352 ));
1353 }
1354 }
1355 InputEncoding::Phase => {
1356 for qubit in 0..config.num_qubits {
1358 circuit.add_gate(InterfaceGate::new(
1359 InterfaceGateType::RZ(0.0), vec![qubit],
1361 ));
1362 }
1363 }
1364 InputEncoding::BasisState => {
1365 for qubit in 0..config.num_qubits {
1367 circuit.add_gate(InterfaceGate::new(InterfaceGateType::X, vec![qubit]));
1368 }
1369 }
1370 InputEncoding::Angle => {
1371 for qubit in 0..config.num_qubits {
1373 circuit.add_gate(InterfaceGate::new(InterfaceGateType::RX(0.0), vec![qubit]));
1374 circuit.add_gate(InterfaceGate::new(InterfaceGateType::RY(0.0), vec![qubit]));
1375 }
1376 }
1377 _ => {
1378 for qubit in 0..config.num_qubits {
1380 circuit.add_gate(InterfaceGate::new(InterfaceGateType::RY(0.0), vec![qubit]));
1381 }
1382 }
1383 }
1384
1385 Ok(circuit)
1386 }
1387
1388 fn calculate_output_size(config: &QuantumReservoirConfig) -> usize {
1390 1
1392 }
1393
1394 fn calculate_feature_size(config: &QuantumReservoirConfig) -> usize {
1396 match config.output_measurement {
1397 OutputMeasurement::PauliExpectation => config.num_qubits * 3,
1398 OutputMeasurement::Probability => 1 << config.num_qubits.min(10), OutputMeasurement::Correlations => config.num_qubits * config.num_qubits,
1400 OutputMeasurement::Entanglement => config.num_qubits,
1401 OutputMeasurement::Fidelity => 1,
1402 OutputMeasurement::QuantumFisherInformation => config.num_qubits,
1403 OutputMeasurement::Variance => config.num_qubits * 3,
1404 OutputMeasurement::HigherOrderMoments => config.num_qubits * 6, OutputMeasurement::SpectralProperties => config.num_qubits,
1406 OutputMeasurement::QuantumCoherence => config.num_qubits,
1407 OutputMeasurement::Purity => 1,
1408 OutputMeasurement::QuantumMutualInformation => config.num_qubits * config.num_qubits,
1409 OutputMeasurement::ProcessTomography => config.num_qubits * config.num_qubits * 4,
1410 OutputMeasurement::TemporalCorrelations => config.memory_capacity,
1411 OutputMeasurement::NonLinearReadout => config.num_qubits * 2,
1412 }
1413 }
1414
1415 pub fn process_input(&mut self, input: &Array1<f64>) -> Result<Array1<f64>> {
1417 let start_time = std::time::Instant::now();
1418
1419 self.encode_input(input)?;
1421
1422 self.evolve_reservoir()?;
1424
1425 let features = self.extract_features()?;
1427
1428 let timestamp = start_time.elapsed().as_secs_f64();
1430 self.reservoir_state
1431 .update_state(self.reservoir_state.state_vector.clone(), timestamp);
1432
1433 let processing_time = start_time.elapsed().as_secs_f64() * 1000.0;
1435 self.update_processing_time(processing_time);
1436
1437 Ok(features)
1438 }
1439
1440 fn encode_input(&mut self, input: &Array1<f64>) -> Result<()> {
1442 match self.config.input_encoding {
1443 InputEncoding::Amplitude => {
1444 self.encode_amplitude(input)?;
1445 }
1446 InputEncoding::Phase => {
1447 self.encode_phase(input)?;
1448 }
1449 InputEncoding::BasisState => {
1450 self.encode_basis_state(input)?;
1451 }
1452 InputEncoding::Angle => {
1453 self.encode_angle(input)?;
1454 }
1455 _ => {
1456 self.encode_amplitude(input)?;
1457 }
1458 }
1459 Ok(())
1460 }
1461
1462 fn encode_amplitude(&mut self, input: &Array1<f64>) -> Result<()> {
1464 let num_inputs = input.len().min(self.config.num_qubits);
1465
1466 for i in 0..num_inputs {
1467 let angle = input[i] * PI; self.apply_single_qubit_rotation(i, InterfaceGateType::RY(angle))?;
1469 }
1470
1471 Ok(())
1472 }
1473
1474 fn encode_phase(&mut self, input: &Array1<f64>) -> Result<()> {
1476 let num_inputs = input.len().min(self.config.num_qubits);
1477
1478 for i in 0..num_inputs {
1479 let angle = input[i] * 2.0 * PI; self.apply_single_qubit_rotation(i, InterfaceGateType::RZ(angle))?;
1481 }
1482
1483 Ok(())
1484 }
1485
1486 fn encode_basis_state(&mut self, input: &Array1<f64>) -> Result<()> {
1488 let num_inputs = input.len().min(self.config.num_qubits);
1489
1490 for i in 0..num_inputs {
1491 if input[i] > 0.5 {
1492 self.apply_single_qubit_gate(i, InterfaceGateType::X)?;
1493 }
1494 }
1495
1496 Ok(())
1497 }
1498
1499 fn encode_angle(&mut self, input: &Array1<f64>) -> Result<()> {
1501 let num_inputs = input.len().min(self.config.num_qubits);
1502
1503 for i in 0..num_inputs {
1504 let angle_x = input[i] * PI;
1505 let angle_y = if i + 1 < input.len() {
1506 input[i + 1] * PI
1507 } else {
1508 0.0
1509 };
1510
1511 self.apply_single_qubit_rotation(i, InterfaceGateType::RX(angle_x))?;
1512 self.apply_single_qubit_rotation(i, InterfaceGateType::RY(angle_y))?;
1513 }
1514
1515 Ok(())
1516 }
1517
1518 fn apply_single_qubit_rotation(
1520 &mut self,
1521 qubit: usize,
1522 gate_type: InterfaceGateType,
1523 ) -> Result<()> {
1524 let mut temp_circuit = InterfaceCircuit::new(self.config.num_qubits, 0);
1525 temp_circuit.add_gate(InterfaceGate::new(gate_type, vec![qubit]));
1526
1527 self.simulator.apply_interface_circuit(&temp_circuit)?;
1528
1529 Ok(())
1530 }
1531
1532 fn apply_single_qubit_gate(
1534 &mut self,
1535 qubit: usize,
1536 gate_type: InterfaceGateType,
1537 ) -> Result<()> {
1538 let mut temp_circuit = InterfaceCircuit::new(self.config.num_qubits, 0);
1539 temp_circuit.add_gate(InterfaceGate::new(gate_type, vec![qubit]));
1540
1541 self.simulator.apply_interface_circuit(&temp_circuit)?;
1542
1543 Ok(())
1544 }
1545
1546 fn evolve_reservoir(&mut self) -> Result<()> {
1548 match self.config.dynamics {
1549 ReservoirDynamics::Unitary => {
1550 self.evolve_unitary()?;
1551 }
1552 ReservoirDynamics::Open => {
1553 self.evolve_open_system()?;
1554 }
1555 ReservoirDynamics::NISQ => {
1556 self.evolve_nisq()?;
1557 }
1558 ReservoirDynamics::Adiabatic => {
1559 self.evolve_adiabatic()?;
1560 }
1561 ReservoirDynamics::Floquet => {
1562 self.evolve_floquet()?;
1563 }
1564 _ => {
1565 self.evolve_unitary()?;
1567 }
1568 }
1569 Ok(())
1570 }
1571
1572 fn evolve_unitary(&mut self) -> Result<()> {
1574 self.simulator
1575 .apply_interface_circuit(&self.reservoir_circuit)?;
1576 Ok(())
1577 }
1578
1579 fn evolve_open_system(&mut self) -> Result<()> {
1581 self.evolve_unitary()?;
1583
1584 self.apply_decoherence()?;
1586
1587 Ok(())
1588 }
1589
1590 fn evolve_nisq(&mut self) -> Result<()> {
1592 self.evolve_unitary()?;
1594
1595 self.apply_gate_errors()?;
1597
1598 self.apply_measurement_errors()?;
1600
1601 Ok(())
1602 }
1603
1604 fn evolve_adiabatic(&mut self) -> Result<()> {
1606 self.evolve_unitary()?;
1609 Ok(())
1610 }
1611
1612 fn evolve_floquet(&mut self) -> Result<()> {
1614 let drive_frequency = 1.0;
1616 let time = self.reservoir_state.time_index as f64 * self.config.time_step;
1617 let drive_strength = (drive_frequency * time).sin();
1618
1619 for qubit in 0..self.config.num_qubits {
1621 let angle = drive_strength * self.config.time_step;
1622 self.apply_single_qubit_rotation(qubit, InterfaceGateType::RX(angle))?;
1623 }
1624
1625 self.evolve_unitary()?;
1627
1628 Ok(())
1629 }
1630
1631 fn apply_decoherence(&mut self) -> Result<()> {
1633 let decoherence_rate = self.config.noise_level;
1634
1635 for amplitude in self.reservoir_state.state_vector.iter_mut() {
1636 let phase_noise = (fastrand::f64() - 0.5) * decoherence_rate * 2.0 * PI;
1638 *amplitude *= Complex64::new(0.0, phase_noise).exp();
1639
1640 let damping = (1.0 - decoherence_rate).sqrt();
1642 *amplitude *= damping;
1643 }
1644
1645 let norm: f64 = self
1647 .reservoir_state
1648 .state_vector
1649 .iter()
1650 .map(|x| x.norm_sqr())
1651 .sum::<f64>()
1652 .sqrt();
1653
1654 if norm > 1e-15 {
1655 self.reservoir_state.state_vector.mapv_inplace(|x| x / norm);
1656 }
1657
1658 Ok(())
1659 }
1660
1661 fn apply_gate_errors(&mut self) -> Result<()> {
1663 let error_rate = self.config.noise_level;
1664
1665 for qubit in 0..self.config.num_qubits {
1666 if fastrand::f64() < error_rate {
1667 let error_type = fastrand::usize(0..3);
1668 let gate_type = match error_type {
1669 0 => InterfaceGateType::X,
1670 1 => InterfaceGateType::PauliY,
1671 _ => InterfaceGateType::PauliZ,
1672 };
1673 self.apply_single_qubit_gate(qubit, gate_type)?;
1674 }
1675 }
1676
1677 Ok(())
1678 }
1679
1680 fn apply_measurement_errors(&mut self) -> Result<()> {
1682 let error_rate = self.config.noise_level * 0.1; if fastrand::f64() < error_rate {
1685 let qubit = fastrand::usize(0..self.config.num_qubits);
1686 self.apply_single_qubit_gate(qubit, InterfaceGateType::X)?;
1687 }
1688
1689 Ok(())
1690 }
1691
1692 fn extract_features(&mut self) -> Result<Array1<f64>> {
1694 match self.config.output_measurement {
1695 OutputMeasurement::PauliExpectation => self.measure_pauli_expectations(),
1696 OutputMeasurement::Probability => self.measure_probabilities(),
1697 OutputMeasurement::Correlations => self.measure_correlations(),
1698 OutputMeasurement::Entanglement => self.measure_entanglement(),
1699 OutputMeasurement::Fidelity => self.measure_fidelity(),
1700 OutputMeasurement::QuantumFisherInformation => {
1701 self.measure_quantum_fisher_information()
1702 }
1703 OutputMeasurement::Variance => self.measure_variance(),
1704 OutputMeasurement::HigherOrderMoments => self.measure_higher_order_moments(),
1705 OutputMeasurement::QuantumCoherence => self.measure_quantum_coherence(),
1706 OutputMeasurement::Purity => self.measure_purity(),
1707 OutputMeasurement::TemporalCorrelations => self.measure_temporal_correlations(),
1708 _ => {
1709 self.measure_pauli_expectations()
1711 }
1712 }
1713 }
1714
1715 fn measure_pauli_expectations(&self) -> Result<Array1<f64>> {
1717 let mut expectations = Vec::new();
1718
1719 for qubit in 0..self.config.num_qubits {
1720 let x_exp = self.calculate_single_qubit_expectation(
1722 qubit,
1723 &[
1724 Complex64::new(0.0, 0.0),
1725 Complex64::new(1.0, 0.0),
1726 Complex64::new(1.0, 0.0),
1727 Complex64::new(0.0, 0.0),
1728 ],
1729 )?;
1730 expectations.push(x_exp);
1731
1732 let y_exp = self.calculate_single_qubit_expectation(
1734 qubit,
1735 &[
1736 Complex64::new(0.0, 0.0),
1737 Complex64::new(0.0, -1.0),
1738 Complex64::new(0.0, 1.0),
1739 Complex64::new(0.0, 0.0),
1740 ],
1741 )?;
1742 expectations.push(y_exp);
1743
1744 let z_exp = self.calculate_single_qubit_expectation(
1746 qubit,
1747 &[
1748 Complex64::new(1.0, 0.0),
1749 Complex64::new(0.0, 0.0),
1750 Complex64::new(0.0, 0.0),
1751 Complex64::new(-1.0, 0.0),
1752 ],
1753 )?;
1754 expectations.push(z_exp);
1755 }
1756
1757 Ok(Array1::from_vec(expectations))
1758 }
1759
1760 fn calculate_single_qubit_expectation(
1762 &self,
1763 qubit: usize,
1764 pauli_matrix: &[Complex64; 4],
1765 ) -> Result<f64> {
1766 let state = &self.reservoir_state.state_vector;
1767 let mut expectation = 0.0;
1768
1769 for i in 0..state.len() {
1770 for j in 0..state.len() {
1771 let i_bit = (i >> qubit) & 1;
1772 let j_bit = (j >> qubit) & 1;
1773 let matrix_element = pauli_matrix[i_bit * 2 + j_bit];
1774
1775 expectation += (state[i].conj() * matrix_element * state[j]).re;
1776 }
1777 }
1778
1779 Ok(expectation)
1780 }
1781
1782 fn measure_probabilities(&self) -> Result<Array1<f64>> {
1784 let probabilities: Vec<f64> = self
1785 .reservoir_state
1786 .state_vector
1787 .iter()
1788 .map(|x| x.norm_sqr())
1789 .collect();
1790
1791 let max_size = 1 << 10; if probabilities.len() > max_size {
1794 let mut sampled = Vec::with_capacity(max_size);
1796 for _ in 0..max_size {
1797 let idx = fastrand::usize(0..probabilities.len());
1798 sampled.push(probabilities[idx]);
1799 }
1800 Ok(Array1::from_vec(sampled))
1801 } else {
1802 Ok(Array1::from_vec(probabilities))
1803 }
1804 }
1805
1806 fn measure_correlations(&mut self) -> Result<Array1<f64>> {
1808 let mut correlations = Vec::new();
1809
1810 for i in 0..self.config.num_qubits {
1811 for j in 0..self.config.num_qubits {
1812 if i != j {
1813 let corr = self.calculate_two_qubit_correlation(i, j)?;
1815 correlations.push(corr);
1816 self.reservoir_state.correlations[[i, j]] = corr;
1817 } else {
1818 correlations.push(1.0); self.reservoir_state.correlations[[i, j]] = 1.0;
1820 }
1821 }
1822 }
1823
1824 Ok(Array1::from_vec(correlations))
1825 }
1826
1827 fn calculate_two_qubit_correlation(&self, qubit1: usize, qubit2: usize) -> Result<f64> {
1829 let state = &self.reservoir_state.state_vector;
1830 let mut correlation = 0.0;
1831
1832 for i in 0..state.len() {
1833 let bit1 = (i >> qubit1) & 1;
1834 let bit2 = (i >> qubit2) & 1;
1835 let sign = if bit1 == bit2 { 1.0 } else { -1.0 };
1836 correlation += sign * state[i].norm_sqr();
1837 }
1838
1839 Ok(correlation)
1840 }
1841
1842 fn measure_entanglement(&self) -> Result<Array1<f64>> {
1844 let mut entanglement_measures = Vec::new();
1845
1846 for qubit in 0..self.config.num_qubits {
1848 let entropy = self.calculate_von_neumann_entropy(qubit)?;
1850 entanglement_measures.push(entropy);
1851 }
1852
1853 Ok(Array1::from_vec(entanglement_measures))
1854 }
1855
1856 fn calculate_von_neumann_entropy(&self, _qubit: usize) -> Result<f64> {
1858 let state = &self.reservoir_state.state_vector;
1859 let mut entropy = 0.0;
1860
1861 for amplitude in state.iter() {
1862 let prob = amplitude.norm_sqr();
1863 if prob > 1e-15 {
1864 entropy -= prob * prob.ln();
1865 }
1866 }
1867
1868 Ok(entropy / (state.len() as f64).ln()) }
1870
1871 fn measure_fidelity(&self) -> Result<Array1<f64>> {
1873 let fidelity = self.reservoir_state.state_vector[0].norm_sqr();
1875 Ok(Array1::from_vec(vec![fidelity]))
1876 }
1877
1878 fn measure_quantum_fisher_information(&self) -> Result<Array1<f64>> {
1880 let mut qfi_values = Vec::new();
1881
1882 for qubit in 0..self.config.num_qubits {
1883 let z_exp = self.calculate_single_qubit_expectation(
1885 qubit,
1886 &[
1887 Complex64::new(1.0, 0.0),
1888 Complex64::new(0.0, 0.0),
1889 Complex64::new(0.0, 0.0),
1890 Complex64::new(-1.0, 0.0),
1891 ],
1892 )?;
1893
1894 let qfi = 4.0 * (1.0 - z_exp * z_exp);
1896 qfi_values.push(qfi);
1897 }
1898
1899 Ok(Array1::from_vec(qfi_values))
1900 }
1901
1902 fn measure_variance(&self) -> Result<Array1<f64>> {
1904 let mut variances = Vec::new();
1905
1906 for qubit in 0..self.config.num_qubits {
1907 for pauli_idx in 0..3 {
1909 let pauli_matrix = match pauli_idx {
1910 0 => [
1911 Complex64::new(0.0, 0.0),
1912 Complex64::new(1.0, 0.0),
1913 Complex64::new(1.0, 0.0),
1914 Complex64::new(0.0, 0.0),
1915 ],
1916 1 => [
1917 Complex64::new(0.0, 0.0),
1918 Complex64::new(0.0, -1.0),
1919 Complex64::new(0.0, 1.0),
1920 Complex64::new(0.0, 0.0),
1921 ],
1922 _ => [
1923 Complex64::new(1.0, 0.0),
1924 Complex64::new(0.0, 0.0),
1925 Complex64::new(0.0, 0.0),
1926 Complex64::new(-1.0, 0.0),
1927 ],
1928 };
1929
1930 let expectation = self.calculate_single_qubit_expectation(qubit, &pauli_matrix)?;
1931 let variance = 1.0 - expectation * expectation; variances.push(variance);
1933 }
1934 }
1935
1936 Ok(Array1::from_vec(variances))
1937 }
1938
1939 fn measure_higher_order_moments(&self) -> Result<Array1<f64>> {
1941 let mut moments = Vec::new();
1942
1943 for qubit in 0..self.config.num_qubits {
1944 let z_exp = self.calculate_single_qubit_expectation(
1946 qubit,
1947 &[
1948 Complex64::new(1.0, 0.0),
1949 Complex64::new(0.0, 0.0),
1950 Complex64::new(0.0, 0.0),
1951 Complex64::new(-1.0, 0.0),
1952 ],
1953 )?;
1954
1955 moments.push(z_exp);
1957
1958 let variance = 1.0 - z_exp * z_exp;
1960 moments.push(variance);
1961
1962 moments.push(0.0);
1965
1966 moments.push(variance * variance);
1968
1969 moments.push(z_exp * variance);
1971
1972 moments.push(variance * variance * variance);
1974 }
1975
1976 Ok(Array1::from_vec(moments))
1977 }
1978
1979 fn measure_quantum_coherence(&self) -> Result<Array1<f64>> {
1981 let mut coherence_measures = Vec::new();
1982
1983 for qubit in 0..self.config.num_qubits {
1984 let mut coherence = 0.0;
1986 let state = &self.reservoir_state.state_vector;
1987
1988 for i in 0..state.len() {
1989 for j in 0..state.len() {
1990 if i != j {
1991 let i_bit = (i >> qubit) & 1;
1992 let j_bit = (j >> qubit) & 1;
1993 if i_bit != j_bit {
1994 coherence += (state[i].conj() * state[j]).norm();
1995 }
1996 }
1997 }
1998 }
1999
2000 coherence_measures.push(coherence);
2001 }
2002
2003 Ok(Array1::from_vec(coherence_measures))
2004 }
2005
2006 fn measure_purity(&self) -> Result<Array1<f64>> {
2008 let state = &self.reservoir_state.state_vector;
2010 let purity = state.iter().map(|x| x.norm_sqr().powi(2)).sum::<f64>();
2011
2012 Ok(Array1::from_vec(vec![purity]))
2013 }
2014
2015 fn measure_temporal_correlations(&self) -> Result<Array1<f64>> {
2017 let mut correlations = Vec::new();
2018
2019 let current_state = &self.reservoir_state.state_vector;
2021
2022 for past_state in self.reservoir_state.state_history.iter() {
2023 let correlation = current_state
2024 .iter()
2025 .zip(past_state.iter())
2026 .map(|(a, b)| (a.conj() * b).re)
2027 .sum::<f64>();
2028 correlations.push(correlation);
2029 }
2030
2031 while correlations.len() < self.config.memory_capacity {
2033 correlations.push(0.0);
2034 }
2035
2036 Ok(Array1::from_vec(correlations))
2037 }
2038
2039 pub fn train(&mut self, training_data: &ReservoirTrainingData) -> Result<TrainingResult> {
2041 let start_time = std::time::Instant::now();
2042
2043 let mut all_features = Vec::new();
2044 let mut all_targets = Vec::new();
2045
2046 for i in 0..self.config.washout_period.min(training_data.inputs.len()) {
2048 let _ = self.process_input(&training_data.inputs[i])?;
2049 }
2050
2051 for i in self.config.washout_period..training_data.inputs.len() {
2053 let features = self.process_input(&training_data.inputs[i])?;
2054 all_features.push(features);
2055
2056 if i < training_data.targets.len() {
2057 all_targets.push(training_data.targets[i].clone());
2058 }
2059 }
2060
2061 self.train_with_learning_algorithm(&all_features, &all_targets)?;
2063
2064 if self.config.memory_config.enable_capacity_estimation {
2066 self.analyze_memory_capacity(&all_features)?;
2067 }
2068
2069 let (training_error, test_error) =
2071 self.evaluate_performance(&all_features, &all_targets)?;
2072
2073 let training_time = start_time.elapsed().as_secs_f64() * 1000.0;
2074
2075 self.metrics.training_examples += all_features.len();
2077 self.metrics.generalization_error = test_error;
2078 self.metrics.memory_capacity = self.reservoir_state.memory_metrics.total_capacity;
2079
2080 Ok(TrainingResult {
2081 training_error,
2082 test_error,
2083 training_time_ms: training_time,
2084 num_examples: all_features.len(),
2085 echo_state_property: self.estimate_echo_state_property()?,
2086 memory_capacity: self.reservoir_state.memory_metrics.total_capacity,
2087 nonlinear_capacity: self.reservoir_state.memory_metrics.nonlinear_capacity,
2088 processing_capacity: self.reservoir_state.memory_metrics.processing_capacity,
2089 })
2090 }
2091
2092 fn train_with_learning_algorithm(
2094 &mut self,
2095 features: &[Array1<f64>],
2096 targets: &[Array1<f64>],
2097 ) -> Result<()> {
2098 match self.config.learning_config.algorithm {
2099 LearningAlgorithm::Ridge => {
2100 self.train_ridge_regression(features, targets)?;
2101 }
2102 LearningAlgorithm::LASSO => {
2103 self.train_lasso_regression(features, targets)?;
2104 }
2105 LearningAlgorithm::ElasticNet => {
2106 self.train_elastic_net(features, targets)?;
2107 }
2108 LearningAlgorithm::RecursiveLeastSquares => {
2109 self.train_recursive_least_squares(features, targets)?;
2110 }
2111 LearningAlgorithm::KalmanFilter => {
2112 self.train_kalman_filter(features, targets)?;
2113 }
2114 _ => {
2115 self.train_ridge_regression(features, targets)?;
2117 }
2118 }
2119
2120 Ok(())
2121 }
2122
2123 fn train_ridge_regression(
2125 &mut self,
2126 features: &[Array1<f64>],
2127 targets: &[Array1<f64>],
2128 ) -> Result<()> {
2129 if features.is_empty() || targets.is_empty() {
2130 return Ok(());
2131 }
2132
2133 let n_samples = features.len().min(targets.len());
2134 let n_features = features[0].len();
2135 let n_outputs = targets[0].len().min(self.output_weights.nrows());
2136
2137 let mut feature_matrix = Array2::zeros((n_samples, n_features));
2139 for (i, feature_vec) in features.iter().enumerate().take(n_samples) {
2140 for (j, &val) in feature_vec.iter().enumerate().take(n_features) {
2141 feature_matrix[[i, j]] = val;
2142 }
2143 }
2144
2145 let mut target_matrix = Array2::zeros((n_samples, n_outputs));
2147 for (i, target_vec) in targets.iter().enumerate().take(n_samples) {
2148 for (j, &val) in target_vec.iter().enumerate().take(n_outputs) {
2149 target_matrix[[i, j]] = val;
2150 }
2151 }
2152
2153 let lambda = self.config.learning_config.regularization;
2155
2156 let xtx = feature_matrix.t().dot(&feature_matrix);
2158
2159 let mut xtx_reg = xtx;
2161 for i in 0..xtx_reg.nrows().min(xtx_reg.ncols()) {
2162 xtx_reg[[i, i]] += lambda;
2163 }
2164
2165 let xty = feature_matrix.t().dot(&target_matrix);
2167
2168 self.solve_linear_system(&xtx_reg, &xty)?;
2170
2171 Ok(())
2172 }
2173
2174 fn train_lasso_regression(
2176 &mut self,
2177 features: &[Array1<f64>],
2178 targets: &[Array1<f64>],
2179 ) -> Result<()> {
2180 let lambda = self.config.learning_config.regularization;
2182 let max_iter = 100;
2183
2184 for _ in 0..max_iter {
2185 for j in 0..self.output_weights.ncols().min(features[0].len()) {
2187 for i in 0..self.output_weights.nrows().min(targets[0].len()) {
2188 let old_weight = self.output_weights[[i, j]];
2190 let gradient = self.compute_lasso_gradient(features, targets, i, j)?;
2191 let update = old_weight - 0.01 * gradient;
2192
2193 self.output_weights[[i, j]] = if update > lambda {
2195 update - lambda
2196 } else if update < -lambda {
2197 update + lambda
2198 } else {
2199 0.0
2200 };
2201 }
2202 }
2203 }
2204
2205 Ok(())
2206 }
2207
2208 fn compute_lasso_gradient(
2210 &self,
2211 features: &[Array1<f64>],
2212 targets: &[Array1<f64>],
2213 output_idx: usize,
2214 feature_idx: usize,
2215 ) -> Result<f64> {
2216 let mut gradient = 0.0;
2217
2218 for (feature_vec, target_vec) in features.iter().zip(targets.iter()) {
2219 if feature_idx < feature_vec.len() && output_idx < target_vec.len() {
2220 let prediction = self.predict_single_output(feature_vec, output_idx)?;
2221 let error = prediction - target_vec[output_idx];
2222 gradient += error * feature_vec[feature_idx];
2223 }
2224 }
2225
2226 gradient /= features.len() as f64;
2227 Ok(gradient)
2228 }
2229
2230 fn train_elastic_net(
2232 &mut self,
2233 features: &[Array1<f64>],
2234 targets: &[Array1<f64>],
2235 ) -> Result<()> {
2236 let l1_ratio = self.config.learning_config.l1_ratio;
2237
2238 if l1_ratio > 0.5 {
2240 self.train_lasso_regression(features, targets)?;
2242 } else {
2243 self.train_ridge_regression(features, targets)?;
2245 }
2246
2247 Ok(())
2248 }
2249
2250 fn train_recursive_least_squares(
2252 &mut self,
2253 features: &[Array1<f64>],
2254 targets: &[Array1<f64>],
2255 ) -> Result<()> {
2256 let forgetting_factor = self.config.learning_config.forgetting_factor;
2257 let n_features = features[0].len().min(self.output_weights.ncols());
2258 let n_outputs = targets[0].len().min(self.output_weights.nrows());
2259
2260 let mut p_matrix = Array2::eye(n_features) * 1000.0; for (feature_vec, target_vec) in features.iter().zip(targets.iter()) {
2265 let x = feature_vec.slice(s![..n_features]).to_owned();
2266 let y = target_vec.slice(s![..n_outputs]).to_owned();
2267
2268 let px = p_matrix.dot(&x);
2270 let denominator = forgetting_factor + x.dot(&px);
2271
2272 if denominator > 1e-15 {
2273 let k = &px / denominator;
2274
2275 for output_idx in 0..n_outputs {
2277 let prediction = self.predict_single_output(feature_vec, output_idx)?;
2278 let error = y[output_idx] - prediction;
2279
2280 for feature_idx in 0..n_features {
2282 self.output_weights[[output_idx, feature_idx]] += k[feature_idx] * error;
2283 }
2284 }
2285
2286 let outer_product = k
2288 .view()
2289 .insert_axis(Axis(1))
2290 .dot(&x.view().insert_axis(Axis(0)));
2291 p_matrix = (p_matrix - outer_product) / forgetting_factor;
2292 }
2293 }
2294
2295 Ok(())
2296 }
2297
2298 fn train_kalman_filter(
2300 &mut self,
2301 features: &[Array1<f64>],
2302 targets: &[Array1<f64>],
2303 ) -> Result<()> {
2304 let process_noise = self.config.learning_config.process_noise;
2305 let measurement_noise = self.config.learning_config.measurement_noise;
2306
2307 let n_features = features[0].len().min(self.output_weights.ncols());
2308 let n_outputs = targets[0].len().min(self.output_weights.nrows());
2309
2310 let mut state_covariance = Array2::eye(n_features) * 1.0;
2312 let process_noise_matrix: Array2<f64> = Array2::eye(n_features) * process_noise;
2313 let measurement_noise_scalar = measurement_noise;
2314
2315 for (feature_vec, target_vec) in features.iter().zip(targets.iter()) {
2317 let x = feature_vec.slice(s![..n_features]).to_owned();
2318 let y = target_vec.slice(s![..n_outputs]).to_owned();
2319
2320 let predicted_covariance = &state_covariance + &process_noise_matrix;
2322
2323 for output_idx in 0..n_outputs {
2325 let measurement = y[output_idx];
2326 let prediction = self.predict_single_output(feature_vec, output_idx)?;
2327
2328 let s = x.dot(&predicted_covariance.dot(&x)) + measurement_noise_scalar;
2330 if s > 1e-15 {
2331 let k = predicted_covariance.dot(&x) / s;
2332
2333 let innovation = measurement - prediction;
2335 for feature_idx in 0..n_features {
2336 self.output_weights[[output_idx, feature_idx]] +=
2337 k[feature_idx] * innovation;
2338 }
2339
2340 let kh = k
2342 .view()
2343 .insert_axis(Axis(1))
2344 .dot(&x.view().insert_axis(Axis(0)));
2345 state_covariance = &predicted_covariance - &kh.dot(&predicted_covariance);
2346 }
2347 }
2348 }
2349
2350 Ok(())
2351 }
2352
2353 fn predict_single_output(&self, features: &Array1<f64>, output_idx: usize) -> Result<f64> {
2355 let feature_size = features.len().min(self.output_weights.ncols());
2356 let mut output = 0.0;
2357
2358 for j in 0..feature_size {
2359 output += self.output_weights[[output_idx, j]] * features[j];
2360 }
2361
2362 Ok(output)
2363 }
2364
2365 fn analyze_memory_capacity(&mut self, features: &[Array1<f64>]) -> Result<()> {
2367 let linear_capacity = self.estimate_linear_memory_capacity(features)?;
2369 self.reservoir_state.memory_metrics.linear_capacity = linear_capacity;
2370
2371 if self.config.memory_config.enable_nonlinear {
2373 let nonlinear_capacity = self.estimate_nonlinear_memory_capacity(features)?;
2374 self.reservoir_state.memory_metrics.nonlinear_capacity = nonlinear_capacity;
2375 }
2376
2377 self.reservoir_state.memory_metrics.total_capacity =
2379 self.reservoir_state.memory_metrics.linear_capacity
2380 + self.reservoir_state.memory_metrics.nonlinear_capacity;
2381
2382 if self.config.memory_config.enable_ipc {
2384 let ipc = self.estimate_information_processing_capacity(features)?;
2385 self.reservoir_state.memory_metrics.processing_capacity = ipc;
2386 }
2387
2388 self.memory_analyzer.capacity_estimates.insert(
2390 "linear".to_string(),
2391 self.reservoir_state.memory_metrics.linear_capacity,
2392 );
2393 self.memory_analyzer.capacity_estimates.insert(
2394 "nonlinear".to_string(),
2395 self.reservoir_state.memory_metrics.nonlinear_capacity,
2396 );
2397 self.memory_analyzer.capacity_estimates.insert(
2398 "total".to_string(),
2399 self.reservoir_state.memory_metrics.total_capacity,
2400 );
2401
2402 Ok(())
2403 }
2404
2405 fn estimate_linear_memory_capacity(&self, features: &[Array1<f64>]) -> Result<f64> {
2407 let mut capacity = 0.0;
2409
2410 for lag in 1..=20 {
2411 if lag < features.len() {
2412 let mut correlation = 0.0;
2413 let mut count = 0;
2414
2415 for i in lag..features.len() {
2416 for j in 0..features[i].len().min(features[i - lag].len()) {
2417 correlation += features[i][j] * features[i - lag][j];
2418 count += 1;
2419 }
2420 }
2421
2422 if count > 0 {
2423 correlation /= count as f64;
2424 capacity += correlation.abs();
2425 }
2426 }
2427 }
2428
2429 Ok(capacity)
2430 }
2431
2432 fn estimate_nonlinear_memory_capacity(&self, features: &[Array1<f64>]) -> Result<f64> {
2434 let mut nonlinear_capacity = 0.0;
2435
2436 for order in &self.config.memory_config.nonlinearity_orders {
2438 let capacity_order = self.test_nonlinear_order(*order, features)?;
2439 nonlinear_capacity += capacity_order;
2440 }
2441
2442 Ok(nonlinear_capacity)
2443 }
2444
2445 fn test_nonlinear_order(&self, order: usize, features: &[Array1<f64>]) -> Result<f64> {
2447 let mut capacity = 0.0;
2448
2449 for lag in 1..=10 {
2451 if lag < features.len() {
2452 let mut correlation = 0.0;
2453 let mut count = 0;
2454
2455 for i in lag..features.len() {
2456 for j in 0..features[i].len().min(features[i - lag].len()) {
2457 let current = features[i][j];
2459 let past = features[i - lag][j];
2460 let nonlinear_target = past.powi(order as i32);
2461
2462 correlation += current * nonlinear_target;
2463 count += 1;
2464 }
2465 }
2466
2467 if count > 0 {
2468 correlation /= count as f64;
2469 capacity += correlation.abs() / order as f64; }
2471 }
2472 }
2473
2474 Ok(capacity)
2475 }
2476
2477 fn estimate_information_processing_capacity(&self, features: &[Array1<f64>]) -> Result<f64> {
2479 let mut ipc = 0.0;
2480
2481 for ipc_function in &self.config.memory_config.ipc_functions {
2482 let capacity_func = self.test_ipc_function(*ipc_function, features)?;
2483 ipc += capacity_func;
2484 }
2485
2486 Ok(ipc)
2487 }
2488
2489 fn test_ipc_function(&self, function: IPCFunction, features: &[Array1<f64>]) -> Result<f64> {
2491 let mut capacity = 0.0;
2492
2493 for lag in 1..=10 {
2494 if lag < features.len() {
2495 let mut correlation = 0.0;
2496 let mut count = 0;
2497
2498 for i in lag..features.len() {
2499 for j in 0..features[i].len().min(features[i - lag].len()) {
2500 let current = features[i][j];
2501 let past = features[i - lag][j];
2502
2503 let target = match function {
2504 IPCFunction::Linear => past,
2505 IPCFunction::Quadratic => past * past,
2506 IPCFunction::Cubic => past * past * past,
2507 IPCFunction::Sine => past.sin(),
2508 IPCFunction::Product => {
2509 if j > 0 && j - 1 < features[i - lag].len() {
2510 past * features[i - lag][j - 1]
2511 } else {
2512 past
2513 }
2514 }
2515 IPCFunction::XOR => {
2516 if past > 0.0 {
2517 1.0
2518 } else {
2519 -1.0
2520 }
2521 }
2522 };
2523
2524 correlation += current * target;
2525 count += 1;
2526 }
2527 }
2528
2529 if count > 0 {
2530 correlation /= count as f64;
2531 capacity += correlation.abs();
2532 }
2533 }
2534 }
2535
2536 Ok(capacity)
2537 }
2538
2539 fn solve_linear_system(&mut self, a: &Array2<f64>, b: &Array2<f64>) -> Result<()> {
2541 let min_dim = a.nrows().min(a.ncols()).min(b.nrows());
2542
2543 for i in 0..min_dim.min(self.output_weights.nrows()) {
2544 for j in 0..b.ncols().min(self.output_weights.ncols()) {
2545 if a[[i, i]].abs() > 1e-15 {
2546 self.output_weights[[i, j]] = b[[i, j]] / a[[i, i]];
2547 }
2548 }
2549 }
2550
2551 Ok(())
2552 }
2553
2554 fn evaluate_performance(
2556 &self,
2557 features: &[Array1<f64>],
2558 targets: &[Array1<f64>],
2559 ) -> Result<(f64, f64)> {
2560 if features.is_empty() || targets.is_empty() {
2561 return Ok((0.0, 0.0));
2562 }
2563
2564 let mut total_error = 0.0;
2565 let n_samples = features.len().min(targets.len());
2566
2567 for i in 0..n_samples {
2568 let prediction = self.predict_output(&features[i])?;
2569 let error = self.calculate_prediction_error(&prediction, &targets[i]);
2570 total_error += error;
2571 }
2572
2573 let training_error = total_error / n_samples as f64;
2574
2575 let test_error = training_error;
2577
2578 Ok((training_error, test_error))
2579 }
2580
2581 fn predict_output(&self, features: &Array1<f64>) -> Result<Array1<f64>> {
2583 let feature_size = features.len().min(self.output_weights.ncols());
2584 let output_size = self.output_weights.nrows();
2585
2586 let mut output = Array1::zeros(output_size);
2587
2588 for i in 0..output_size {
2589 for j in 0..feature_size {
2590 output[i] += self.output_weights[[i, j]] * features[j];
2591 }
2592 }
2593
2594 Ok(output)
2595 }
2596
2597 fn calculate_prediction_error(&self, prediction: &Array1<f64>, target: &Array1<f64>) -> f64 {
2599 let min_len = prediction.len().min(target.len());
2600 let mut error = 0.0;
2601
2602 for i in 0..min_len {
2603 let diff = prediction[i] - target[i];
2604 error += diff * diff;
2605 }
2606
2607 (error / min_len as f64).sqrt() }
2609
2610 fn estimate_echo_state_property(&self) -> Result<f64> {
2612 let coupling = self.config.coupling_strength;
2613 let estimated_spectral_radius = coupling.tanh(); Ok(if estimated_spectral_radius < 1.0 {
2617 1.0
2618 } else {
2619 1.0 / estimated_spectral_radius
2620 })
2621 }
2622
2623 fn update_processing_time(&mut self, time_ms: f64) {
2625 let count = self.metrics.training_examples as f64;
2626 self.metrics.avg_processing_time_ms =
2627 (self.metrics.avg_processing_time_ms * count + time_ms) / (count + 1.0);
2628 }
2629
2630 pub fn get_metrics(&self) -> &ReservoirMetrics {
2632 &self.metrics
2633 }
2634
2635 pub fn get_memory_analysis(&self) -> &MemoryAnalyzer {
2637 &self.memory_analyzer
2638 }
2639
2640 pub fn reset(&mut self) -> Result<()> {
2642 self.reservoir_state =
2643 QuantumReservoirState::new(self.config.num_qubits, self.config.memory_capacity);
2644 self.metrics = ReservoirMetrics::default();
2645 self.training_history.clear();
2646 Ok(())
2647 }
2648}
2649
2650impl TimeSeriesPredictor {
2651 pub fn new(config: &TimeSeriesConfig) -> Self {
2653 Self {
2654 arima_params: ARIMAParams {
2655 ar_coeffs: Array1::zeros(config.ar_order),
2656 ma_coeffs: Array1::zeros(config.ma_order),
2657 diff_order: config.diff_order,
2658 residuals: VecDeque::with_capacity(config.ma_order),
2659 variance: 1.0,
2660 },
2661 nar_state: NARState {
2662 order: config.nar_order,
2663 coeffs: Array2::zeros((config.nar_order, config.nar_order)),
2664 history: VecDeque::with_capacity(config.nar_order),
2665 activation: ActivationFunction::Tanh,
2666 },
2667 kernel_weights: Array1::from_vec(config.kernel_params.clone()),
2668 trend_model: TrendModel {
2669 params: vec![0.0, 0.0], strength: 0.0,
2671 direction: 0.0,
2672 },
2673 }
2674 }
2675}
2676
2677impl MemoryAnalyzer {
2678 pub fn new(config: MemoryAnalysisConfig) -> Self {
2680 Self {
2681 config,
2682 capacity_estimates: HashMap::new(),
2683 nonlinearity_measures: HashMap::new(),
2684 temporal_correlations: Array2::zeros((0, 0)),
2685 ipc_metrics: HashMap::new(),
2686 }
2687 }
2688}
2689
2690#[derive(Debug, Clone, Serialize, Deserialize)]
2692pub struct TrainingResult {
2693 pub training_error: f64,
2695 pub test_error: f64,
2697 pub training_time_ms: f64,
2699 pub num_examples: usize,
2701 pub echo_state_property: f64,
2703 pub memory_capacity: f64,
2705 pub nonlinear_capacity: f64,
2707 pub processing_capacity: f64,
2709}
2710
2711pub fn benchmark_enhanced_quantum_reservoir_computing() -> Result<HashMap<String, f64>> {
2713 let mut results = HashMap::new();
2714
2715 let configs = vec![
2717 QuantumReservoirConfig {
2718 num_qubits: 6,
2719 architecture: QuantumReservoirArchitecture::RandomCircuit,
2720 learning_config: AdvancedLearningConfig {
2721 algorithm: LearningAlgorithm::Ridge,
2722 ..Default::default()
2723 },
2724 ..Default::default()
2725 },
2726 QuantumReservoirConfig {
2727 num_qubits: 8,
2728 architecture: QuantumReservoirArchitecture::ScaleFree,
2729 learning_config: AdvancedLearningConfig {
2730 algorithm: LearningAlgorithm::LASSO,
2731 ..Default::default()
2732 },
2733 ..Default::default()
2734 },
2735 QuantumReservoirConfig {
2736 num_qubits: 6,
2737 architecture: QuantumReservoirArchitecture::HierarchicalModular,
2738 learning_config: AdvancedLearningConfig {
2739 algorithm: LearningAlgorithm::RecursiveLeastSquares,
2740 ..Default::default()
2741 },
2742 memory_config: MemoryAnalysisConfig {
2743 enable_capacity_estimation: true,
2744 enable_nonlinear: true,
2745 ..Default::default()
2746 },
2747 ..Default::default()
2748 },
2749 QuantumReservoirConfig {
2750 num_qubits: 8,
2751 architecture: QuantumReservoirArchitecture::Grid,
2752 dynamics: ReservoirDynamics::Floquet,
2753 input_encoding: InputEncoding::Angle,
2754 output_measurement: OutputMeasurement::TemporalCorrelations,
2755 ..Default::default()
2756 },
2757 ];
2758
2759 for (i, config) in configs.into_iter().enumerate() {
2760 let start = std::time::Instant::now();
2761
2762 let mut qrc = QuantumReservoirComputerEnhanced::new(config)?;
2763
2764 let training_data = ReservoirTrainingData::new(
2766 (0..200)
2767 .map(|i| {
2768 Array1::from_vec(vec![
2769 (i as f64 * 0.1).sin(),
2770 (i as f64 * 0.1).cos(),
2771 (i as f64 * 0.05).sin() * (i as f64 * 0.2).cos(),
2772 ])
2773 })
2774 .collect(),
2775 (0..200)
2776 .map(|i| Array1::from_vec(vec![(i as f64 * 0.1 + 1.0).sin()]))
2777 .collect(),
2778 (0..200).map(|i| i as f64 * 0.1).collect(),
2779 );
2780
2781 let training_result = qrc.train(&training_data)?;
2783
2784 let time = start.elapsed().as_secs_f64() * 1000.0;
2785 results.insert(format!("enhanced_config_{}", i), time);
2786
2787 let metrics = qrc.get_metrics();
2789 results.insert(
2790 format!("enhanced_config_{}_accuracy", i),
2791 metrics.prediction_accuracy,
2792 );
2793 results.insert(
2794 format!("enhanced_config_{}_memory_capacity", i),
2795 training_result.memory_capacity,
2796 );
2797 results.insert(
2798 format!("enhanced_config_{}_nonlinear_capacity", i),
2799 training_result.nonlinear_capacity,
2800 );
2801 results.insert(
2802 format!("enhanced_config_{}_processing_capacity", i),
2803 training_result.processing_capacity,
2804 );
2805 results.insert(
2806 format!("enhanced_config_{}_quantum_advantage", i),
2807 metrics.quantum_advantage,
2808 );
2809 results.insert(
2810 format!("enhanced_config_{}_efficiency", i),
2811 metrics.reservoir_efficiency,
2812 );
2813
2814 let memory_analyzer = qrc.get_memory_analysis();
2816 if let Some(&linear_capacity) = memory_analyzer.capacity_estimates.get("linear") {
2817 results.insert(
2818 format!("enhanced_config_{}_linear_memory", i),
2819 linear_capacity,
2820 );
2821 }
2822 if let Some(&total_capacity) = memory_analyzer.capacity_estimates.get("total") {
2823 results.insert(
2824 format!("enhanced_config_{}_total_memory", i),
2825 total_capacity,
2826 );
2827 }
2828 }
2829
2830 Ok(results)
2831}
2832
2833#[cfg(test)]
2834mod tests {
2835 use super::*;
2836 use approx::assert_abs_diff_eq;
2837
2838 #[test]
2839 fn test_enhanced_quantum_reservoir_creation() {
2840 let config = QuantumReservoirConfig::default();
2841 let qrc = QuantumReservoirComputerEnhanced::new(config);
2842 assert!(qrc.is_ok());
2843 }
2844
2845 #[test]
2846 fn test_enhanced_reservoir_state_creation() {
2847 let state = QuantumReservoirState::new(3, 10);
2848 assert_eq!(state.state_vector.len(), 8); assert_eq!(state.state_history.capacity(), 10);
2850 assert_eq!(state.time_index, 0);
2851 assert!(state.memory_metrics.total_capacity >= 0.0);
2852 }
2853
2854 #[test]
2855 fn test_enhanced_input_processing() {
2856 let config = QuantumReservoirConfig {
2857 num_qubits: 3,
2858 evolution_steps: 2,
2859 ..Default::default()
2860 };
2861 let mut qrc = QuantumReservoirComputerEnhanced::new(config).unwrap();
2862
2863 let input = Array1::from_vec(vec![0.5, 0.3, 0.8]);
2864 let result = qrc.process_input(&input);
2865 assert!(result.is_ok());
2866
2867 let features = result.unwrap();
2868 assert!(!features.is_empty());
2869 }
2870
2871 #[test]
2872 fn test_enhanced_architectures() {
2873 let architectures = vec![
2874 QuantumReservoirArchitecture::RandomCircuit,
2875 QuantumReservoirArchitecture::SpinChain,
2876 QuantumReservoirArchitecture::ScaleFree,
2877 QuantumReservoirArchitecture::HierarchicalModular,
2878 QuantumReservoirArchitecture::Ring,
2879 QuantumReservoirArchitecture::Grid,
2880 ];
2881
2882 for arch in architectures {
2883 let config = QuantumReservoirConfig {
2884 num_qubits: 4,
2885 architecture: arch,
2886 evolution_steps: 2,
2887 ..Default::default()
2888 };
2889
2890 let qrc = QuantumReservoirComputerEnhanced::new(config);
2891 assert!(qrc.is_ok(), "Failed for architecture: {:?}", arch);
2892 }
2893 }
2894
2895 #[test]
2896 fn test_advanced_learning_algorithms() {
2897 let algorithms = vec![
2898 LearningAlgorithm::Ridge,
2899 LearningAlgorithm::LASSO,
2900 LearningAlgorithm::ElasticNet,
2901 LearningAlgorithm::RecursiveLeastSquares,
2902 ];
2903
2904 for algorithm in algorithms {
2905 let config = QuantumReservoirConfig {
2906 num_qubits: 3,
2907 learning_config: AdvancedLearningConfig {
2908 algorithm,
2909 ..Default::default()
2910 },
2911 ..Default::default()
2912 };
2913
2914 let qrc = QuantumReservoirComputerEnhanced::new(config);
2915 assert!(qrc.is_ok(), "Failed for algorithm: {:?}", algorithm);
2916 }
2917 }
2918
2919 #[test]
2920 fn test_enhanced_encoding_methods() {
2921 let encodings = vec![
2922 InputEncoding::Amplitude,
2923 InputEncoding::Phase,
2924 InputEncoding::BasisState,
2925 InputEncoding::Angle,
2926 ];
2927
2928 for encoding in encodings {
2929 let config = QuantumReservoirConfig {
2930 num_qubits: 3,
2931 input_encoding: encoding,
2932 ..Default::default()
2933 };
2934 let mut qrc = QuantumReservoirComputerEnhanced::new(config).unwrap();
2935
2936 let input = Array1::from_vec(vec![0.5, 0.3]);
2937 let result = qrc.encode_input(&input);
2938 assert!(result.is_ok(), "Failed for encoding: {:?}", encoding);
2939 }
2940 }
2941
2942 #[test]
2943 fn test_enhanced_measurement_strategies() {
2944 let measurements = vec![
2945 OutputMeasurement::PauliExpectation,
2946 OutputMeasurement::Probability,
2947 OutputMeasurement::Correlations,
2948 OutputMeasurement::Entanglement,
2949 OutputMeasurement::QuantumFisherInformation,
2950 OutputMeasurement::Variance,
2951 OutputMeasurement::QuantumCoherence,
2952 OutputMeasurement::Purity,
2953 OutputMeasurement::TemporalCorrelations,
2954 ];
2955
2956 for measurement in measurements {
2957 let config = QuantumReservoirConfig {
2958 num_qubits: 3,
2959 output_measurement: measurement,
2960 ..Default::default()
2961 };
2962
2963 let qrc = QuantumReservoirComputerEnhanced::new(config);
2964 assert!(qrc.is_ok(), "Failed for measurement: {:?}", measurement);
2965 }
2966 }
2967
2968 #[test]
2969 fn test_enhanced_reservoir_dynamics() {
2970 let dynamics = vec![
2971 ReservoirDynamics::Unitary,
2972 ReservoirDynamics::Open,
2973 ReservoirDynamics::NISQ,
2974 ReservoirDynamics::Floquet,
2975 ];
2976
2977 for dynamic in dynamics {
2978 let config = QuantumReservoirConfig {
2979 num_qubits: 3,
2980 dynamics: dynamic,
2981 evolution_steps: 1,
2982 ..Default::default()
2983 };
2984
2985 let mut qrc = QuantumReservoirComputerEnhanced::new(config).unwrap();
2986 let result = qrc.evolve_reservoir();
2987 assert!(result.is_ok(), "Failed for dynamics: {:?}", dynamic);
2988 }
2989 }
2990
2991 #[test]
2992 fn test_memory_analysis() {
2993 let config = QuantumReservoirConfig {
2994 num_qubits: 4,
2995 memory_config: MemoryAnalysisConfig {
2996 enable_capacity_estimation: true,
2997 enable_nonlinear: true,
2998 enable_ipc: true,
2999 ..Default::default()
3000 },
3001 ..Default::default()
3002 };
3003
3004 let qrc = QuantumReservoirComputerEnhanced::new(config).unwrap();
3005 let memory_analyzer = qrc.get_memory_analysis();
3006
3007 assert!(memory_analyzer.config.enable_capacity_estimation);
3008 assert!(memory_analyzer.config.enable_nonlinear);
3009 assert!(memory_analyzer.config.enable_ipc);
3010 }
3011
3012 #[test]
3013 fn test_enhanced_training_data() {
3014 let training_data = ReservoirTrainingData::new(
3015 vec![
3016 Array1::from_vec(vec![0.1, 0.2]),
3017 Array1::from_vec(vec![0.3, 0.4]),
3018 ],
3019 vec![Array1::from_vec(vec![0.5]), Array1::from_vec(vec![0.6])],
3020 vec![0.0, 1.0],
3021 )
3022 .with_features(vec![
3023 Array1::from_vec(vec![0.7, 0.8]),
3024 Array1::from_vec(vec![0.9, 1.0]),
3025 ])
3026 .with_labels(vec![0, 1])
3027 .with_weights(vec![1.0, 1.0]);
3028
3029 assert_eq!(training_data.len(), 2);
3030 assert!(training_data.features.is_some());
3031 assert!(training_data.labels.is_some());
3032 assert!(training_data.sample_weights.is_some());
3033
3034 let (train, test) = training_data.train_test_split(0.5);
3035 assert_eq!(train.len(), 1);
3036 assert_eq!(test.len(), 1);
3037 }
3038
3039 #[test]
3040 fn test_time_series_predictor() {
3041 let config = TimeSeriesConfig::default();
3042 let predictor = TimeSeriesPredictor::new(&config);
3043
3044 assert_eq!(predictor.arima_params.ar_coeffs.len(), config.ar_order);
3045 assert_eq!(predictor.arima_params.ma_coeffs.len(), config.ma_order);
3046 assert_eq!(predictor.nar_state.order, config.nar_order);
3047 }
3048
3049 #[test]
3050 fn test_enhanced_metrics_tracking() {
3051 let config = QuantumReservoirConfig::default();
3052 let qrc = QuantumReservoirComputerEnhanced::new(config).unwrap();
3053
3054 let metrics = qrc.get_metrics();
3055 assert_eq!(metrics.training_examples, 0);
3056 assert_eq!(metrics.prediction_accuracy, 0.0);
3057 assert_eq!(metrics.memory_capacity, 0.0);
3058 assert_eq!(metrics.nonlinear_memory_capacity, 0.0);
3059 assert_eq!(metrics.quantum_advantage, 0.0);
3060 }
3061
3062 #[test]
3063 fn test_enhanced_feature_sizes() {
3064 let measurements = vec![
3065 (OutputMeasurement::PauliExpectation, 24), (OutputMeasurement::QuantumFisherInformation, 8), (OutputMeasurement::Variance, 24), (OutputMeasurement::Purity, 1), ];
3070
3071 for (measurement, expected_size) in measurements {
3072 let config = QuantumReservoirConfig {
3073 num_qubits: 8,
3074 output_measurement: measurement,
3075 ..Default::default()
3076 };
3077
3078 let feature_size = QuantumReservoirComputerEnhanced::calculate_feature_size(&config);
3079 assert_eq!(
3080 feature_size, expected_size,
3081 "Feature size mismatch for {:?}",
3082 measurement
3083 );
3084 }
3085 }
3086}