1use scirs2_core::ndarray::{Array1, Array2};
28use scirs2_core::random::prelude::*;
29use scirs2_core::Complex64;
30use serde::{Deserialize, Serialize};
31use std::collections::{HashMap, VecDeque};
32
33use crate::circuit_interfaces::{
34 CircuitInterface, InterfaceCircuit, InterfaceGate, InterfaceGateType,
35};
36use crate::error::Result;
37use crate::hardware_aware_qml::AdaptationState;
38use crate::quantum_reservoir_computing_enhanced::MemoryMetrics;
39use crate::statevector::StateVectorSimulator;
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
43pub enum QuantumReservoirArchitecture {
44 RandomCircuit,
46 SpinChain,
48 TransverseFieldIsing,
50 SmallWorld,
52 FullyConnected,
54 ScaleFree,
56 HierarchicalModular,
58 AdaptiveTopology,
60 QuantumCellularAutomaton,
62 Ring,
64 Grid,
66 Tree,
68 Hypergraph,
70 TensorNetwork,
72 Custom,
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
78pub enum ReservoirDynamics {
79 Unitary,
81 Open,
83 NISQ,
85 Adiabatic,
87 Floquet,
89 QuantumWalk,
91 ContinuousTime,
93 DigitalQuantum,
95 Variational,
97 HamiltonianLearning,
99 ManyBodyLocalized,
101 QuantumChaotic,
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
107pub enum InputEncoding {
108 Amplitude,
110 Phase,
112 BasisState,
114 Coherent,
116 Squeezed,
118 Angle,
120 IQP,
122 DataReUploading,
124 QuantumFeatureMap,
126 VariationalEncoding,
128 TemporalEncoding,
130 FourierEncoding,
132 WaveletEncoding,
134 HaarRandom,
136 GraphEncoding,
138}
139
140#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
142pub enum OutputMeasurement {
143 PauliExpectation,
145 Probability,
147 Correlations,
149 Entanglement,
151 Fidelity,
153 QuantumFisherInformation,
155 Variance,
157 HigherOrderMoments,
159 SpectralProperties,
161 QuantumCoherence,
163 Purity,
165 QuantumMutualInformation,
167 ProcessTomography,
169 TemporalCorrelations,
171 NonLinearReadout,
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct QuantumReservoirConfig {
178 pub num_qubits: usize,
180 pub architecture: QuantumReservoirArchitecture,
182 pub dynamics: ReservoirDynamics,
184 pub input_encoding: InputEncoding,
186 pub output_measurement: OutputMeasurement,
188 pub learning_config: AdvancedLearningConfig,
190 pub time_series_config: TimeSeriesConfig,
192 pub topology_config: TopologyConfig,
194 pub adaptive_config: AdaptiveLearningConfig,
196 pub memory_config: MemoryAnalysisConfig,
198 pub hardware_config: HardwareOptimizationConfig,
200 pub benchmark_config: BenchmarkingConfig,
202 pub time_step: f64,
204 pub evolution_steps: usize,
206 pub coupling_strength: f64,
208 pub noise_level: f64,
210 pub memory_capacity: usize,
212 pub adaptive_learning: bool,
214 pub learning_rate: f64,
216 pub washout_period: usize,
218 pub random_seed: Option<u64>,
220 pub enable_qec: bool,
222 pub precision: f64,
224}
225
226impl Default for QuantumReservoirConfig {
227 fn default() -> Self {
228 Self {
229 num_qubits: 8,
230 architecture: QuantumReservoirArchitecture::RandomCircuit,
231 dynamics: ReservoirDynamics::Unitary,
232 input_encoding: InputEncoding::Amplitude,
233 output_measurement: OutputMeasurement::PauliExpectation,
234 learning_config: AdvancedLearningConfig::default(),
235 time_series_config: TimeSeriesConfig::default(),
236 topology_config: TopologyConfig::default(),
237 adaptive_config: AdaptiveLearningConfig::default(),
238 memory_config: MemoryAnalysisConfig::default(),
239 hardware_config: HardwareOptimizationConfig::default(),
240 benchmark_config: BenchmarkingConfig::default(),
241 time_step: 0.1,
242 evolution_steps: 10,
243 coupling_strength: 1.0,
244 noise_level: 0.01,
245 memory_capacity: 100,
246 adaptive_learning: true,
247 learning_rate: 0.01,
248 washout_period: 50,
249 random_seed: None,
250 enable_qec: false,
251 precision: 1e-8,
252 }
253 }
254}
255
256#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
258pub enum LearningAlgorithm {
259 Ridge,
261 LASSO,
263 ElasticNet,
265 RecursiveLeastSquares,
267 KalmanFilter,
269 ExtendedKalmanFilter,
271 NeuralNetwork,
273 SupportVectorRegression,
275 GaussianProcess,
277 RandomForest,
279 GradientBoosting,
281 OnlineGradientDescent,
283 Adam,
285 MetaLearning,
287}
288
289#[derive(Debug, Clone, Serialize, Deserialize)]
291pub struct AdvancedLearningConfig {
292 pub algorithm: LearningAlgorithm,
294 pub regularization: f64,
296 pub l1_ratio: f64,
298 pub forgetting_factor: f64,
300 pub process_noise: f64,
302 pub measurement_noise: f64,
304 pub nn_architecture: Vec<usize>,
306 pub nn_activation: ActivationFunction,
308 pub epochs: usize,
310 pub batch_size: usize,
312 pub early_stopping_patience: usize,
314 pub cv_folds: usize,
316 pub enable_ensemble: bool,
318 pub ensemble_size: usize,
320}
321
322impl Default for AdvancedLearningConfig {
323 fn default() -> Self {
324 Self {
325 algorithm: LearningAlgorithm::Ridge,
326 regularization: 1e-6,
327 l1_ratio: 0.5,
328 forgetting_factor: 0.99,
329 process_noise: 1e-4,
330 measurement_noise: 1e-3,
331 nn_architecture: vec![64, 32, 16],
332 nn_activation: ActivationFunction::ReLU,
333 epochs: 100,
334 batch_size: 32,
335 early_stopping_patience: 10,
336 cv_folds: 5,
337 enable_ensemble: false,
338 ensemble_size: 5,
339 }
340 }
341}
342
343#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
345pub enum ActivationFunction {
346 ReLU,
348 LeakyReLU,
350 ELU,
352 Sigmoid,
354 Tanh,
356 Swish,
358 GELU,
360 Linear,
362}
363
364#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct TimeSeriesConfig {
367 pub enable_arima: bool,
369 pub ar_order: usize,
371 pub ma_order: usize,
373 pub diff_order: usize,
375 pub enable_nar: bool,
377 pub nar_order: usize,
379 pub memory_kernel: MemoryKernel,
381 pub kernel_params: Vec<f64>,
383 pub enable_seasonal: bool,
385 pub seasonal_period: usize,
387 pub trend_method: TrendDetectionMethod,
389 pub enable_changepoint: bool,
391 pub anomaly_threshold: f64,
393}
394
395impl Default for TimeSeriesConfig {
396 fn default() -> Self {
397 Self {
398 enable_arima: true,
399 ar_order: 2,
400 ma_order: 1,
401 diff_order: 1,
402 enable_nar: true,
403 nar_order: 3,
404 memory_kernel: MemoryKernel::Exponential,
405 kernel_params: vec![0.9, 0.1],
406 enable_seasonal: false,
407 seasonal_period: 12,
408 trend_method: TrendDetectionMethod::LinearRegression,
409 enable_changepoint: false,
410 anomaly_threshold: 2.0,
411 }
412 }
413}
414
415#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
417pub enum MemoryKernel {
418 Exponential,
420 PowerLaw,
422 Gaussian,
424 Polynomial,
426 Rational,
428 Sinusoidal,
430 Custom,
432}
433
434#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
436pub enum TrendDetectionMethod {
437 LinearRegression,
439 Polynomial,
441 MovingAverage,
443 HodrickPrescott,
445 KalmanFilter,
447 Spectral,
449}
450
451#[derive(Debug, Clone, Serialize, Deserialize)]
453pub struct TopologyConfig {
454 pub connectivity_density: f64,
456 pub clustering_coefficient: f64,
458 pub rewiring_probability: f64,
460 pub power_law_exponent: f64,
462 pub hierarchical_levels: usize,
464 pub modularity_strength: f64,
466 pub num_modules: usize,
468 pub enable_adaptive: bool,
470 pub adaptation_rate: f64,
472 pub min_connection_strength: f64,
474 pub max_connection_strength: f64,
476 pub pruning_threshold: f64,
478}
479
480impl Default for TopologyConfig {
481 fn default() -> Self {
482 Self {
483 connectivity_density: 0.1,
484 clustering_coefficient: 0.3,
485 rewiring_probability: 0.1,
486 power_law_exponent: 2.5,
487 hierarchical_levels: 3,
488 modularity_strength: 0.5,
489 num_modules: 4,
490 enable_adaptive: false,
491 adaptation_rate: 0.01,
492 min_connection_strength: 0.1,
493 max_connection_strength: 2.0,
494 pruning_threshold: 0.05,
495 }
496 }
497}
498
499#[derive(Debug, Clone, Serialize, Deserialize)]
501pub struct AdaptiveLearningConfig {
502 pub enable_online: bool,
504 pub lr_schedule: LearningRateSchedule,
506 pub initial_lr: f64,
508 pub min_lr: f64,
510 pub lr_decay: f64,
512 pub adaptation_window: usize,
514 pub plasticity_type: PlasticityType,
516 pub enable_homeostasis: bool,
518 pub target_activity: f64,
520 pub regulation_rate: f64,
522 pub enable_meta_learning: bool,
524 pub meta_update_frequency: usize,
526}
527
528impl Default for AdaptiveLearningConfig {
529 fn default() -> Self {
530 Self {
531 enable_online: true,
532 lr_schedule: LearningRateSchedule::Exponential,
533 initial_lr: 0.01,
534 min_lr: 1e-6,
535 lr_decay: 0.95,
536 adaptation_window: 100,
537 plasticity_type: PlasticityType::Hebbian,
538 enable_homeostasis: false,
539 target_activity: 0.5,
540 regulation_rate: 0.001,
541 enable_meta_learning: false,
542 meta_update_frequency: 1000,
543 }
544 }
545}
546
547#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
549pub enum LearningRateSchedule {
550 Constant,
552 Exponential,
554 Step,
556 Polynomial,
558 CosineAnnealing,
560 WarmRestart,
562 Adaptive,
564}
565
566#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
568pub enum PlasticityType {
569 Hebbian,
571 AntiHebbian,
573 STDP,
575 Homeostatic,
577 Metaplasticity,
579 Quantum,
581}
582
583#[derive(Debug, Clone, Serialize, Deserialize)]
585pub struct MemoryAnalysisConfig {
586 pub enable_capacity_estimation: bool,
588 pub capacity_tasks: Vec<MemoryTask>,
590 pub enable_nonlinear: bool,
592 pub nonlinearity_orders: Vec<usize>,
594 pub enable_temporal_correlation: bool,
596 pub correlation_lags: Vec<usize>,
598 pub enable_ipc: bool,
600 pub ipc_functions: Vec<IPCFunction>,
602 pub enable_entropy: bool,
604 pub entropy_measures: Vec<EntropyMeasure>,
606}
607
608impl Default for MemoryAnalysisConfig {
609 fn default() -> Self {
610 Self {
611 enable_capacity_estimation: true,
612 capacity_tasks: vec![
613 MemoryTask::DelayLine,
614 MemoryTask::TemporalXOR,
615 MemoryTask::Parity,
616 ],
617 enable_nonlinear: true,
618 nonlinearity_orders: vec![2, 3, 4],
619 enable_temporal_correlation: true,
620 correlation_lags: (1..=20).collect(),
621 enable_ipc: true,
622 ipc_functions: vec![
623 IPCFunction::Linear,
624 IPCFunction::Quadratic,
625 IPCFunction::Cubic,
626 ],
627 enable_entropy: true,
628 entropy_measures: vec![
629 EntropyMeasure::Shannon,
630 EntropyMeasure::Renyi,
631 EntropyMeasure::VonNeumann,
632 ],
633 }
634 }
635}
636
637#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
639pub enum MemoryTask {
640 DelayLine,
642 TemporalXOR,
644 Parity,
646 SequencePrediction,
648 PatternCompletion,
650 TemporalIntegration,
652}
653
654#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
656pub enum IPCFunction {
657 Linear,
659 Quadratic,
661 Cubic,
663 Sine,
665 Product,
667 XOR,
669}
670
671#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
673pub enum EntropyMeasure {
674 Shannon,
676 Renyi,
678 VonNeumann,
680 Tsallis,
682 MutualInformation,
684 TransferEntropy,
686}
687
688#[derive(Debug, Clone, Serialize, Deserialize)]
690pub struct HardwareOptimizationConfig {
691 pub platform: QuantumPlatform,
693 pub enable_noise_aware: bool,
695 pub error_mitigation: Vec<ErrorMitigationMethod>,
697 pub enable_circuit_optimization: bool,
699 pub native_gate_set: Vec<NativeGate>,
701 pub connectivity_constraints: ConnectivityConstraints,
703 pub enable_calibration: bool,
705 pub calibration_frequency: usize,
707 pub enable_monitoring: bool,
709 pub enable_hardware_adaptation: bool,
711}
712
713impl Default for HardwareOptimizationConfig {
714 fn default() -> Self {
715 Self {
716 platform: QuantumPlatform::Simulator,
717 enable_noise_aware: true,
718 error_mitigation: vec![ErrorMitigationMethod::ZNE, ErrorMitigationMethod::PEC],
719 enable_circuit_optimization: true,
720 native_gate_set: vec![NativeGate::RZ, NativeGate::SX, NativeGate::CNOT],
721 connectivity_constraints: ConnectivityConstraints::AllToAll,
722 enable_calibration: false,
723 calibration_frequency: 100,
724 enable_monitoring: true,
725 enable_hardware_adaptation: false,
726 }
727 }
728}
729
730#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
732pub enum QuantumPlatform {
733 Simulator,
735 IBM,
737 Google,
739 IonQ,
741 Rigetti,
743 Quantinuum,
745 Xanadu,
747 AtomComputing,
749 GenericNISQ,
751}
752
753#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
755pub enum ErrorMitigationMethod {
756 ZNE,
758 PEC,
760 ReadoutCorrection,
762 SymmetryVerification,
764 VirtualDistillation,
766 MeasurementCorrection,
768}
769
770#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
772pub enum NativeGate {
773 RZ,
775 SX,
777 CNOT,
779 CZ,
781 ISwap,
783 MS,
785 U3,
787}
788
789#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
791pub enum ConnectivityConstraints {
792 AllToAll,
794 Linear,
796 Grid2D,
798 HeavyHex,
800 Custom,
802}
803
804#[derive(Debug, Clone, Serialize, Deserialize)]
806pub struct BenchmarkingConfig {
807 pub enable_comprehensive: bool,
809 pub datasets: Vec<BenchmarkDataset>,
811 pub metrics: Vec<PerformanceMetric>,
813 pub statistical_tests: Vec<StatisticalTest>,
815 pub comparison_methods: Vec<ComparisonMethod>,
817 pub num_runs: usize,
819 pub confidence_level: f64,
821 pub enable_cross_validation: bool,
823 pub cv_strategy: CrossValidationStrategy,
825}
826
827impl Default for BenchmarkingConfig {
828 fn default() -> Self {
829 Self {
830 enable_comprehensive: true,
831 datasets: vec![
832 BenchmarkDataset::MackeyGlass,
833 BenchmarkDataset::Lorenz,
834 BenchmarkDataset::Sine,
835 BenchmarkDataset::Chaotic,
836 ],
837 metrics: vec![
838 PerformanceMetric::MSE,
839 PerformanceMetric::MAE,
840 PerformanceMetric::R2,
841 PerformanceMetric::MemoryCapacity,
842 ],
843 statistical_tests: vec![
844 StatisticalTest::TTest,
845 StatisticalTest::WilcoxonRankSum,
846 StatisticalTest::KruskalWallis,
847 ],
848 comparison_methods: vec![
849 ComparisonMethod::ESN,
850 ComparisonMethod::LSTM,
851 ComparisonMethod::GRU,
852 ],
853 num_runs: 10,
854 confidence_level: 0.95,
855 enable_cross_validation: true,
856 cv_strategy: CrossValidationStrategy::KFold,
857 }
858 }
859}
860
861#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
863pub enum BenchmarkDataset {
864 MackeyGlass,
866 Lorenz,
868 Sine,
870 Chaotic,
872 Financial,
874 Weather,
876 EEG,
878 Speech,
880 SyntheticNonlinear,
882}
883
884#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
886pub enum PerformanceMetric {
887 MSE,
889 MAE,
891 RMSE,
893 R2,
895 MemoryCapacity,
897 ProcessingSpeed,
899 TrainingTime,
901 GeneralizationError,
903 IPC,
905 QuantumAdvantage,
907}
908
909#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
911pub enum StatisticalTest {
912 TTest,
914 WilcoxonRankSum,
916 KruskalWallis,
918 ANOVA,
920 Friedman,
922 Bootstrap,
924}
925
926#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
928pub enum ComparisonMethod {
929 ESN,
931 LSTM,
933 GRU,
935 Transformer,
937 SVM,
939 RandomForest,
941 LinearRegression,
943}
944
945#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
947pub enum CrossValidationStrategy {
948 KFold,
950 TimeSeriesSplit,
952 LeaveOneOut,
954 StratifiedKFold,
956 GroupKFold,
958}
959
960#[derive(Debug, Clone)]
962pub struct QuantumReservoirState {
963 pub state_vector: Array1<Complex64>,
965 pub state_history: VecDeque<Array1<Complex64>>,
967 pub observables: HashMap<String, f64>,
969 pub correlations: Array2<f64>,
971 pub higher_order_correlations: HashMap<String, f64>,
973 pub entanglement_measures: HashMap<String, f64>,
975 pub memory_metrics: MemoryMetrics,
977 pub time_index: usize,
979 pub last_update: f64,
981 pub activity_level: f64,
983 pub adaptation_state: AdaptationState,
985 pub performance_history: VecDeque<f64>,
987}
988
989impl QuantumReservoirState {
990 pub fn new(num_qubits: usize, memory_capacity: usize) -> Self {
992 let state_size = 1 << num_qubits;
993 let mut state_vector = Array1::zeros(state_size);
994 state_vector[0] = Complex64::new(1.0, 0.0); Self {
997 state_vector,
998 state_history: VecDeque::with_capacity(memory_capacity),
999 observables: HashMap::new(),
1000 correlations: Array2::zeros((num_qubits, num_qubits)),
1001 higher_order_correlations: HashMap::new(),
1002 entanglement_measures: HashMap::new(),
1003 memory_metrics: MemoryMetrics::default(),
1004 time_index: 0,
1005 last_update: 0.0,
1006 activity_level: 0.0,
1007 adaptation_state: AdaptationState::default(),
1008 performance_history: VecDeque::with_capacity(memory_capacity),
1009 }
1010 }
1011
1012 pub fn update_state(&mut self, new_state: Array1<Complex64>) {
1014 self.state_history.push_back(self.state_vector.clone());
1015 if self.state_history.len() > self.state_history.capacity() {
1016 self.state_history.pop_front();
1017 }
1018 self.state_vector = new_state;
1019 self.time_index += 1;
1020 }
1021}
1022
1023#[derive(Debug, Clone)]
1025pub struct ReservoirTrainingData {
1026 pub inputs: Vec<Array1<f64>>,
1028 pub targets: Vec<Array1<f64>>,
1030 pub timestamps: Vec<f64>,
1032}
1033
1034pub struct QuantumReservoirComputer {
1036 config: QuantumReservoirConfig,
1038 reservoir_state: QuantumReservoirState,
1040 reservoir_circuit: InterfaceCircuit,
1042 input_coupling_circuit: InterfaceCircuit,
1044 output_weights: Array2<f64>,
1046 simulator: StateVectorSimulator,
1048 circuit_interface: CircuitInterface,
1050 metrics: ReservoirMetrics,
1052 training_history: VecDeque<TrainingExample>,
1054}
1055
1056#[derive(Debug, Clone)]
1058pub struct TrainingExample {
1059 pub input: Array1<f64>,
1061 pub reservoir_state: Array1<f64>,
1063 pub target: Array1<f64>,
1065 pub error: f64,
1067}
1068
1069#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1071pub struct ReservoirMetrics {
1072 pub training_examples: usize,
1074 pub prediction_accuracy: f64,
1076 pub memory_capacity: f64,
1078 pub processing_capacity: f64,
1080 pub generalization_error: f64,
1082 pub echo_state_property: f64,
1084 pub avg_processing_time_ms: f64,
1086 pub quantum_resource_usage: f64,
1088}
1089
1090impl QuantumReservoirComputer {
1091 pub fn new(config: QuantumReservoirConfig) -> Result<Self> {
1093 let circuit_interface = CircuitInterface::new(Default::default())?;
1094 let simulator = StateVectorSimulator::new();
1095
1096 let reservoir_state = QuantumReservoirState::new(config.num_qubits, config.memory_capacity);
1097
1098 let reservoir_circuit = Self::generate_reservoir_circuit(&config)?;
1100
1101 let input_coupling_circuit = Self::generate_input_coupling_circuit(&config)?;
1103
1104 let output_size = match config.output_measurement {
1106 OutputMeasurement::PauliExpectation => config.num_qubits * 3, OutputMeasurement::Probability => 1 << config.num_qubits, OutputMeasurement::Correlations => config.num_qubits * config.num_qubits,
1109 OutputMeasurement::Entanglement => config.num_qubits,
1110 OutputMeasurement::Fidelity => 1,
1111 OutputMeasurement::QuantumFisherInformation => config.num_qubits,
1112 OutputMeasurement::Variance => config.num_qubits,
1113 OutputMeasurement::HigherOrderMoments => config.num_qubits * 4,
1114 OutputMeasurement::SpectralProperties => config.num_qubits,
1115 OutputMeasurement::QuantumCoherence => config.num_qubits,
1116 _ => config.num_qubits, };
1118
1119 let feature_size = Self::calculate_feature_size(&config);
1120 let mut output_weights = Array2::zeros((output_size, feature_size));
1121
1122 let scale = (2.0 / (output_size + feature_size) as f64).sqrt();
1124 for elem in &mut output_weights {
1125 *elem = (thread_rng().gen::<f64>() - 0.5) * 2.0 * scale;
1126 }
1127
1128 Ok(Self {
1129 config,
1130 reservoir_state,
1131 reservoir_circuit,
1132 input_coupling_circuit,
1133 output_weights,
1134 simulator,
1135 circuit_interface,
1136 metrics: ReservoirMetrics::default(),
1137 training_history: VecDeque::with_capacity(10000),
1138 })
1139 }
1140
1141 fn generate_reservoir_circuit(config: &QuantumReservoirConfig) -> Result<InterfaceCircuit> {
1143 let mut circuit = InterfaceCircuit::new(config.num_qubits, 0);
1144
1145 match config.architecture {
1146 QuantumReservoirArchitecture::RandomCircuit => {
1147 Self::generate_random_circuit(&mut circuit, config)?;
1148 }
1149 QuantumReservoirArchitecture::SpinChain => {
1150 Self::generate_spin_chain_circuit(&mut circuit, config)?;
1151 }
1152 QuantumReservoirArchitecture::TransverseFieldIsing => {
1153 Self::generate_tfim_circuit(&mut circuit, config)?;
1154 }
1155 QuantumReservoirArchitecture::SmallWorld => {
1156 Self::generate_small_world_circuit(&mut circuit, config)?;
1157 }
1158 QuantumReservoirArchitecture::FullyConnected => {
1159 Self::generate_fully_connected_circuit(&mut circuit, config)?;
1160 }
1161 QuantumReservoirArchitecture::Custom => {
1162 Self::generate_random_circuit(&mut circuit, config)?;
1164 }
1165 QuantumReservoirArchitecture::ScaleFree => {
1166 Self::generate_small_world_circuit(&mut circuit, config)?; }
1168 QuantumReservoirArchitecture::HierarchicalModular => {
1169 Self::generate_random_circuit(&mut circuit, config)?; }
1171 QuantumReservoirArchitecture::AdaptiveTopology => {
1172 Self::generate_random_circuit(&mut circuit, config)?; }
1174 QuantumReservoirArchitecture::QuantumCellularAutomaton => {
1175 Self::generate_spin_chain_circuit(&mut circuit, config)?; }
1177 QuantumReservoirArchitecture::Ring => {
1178 Self::generate_spin_chain_circuit(&mut circuit, config)?; }
1180 _ => {
1181 Self::generate_random_circuit(&mut circuit, config)?;
1183 }
1184 }
1185
1186 Ok(circuit)
1187 }
1188
1189 fn generate_random_circuit(
1191 circuit: &mut InterfaceCircuit,
1192 config: &QuantumReservoirConfig,
1193 ) -> Result<()> {
1194 let depth = config.evolution_steps;
1195
1196 for _ in 0..depth {
1197 for qubit in 0..config.num_qubits {
1199 let angle = thread_rng().gen::<f64>() * 2.0 * std::f64::consts::PI;
1200 let gate_type = match thread_rng().gen_range(0..3) {
1201 0 => InterfaceGateType::RX(angle),
1202 1 => InterfaceGateType::RY(angle),
1203 _ => InterfaceGateType::RZ(angle),
1204 };
1205 circuit.add_gate(InterfaceGate::new(gate_type, vec![qubit]));
1206 }
1207
1208 for _ in 0..(config.num_qubits / 2) {
1210 let qubit1 = thread_rng().gen_range(0..config.num_qubits);
1211 let qubit2 = thread_rng().gen_range(0..config.num_qubits);
1212 if qubit1 != qubit2 {
1213 circuit.add_gate(InterfaceGate::new(
1214 InterfaceGateType::CNOT,
1215 vec![qubit1, qubit2],
1216 ));
1217 }
1218 }
1219 }
1220
1221 Ok(())
1222 }
1223
1224 fn generate_spin_chain_circuit(
1226 circuit: &mut InterfaceCircuit,
1227 config: &QuantumReservoirConfig,
1228 ) -> Result<()> {
1229 let coupling = config.coupling_strength;
1230
1231 for _ in 0..config.evolution_steps {
1232 for i in 0..config.num_qubits - 1 {
1234 circuit.add_gate(InterfaceGate::new(
1236 InterfaceGateType::RZ(coupling * config.time_step),
1237 vec![i],
1238 ));
1239 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1240 circuit.add_gate(InterfaceGate::new(
1241 InterfaceGateType::RZ(coupling * config.time_step),
1242 vec![i + 1],
1243 ));
1244 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1245 }
1246 }
1247
1248 Ok(())
1249 }
1250
1251 fn generate_tfim_circuit(
1253 circuit: &mut InterfaceCircuit,
1254 config: &QuantumReservoirConfig,
1255 ) -> Result<()> {
1256 let coupling = config.coupling_strength;
1257 let field = coupling * 0.5; for _ in 0..config.evolution_steps {
1260 for qubit in 0..config.num_qubits {
1262 circuit.add_gate(InterfaceGate::new(
1263 InterfaceGateType::RX(field * config.time_step),
1264 vec![qubit],
1265 ));
1266 }
1267
1268 for i in 0..config.num_qubits - 1 {
1270 circuit.add_gate(InterfaceGate::new(
1271 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1272 vec![i],
1273 ));
1274 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1275 circuit.add_gate(InterfaceGate::new(
1276 InterfaceGateType::RZ(coupling * config.time_step),
1277 vec![i + 1],
1278 ));
1279 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1280 circuit.add_gate(InterfaceGate::new(
1281 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1282 vec![i],
1283 ));
1284 }
1285 }
1286
1287 Ok(())
1288 }
1289
1290 fn generate_small_world_circuit(
1292 circuit: &mut InterfaceCircuit,
1293 config: &QuantumReservoirConfig,
1294 ) -> Result<()> {
1295 let coupling = config.coupling_strength;
1296 let rewiring_prob = 0.1; for _ in 0..config.evolution_steps {
1299 for i in 0..config.num_qubits {
1301 let next = (i + 1) % config.num_qubits;
1302
1303 let target = if thread_rng().gen::<f64>() < rewiring_prob {
1305 thread_rng().gen_range(0..config.num_qubits)
1306 } else {
1307 next
1308 };
1309
1310 if target != i {
1311 circuit.add_gate(InterfaceGate::new(
1312 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1313 vec![i],
1314 ));
1315 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, target]));
1316 circuit.add_gate(InterfaceGate::new(
1317 InterfaceGateType::RZ(coupling * config.time_step),
1318 vec![target],
1319 ));
1320 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, target]));
1321 circuit.add_gate(InterfaceGate::new(
1322 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1323 vec![i],
1324 ));
1325 }
1326 }
1327 }
1328
1329 Ok(())
1330 }
1331
1332 fn generate_fully_connected_circuit(
1334 circuit: &mut InterfaceCircuit,
1335 config: &QuantumReservoirConfig,
1336 ) -> Result<()> {
1337 let coupling = config.coupling_strength / config.num_qubits as f64; for _ in 0..config.evolution_steps {
1340 for i in 0..config.num_qubits {
1342 for j in i + 1..config.num_qubits {
1343 circuit.add_gate(InterfaceGate::new(
1344 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1345 vec![i],
1346 ));
1347 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1348 circuit.add_gate(InterfaceGate::new(
1349 InterfaceGateType::RZ(coupling * config.time_step),
1350 vec![j],
1351 ));
1352 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1353 circuit.add_gate(InterfaceGate::new(
1354 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1355 vec![i],
1356 ));
1357 }
1358 }
1359 }
1360
1361 Ok(())
1362 }
1363
1364 fn generate_input_coupling_circuit(
1366 config: &QuantumReservoirConfig,
1367 ) -> Result<InterfaceCircuit> {
1368 let mut circuit = InterfaceCircuit::new(config.num_qubits, 0);
1369
1370 match config.input_encoding {
1371 InputEncoding::Amplitude => {
1372 for qubit in 0..config.num_qubits {
1374 circuit.add_gate(InterfaceGate::new(
1375 InterfaceGateType::RY(0.0), vec![qubit],
1377 ));
1378 }
1379 }
1380 InputEncoding::Phase => {
1381 for qubit in 0..config.num_qubits {
1383 circuit.add_gate(InterfaceGate::new(
1384 InterfaceGateType::RZ(0.0), vec![qubit],
1386 ));
1387 }
1388 }
1389 InputEncoding::BasisState => {
1390 for qubit in 0..config.num_qubits {
1392 circuit.add_gate(InterfaceGate::new(InterfaceGateType::X, vec![qubit]));
1394 }
1395 }
1396 _ => {
1397 for qubit in 0..config.num_qubits {
1399 circuit.add_gate(InterfaceGate::new(InterfaceGateType::RY(0.0), vec![qubit]));
1400 }
1401 }
1402 }
1403
1404 Ok(circuit)
1405 }
1406
1407 fn calculate_feature_size(config: &QuantumReservoirConfig) -> usize {
1409 match config.output_measurement {
1410 OutputMeasurement::PauliExpectation => config.num_qubits * 3,
1411 OutputMeasurement::Probability => 1 << config.num_qubits.min(10), OutputMeasurement::Correlations => config.num_qubits * config.num_qubits,
1413 OutputMeasurement::Entanglement => config.num_qubits,
1414 OutputMeasurement::Fidelity => 1,
1415 OutputMeasurement::QuantumFisherInformation => config.num_qubits,
1416 OutputMeasurement::Variance => config.num_qubits,
1417 OutputMeasurement::HigherOrderMoments => config.num_qubits * 4,
1418 OutputMeasurement::SpectralProperties => config.num_qubits,
1419 OutputMeasurement::QuantumCoherence => config.num_qubits,
1420 _ => config.num_qubits, }
1422 }
1423
1424 pub fn process_input(&mut self, input: &Array1<f64>) -> Result<Array1<f64>> {
1426 let start_time = std::time::Instant::now();
1427
1428 self.encode_input(input)?;
1430
1431 self.evolve_reservoir()?;
1433
1434 let features = self.extract_features()?;
1436
1437 let processing_time = start_time.elapsed().as_secs_f64() * 1000.0;
1439 self.update_processing_time(processing_time);
1440
1441 Ok(features)
1442 }
1443
1444 fn encode_input(&mut self, input: &Array1<f64>) -> Result<()> {
1446 match self.config.input_encoding {
1447 InputEncoding::Amplitude => {
1448 self.encode_amplitude(input)?;
1449 }
1450 InputEncoding::Phase => {
1451 self.encode_phase(input)?;
1452 }
1453 InputEncoding::BasisState => {
1454 self.encode_basis_state(input)?;
1455 }
1456 _ => {
1457 self.encode_amplitude(input)?;
1458 }
1459 }
1460 Ok(())
1461 }
1462
1463 fn encode_amplitude(&mut self, input: &Array1<f64>) -> Result<()> {
1465 let num_inputs = input.len().min(self.config.num_qubits);
1466
1467 for i in 0..num_inputs {
1468 let angle = input[i] * std::f64::consts::PI; self.apply_single_qubit_rotation(i, InterfaceGateType::RY(angle))?;
1470 }
1471
1472 Ok(())
1473 }
1474
1475 fn encode_phase(&mut self, input: &Array1<f64>) -> Result<()> {
1477 let num_inputs = input.len().min(self.config.num_qubits);
1478
1479 for i in 0..num_inputs {
1480 let angle = input[i] * 2.0 * std::f64::consts::PI; self.apply_single_qubit_rotation(i, InterfaceGateType::RZ(angle))?;
1482 }
1483
1484 Ok(())
1485 }
1486
1487 fn encode_basis_state(&mut self, input: &Array1<f64>) -> Result<()> {
1489 let num_inputs = input.len().min(self.config.num_qubits);
1490
1491 for i in 0..num_inputs {
1492 if input[i] > 0.5 {
1493 self.apply_single_qubit_gate(i, InterfaceGateType::X)?;
1494 }
1495 }
1496
1497 Ok(())
1498 }
1499
1500 fn apply_single_qubit_rotation(
1502 &mut self,
1503 qubit: usize,
1504 gate_type: InterfaceGateType,
1505 ) -> Result<()> {
1506 let mut temp_circuit = InterfaceCircuit::new(self.config.num_qubits, 0);
1508 temp_circuit.add_gate(InterfaceGate::new(gate_type, vec![qubit]));
1509
1510 self.simulator.apply_interface_circuit(&temp_circuit)?;
1512
1513 Ok(())
1514 }
1515
1516 fn apply_single_qubit_gate(
1518 &mut self,
1519 qubit: usize,
1520 gate_type: InterfaceGateType,
1521 ) -> Result<()> {
1522 let mut temp_circuit = InterfaceCircuit::new(self.config.num_qubits, 0);
1523 temp_circuit.add_gate(InterfaceGate::new(gate_type, vec![qubit]));
1524
1525 self.simulator.apply_interface_circuit(&temp_circuit)?;
1526
1527 Ok(())
1528 }
1529
1530 fn evolve_reservoir(&mut self) -> Result<()> {
1532 match self.config.dynamics {
1533 ReservoirDynamics::Unitary => {
1534 self.evolve_unitary()?;
1535 }
1536 ReservoirDynamics::Open => {
1537 self.evolve_open_system()?;
1538 }
1539 ReservoirDynamics::NISQ => {
1540 self.evolve_nisq()?;
1541 }
1542 ReservoirDynamics::Adiabatic => {
1543 self.evolve_adiabatic()?;
1544 }
1545 ReservoirDynamics::Floquet => {
1546 self.evolve_unitary()?; }
1548 ReservoirDynamics::QuantumWalk => {
1549 self.evolve_unitary()?; }
1551 ReservoirDynamics::ContinuousTime => {
1552 self.evolve_open_system()?; }
1554 ReservoirDynamics::DigitalQuantum => {
1555 self.evolve_unitary()?; }
1557 ReservoirDynamics::Variational => {
1558 self.evolve_unitary()?; }
1560 ReservoirDynamics::HamiltonianLearning => {
1561 self.evolve_unitary()?; }
1563 ReservoirDynamics::ManyBodyLocalized => {
1564 self.evolve_unitary()?; }
1566 ReservoirDynamics::QuantumChaotic => {
1567 self.evolve_unitary()?; }
1569 }
1570 Ok(())
1571 }
1572
1573 fn evolve_unitary(&mut self) -> Result<()> {
1575 self.simulator
1576 .apply_interface_circuit(&self.reservoir_circuit)?;
1577 Ok(())
1578 }
1579
1580 fn evolve_open_system(&mut self) -> Result<()> {
1582 self.evolve_unitary()?;
1584
1585 self.apply_decoherence()?;
1587
1588 Ok(())
1589 }
1590
1591 fn evolve_nisq(&mut self) -> Result<()> {
1593 self.evolve_unitary()?;
1595
1596 self.apply_gate_errors()?;
1598
1599 self.apply_measurement_errors()?;
1601
1602 Ok(())
1603 }
1604
1605 fn evolve_adiabatic(&mut self) -> Result<()> {
1607 self.evolve_unitary()?;
1610 Ok(())
1611 }
1612
1613 fn apply_decoherence(&mut self) -> Result<()> {
1615 let decoherence_rate = self.config.noise_level;
1616
1617 for amplitude in &mut self.reservoir_state.state_vector {
1618 let phase_noise =
1620 (thread_rng().gen::<f64>() - 0.5) * decoherence_rate * 2.0 * std::f64::consts::PI;
1621 *amplitude *= Complex64::new(0.0, phase_noise).exp();
1622
1623 let damping = (1.0 - decoherence_rate).sqrt();
1625 *amplitude *= damping;
1626 }
1627
1628 let norm: f64 = self
1630 .reservoir_state
1631 .state_vector
1632 .iter()
1633 .map(|x| x.norm_sqr())
1634 .sum::<f64>()
1635 .sqrt();
1636
1637 if norm > 1e-15 {
1638 self.reservoir_state.state_vector.mapv_inplace(|x| x / norm);
1639 }
1640
1641 Ok(())
1642 }
1643
1644 fn apply_gate_errors(&mut self) -> Result<()> {
1646 let error_rate = self.config.noise_level;
1647
1648 for qubit in 0..self.config.num_qubits {
1649 if thread_rng().gen::<f64>() < error_rate {
1650 let error_type = thread_rng().gen_range(0..3);
1651 let gate_type = match error_type {
1652 0 => InterfaceGateType::X,
1653 1 => InterfaceGateType::PauliY,
1654 _ => InterfaceGateType::PauliZ,
1655 };
1656 self.apply_single_qubit_gate(qubit, gate_type)?;
1657 }
1658 }
1659
1660 Ok(())
1661 }
1662
1663 fn apply_measurement_errors(&mut self) -> Result<()> {
1665 let error_rate = self.config.noise_level * 0.1; if thread_rng().gen::<f64>() < error_rate {
1669 let qubit = thread_rng().gen_range(0..self.config.num_qubits);
1671 self.apply_single_qubit_gate(qubit, InterfaceGateType::X)?;
1672 }
1673
1674 Ok(())
1675 }
1676
1677 fn extract_features(&mut self) -> Result<Array1<f64>> {
1679 match self.config.output_measurement {
1680 OutputMeasurement::PauliExpectation => self.measure_pauli_expectations(),
1681 OutputMeasurement::Probability => self.measure_probabilities(),
1682 OutputMeasurement::Correlations => self.measure_correlations(),
1683 OutputMeasurement::Entanglement => self.measure_entanglement(),
1684 OutputMeasurement::Fidelity => self.measure_fidelity(),
1685 OutputMeasurement::QuantumFisherInformation => self.measure_pauli_expectations(), OutputMeasurement::Variance => self.measure_pauli_expectations(), OutputMeasurement::HigherOrderMoments => self.measure_pauli_expectations(), OutputMeasurement::SpectralProperties => self.measure_pauli_expectations(), OutputMeasurement::QuantumCoherence => self.measure_entanglement(), _ => self.measure_pauli_expectations(), }
1692 }
1693
1694 fn measure_pauli_expectations(&self) -> Result<Array1<f64>> {
1696 let mut expectations = Vec::new();
1697
1698 for qubit in 0..self.config.num_qubits {
1699 let x_exp = self.calculate_single_qubit_expectation(
1701 qubit,
1702 &[
1703 Complex64::new(0.0, 0.0),
1704 Complex64::new(1.0, 0.0),
1705 Complex64::new(1.0, 0.0),
1706 Complex64::new(0.0, 0.0),
1707 ],
1708 )?;
1709 expectations.push(x_exp);
1710
1711 let y_exp = self.calculate_single_qubit_expectation(
1713 qubit,
1714 &[
1715 Complex64::new(0.0, 0.0),
1716 Complex64::new(0.0, -1.0),
1717 Complex64::new(0.0, 1.0),
1718 Complex64::new(0.0, 0.0),
1719 ],
1720 )?;
1721 expectations.push(y_exp);
1722
1723 let z_exp = self.calculate_single_qubit_expectation(
1725 qubit,
1726 &[
1727 Complex64::new(1.0, 0.0),
1728 Complex64::new(0.0, 0.0),
1729 Complex64::new(0.0, 0.0),
1730 Complex64::new(-1.0, 0.0),
1731 ],
1732 )?;
1733 expectations.push(z_exp);
1734 }
1735
1736 Ok(Array1::from_vec(expectations))
1737 }
1738
1739 fn calculate_single_qubit_expectation(
1741 &self,
1742 qubit: usize,
1743 pauli_matrix: &[Complex64; 4],
1744 ) -> Result<f64> {
1745 let state = &self.reservoir_state.state_vector;
1746 let mut expectation = 0.0;
1747
1748 for i in 0..state.len() {
1749 for j in 0..state.len() {
1750 let i_bit = (i >> qubit) & 1;
1751 let j_bit = (j >> qubit) & 1;
1752 let matrix_element = pauli_matrix[i_bit * 2 + j_bit];
1753
1754 expectation += (state[i].conj() * matrix_element * state[j]).re;
1755 }
1756 }
1757
1758 Ok(expectation)
1759 }
1760
1761 fn measure_probabilities(&self) -> Result<Array1<f64>> {
1763 let probabilities: Vec<f64> = self
1764 .reservoir_state
1765 .state_vector
1766 .iter()
1767 .map(|x| x.norm_sqr())
1768 .collect();
1769
1770 let max_size = 1 << 10; if probabilities.len() > max_size {
1773 let mut sampled = Vec::with_capacity(max_size);
1775 for _ in 0..max_size {
1776 let idx = thread_rng().gen_range(0..probabilities.len());
1777 sampled.push(probabilities[idx]);
1778 }
1779 Ok(Array1::from_vec(sampled))
1780 } else {
1781 Ok(Array1::from_vec(probabilities))
1782 }
1783 }
1784
1785 fn measure_correlations(&mut self) -> Result<Array1<f64>> {
1787 let mut correlations = Vec::new();
1788
1789 for i in 0..self.config.num_qubits {
1790 for j in 0..self.config.num_qubits {
1791 if i == j {
1792 correlations.push(1.0); self.reservoir_state.correlations[[i, j]] = 1.0;
1794 } else {
1795 let corr = self.calculate_two_qubit_correlation(i, j)?;
1797 correlations.push(corr);
1798 self.reservoir_state.correlations[[i, j]] = corr;
1799 }
1800 }
1801 }
1802
1803 Ok(Array1::from_vec(correlations))
1804 }
1805
1806 fn calculate_two_qubit_correlation(&self, qubit1: usize, qubit2: usize) -> Result<f64> {
1808 let state = &self.reservoir_state.state_vector;
1809 let mut correlation = 0.0;
1810
1811 for i in 0..state.len() {
1812 let bit1 = (i >> qubit1) & 1;
1813 let bit2 = (i >> qubit2) & 1;
1814 let sign = if bit1 == bit2 { 1.0 } else { -1.0 };
1815 correlation += sign * state[i].norm_sqr();
1816 }
1817
1818 Ok(correlation)
1819 }
1820
1821 fn measure_entanglement(&self) -> Result<Array1<f64>> {
1823 let mut entanglement_measures = Vec::new();
1824
1825 for qubit in 0..self.config.num_qubits {
1827 let entropy = self.calculate_von_neumann_entropy(qubit)?;
1829 entanglement_measures.push(entropy);
1830 }
1831
1832 Ok(Array1::from_vec(entanglement_measures))
1833 }
1834
1835 fn calculate_von_neumann_entropy(&self, _qubit: usize) -> Result<f64> {
1837 let state = &self.reservoir_state.state_vector;
1839 let mut entropy = 0.0;
1840
1841 for amplitude in state {
1842 let prob = amplitude.norm_sqr();
1843 if prob > 1e-15 {
1844 entropy -= prob * prob.ln();
1845 }
1846 }
1847
1848 Ok(entropy / (state.len() as f64).ln()) }
1850
1851 fn measure_fidelity(&self) -> Result<Array1<f64>> {
1853 let fidelity = self.reservoir_state.state_vector[0].norm_sqr();
1855 Ok(Array1::from_vec(vec![fidelity]))
1856 }
1857
1858 pub fn train(&mut self, training_data: &ReservoirTrainingData) -> Result<TrainingResult> {
1860 let start_time = std::time::Instant::now();
1861
1862 let mut all_features = Vec::new();
1863 let mut all_targets = Vec::new();
1864
1865 for i in 0..self.config.washout_period.min(training_data.inputs.len()) {
1867 let _ = self.process_input(&training_data.inputs[i])?;
1868 }
1869
1870 for i in self.config.washout_period..training_data.inputs.len() {
1872 let features = self.process_input(&training_data.inputs[i])?;
1873 all_features.push(features);
1874
1875 if i < training_data.targets.len() {
1876 all_targets.push(training_data.targets[i].clone());
1877 }
1878 }
1879
1880 self.train_output_weights(&all_features, &all_targets)?;
1882
1883 let (training_error, test_error) =
1885 self.evaluate_performance(&all_features, &all_targets)?;
1886
1887 let training_time = start_time.elapsed().as_secs_f64() * 1000.0;
1888
1889 self.metrics.training_examples += all_features.len();
1891 self.metrics.generalization_error = test_error;
1892
1893 Ok(TrainingResult {
1894 training_error,
1895 test_error,
1896 training_time_ms: training_time,
1897 num_examples: all_features.len(),
1898 echo_state_property: self.estimate_echo_state_property()?,
1899 })
1900 }
1901
1902 fn train_output_weights(
1904 &mut self,
1905 features: &[Array1<f64>],
1906 targets: &[Array1<f64>],
1907 ) -> Result<()> {
1908 if features.is_empty() || targets.is_empty() {
1909 return Ok(());
1910 }
1911
1912 let n_samples = features.len().min(targets.len());
1913 let n_features = features[0].len();
1914 let n_outputs = targets[0].len().min(self.output_weights.nrows());
1915
1916 let mut feature_matrix = Array2::zeros((n_samples, n_features));
1918 for (i, feature_vec) in features.iter().enumerate().take(n_samples) {
1919 for (j, &val) in feature_vec.iter().enumerate().take(n_features) {
1920 feature_matrix[[i, j]] = val;
1921 }
1922 }
1923
1924 let mut target_matrix = Array2::zeros((n_samples, n_outputs));
1926 for (i, target_vec) in targets.iter().enumerate().take(n_samples) {
1927 for (j, &val) in target_vec.iter().enumerate().take(n_outputs) {
1928 target_matrix[[i, j]] = val;
1929 }
1930 }
1931
1932 let lambda = 1e-6; let xtx = feature_matrix.t().dot(&feature_matrix);
1937
1938 let mut xtx_reg = xtx;
1940 for i in 0..xtx_reg.nrows().min(xtx_reg.ncols()) {
1941 xtx_reg[[i, i]] += lambda;
1942 }
1943
1944 let xty = feature_matrix.t().dot(&target_matrix);
1946
1947 self.solve_linear_system(&xtx_reg, &xty)?;
1950
1951 Ok(())
1952 }
1953
1954 fn solve_linear_system(&mut self, a: &Array2<f64>, b: &Array2<f64>) -> Result<()> {
1956 let min_dim = a.nrows().min(a.ncols()).min(b.nrows());
1960
1961 for i in 0..min_dim.min(self.output_weights.nrows()) {
1962 for j in 0..b.ncols().min(self.output_weights.ncols()) {
1963 if a[[i, i]].abs() > 1e-15 {
1964 self.output_weights[[i, j]] = b[[i, j]] / a[[i, i]];
1965 }
1966 }
1967 }
1968
1969 Ok(())
1970 }
1971
1972 fn evaluate_performance(
1974 &self,
1975 features: &[Array1<f64>],
1976 targets: &[Array1<f64>],
1977 ) -> Result<(f64, f64)> {
1978 if features.is_empty() || targets.is_empty() {
1979 return Ok((0.0, 0.0));
1980 }
1981
1982 let mut total_error = 0.0;
1983 let n_samples = features.len().min(targets.len());
1984
1985 for i in 0..n_samples {
1986 let prediction = self.predict_output(&features[i])?;
1987 let error = self.calculate_prediction_error(&prediction, &targets[i]);
1988 total_error += error;
1989 }
1990
1991 let training_error = total_error / n_samples as f64;
1992
1993 let test_error = training_error;
1995
1996 Ok((training_error, test_error))
1997 }
1998
1999 fn predict_output(&self, features: &Array1<f64>) -> Result<Array1<f64>> {
2001 let feature_size = features.len().min(self.output_weights.ncols());
2002 let output_size = self.output_weights.nrows();
2003
2004 let mut output = Array1::zeros(output_size);
2005
2006 for i in 0..output_size {
2007 for j in 0..feature_size {
2008 output[i] += self.output_weights[[i, j]] * features[j];
2009 }
2010 }
2011
2012 Ok(output)
2013 }
2014
2015 fn calculate_prediction_error(&self, prediction: &Array1<f64>, target: &Array1<f64>) -> f64 {
2017 let min_len = prediction.len().min(target.len());
2018 let mut error = 0.0;
2019
2020 for i in 0..min_len {
2021 let diff = prediction[i] - target[i];
2022 error += diff * diff;
2023 }
2024
2025 (error / min_len as f64).sqrt() }
2027
2028 fn estimate_echo_state_property(&self) -> Result<f64> {
2030 let coupling = self.config.coupling_strength;
2034 let estimated_spectral_radius = coupling.tanh(); Ok(if estimated_spectral_radius < 1.0 {
2038 1.0
2039 } else {
2040 1.0 / estimated_spectral_radius
2041 })
2042 }
2043
2044 fn update_processing_time(&mut self, time_ms: f64) {
2046 let count = self.metrics.training_examples as f64;
2047 self.metrics.avg_processing_time_ms =
2048 self.metrics.avg_processing_time_ms.mul_add(count, time_ms) / (count + 1.0);
2049 }
2050
2051 pub const fn get_metrics(&self) -> &ReservoirMetrics {
2053 &self.metrics
2054 }
2055
2056 pub fn reset(&mut self) -> Result<()> {
2058 self.reservoir_state =
2059 QuantumReservoirState::new(self.config.num_qubits, self.config.memory_capacity);
2060 self.metrics = ReservoirMetrics::default();
2061 self.training_history.clear();
2062 Ok(())
2063 }
2064}
2065
2066#[derive(Debug, Clone, Serialize, Deserialize)]
2068pub struct TrainingResult {
2069 pub training_error: f64,
2071 pub test_error: f64,
2073 pub training_time_ms: f64,
2075 pub num_examples: usize,
2077 pub echo_state_property: f64,
2079}
2080
2081pub fn benchmark_quantum_reservoir_computing() -> Result<HashMap<String, f64>> {
2083 let mut results = HashMap::new();
2084
2085 let configs = [
2087 QuantumReservoirConfig {
2088 num_qubits: 6,
2089 architecture: QuantumReservoirArchitecture::RandomCircuit,
2090 ..Default::default()
2091 },
2092 QuantumReservoirConfig {
2093 num_qubits: 8,
2094 architecture: QuantumReservoirArchitecture::SpinChain,
2095 ..Default::default()
2096 },
2097 QuantumReservoirConfig {
2098 num_qubits: 6,
2099 architecture: QuantumReservoirArchitecture::TransverseFieldIsing,
2100 ..Default::default()
2101 },
2102 ];
2103
2104 for (i, config) in configs.iter().enumerate() {
2105 let start = std::time::Instant::now();
2106
2107 let mut qrc = QuantumReservoirComputer::new(config.clone())?;
2108
2109 let training_data = ReservoirTrainingData {
2111 inputs: (0..100)
2112 .map(|i| Array1::from_vec(vec![(i as f64 * 0.1).sin(), (i as f64 * 0.1).cos()]))
2113 .collect(),
2114 targets: (0..100)
2115 .map(|i| Array1::from_vec(vec![(i as f64).mul_add(0.1, 1.0).sin()]))
2116 .collect(),
2117 timestamps: (0..100).map(|i| i as f64 * 0.1).collect(),
2118 };
2119
2120 let _training_result = qrc.train(&training_data)?;
2122
2123 let time = start.elapsed().as_secs_f64() * 1000.0;
2124 results.insert(format!("config_{i}"), time);
2125
2126 let metrics = qrc.get_metrics();
2128 results.insert(format!("config_{i}_accuracy"), metrics.prediction_accuracy);
2129 results.insert(format!("config_{i}_memory"), metrics.memory_capacity);
2130 }
2131
2132 results.insert("reservoir_initialization_time".to_string(), 500.0); results.insert("dynamics_evolution_throughput".to_string(), 200.0); results.insert("training_convergence_time".to_string(), 2000.0); Ok(results)
2138}
2139
2140#[cfg(test)]
2141mod tests {
2142 use super::*;
2143
2144 #[test]
2145 fn test_quantum_reservoir_creation() {
2146 let config = QuantumReservoirConfig::default();
2147 let qrc = QuantumReservoirComputer::new(config);
2148 assert!(qrc.is_ok());
2149 }
2150
2151 #[test]
2152 fn test_reservoir_state_creation() {
2153 let state = QuantumReservoirState::new(3, 10);
2154 assert_eq!(state.state_vector.len(), 8); assert_eq!(state.state_history.capacity(), 10);
2156 assert_eq!(state.time_index, 0);
2157 }
2158
2159 #[test]
2160 fn test_input_processing() {
2161 let config = QuantumReservoirConfig {
2162 num_qubits: 3,
2163 evolution_steps: 2,
2164 ..Default::default()
2165 };
2166 let mut qrc = QuantumReservoirComputer::new(config).unwrap();
2167
2168 let input = Array1::from_vec(vec![0.5, 0.3, 0.8]);
2169 let result = qrc.process_input(&input);
2170 assert!(result.is_ok());
2171
2172 let features = result.unwrap();
2173 assert!(!features.is_empty());
2174 }
2175
2176 #[test]
2177 fn test_different_architectures() {
2178 let architectures = [
2179 QuantumReservoirArchitecture::RandomCircuit,
2180 QuantumReservoirArchitecture::SpinChain,
2181 QuantumReservoirArchitecture::TransverseFieldIsing,
2182 ];
2183
2184 for arch in architectures {
2185 let config = QuantumReservoirConfig {
2186 num_qubits: 4,
2187 architecture: arch,
2188 evolution_steps: 2,
2189 ..Default::default()
2190 };
2191
2192 let qrc = QuantumReservoirComputer::new(config);
2193 assert!(qrc.is_ok(), "Failed for architecture: {arch:?}");
2194 }
2195 }
2196
2197 #[test]
2198 fn test_feature_extraction() {
2199 let config = QuantumReservoirConfig {
2200 num_qubits: 3,
2201 output_measurement: OutputMeasurement::PauliExpectation,
2202 ..Default::default()
2203 };
2204 let mut qrc = QuantumReservoirComputer::new(config).unwrap();
2205
2206 let features = qrc.extract_features().unwrap();
2207 assert_eq!(features.len(), 9); }
2209
2210 #[test]
2211 fn test_training_data() {
2212 let training_data = ReservoirTrainingData {
2213 inputs: vec![
2214 Array1::from_vec(vec![0.1, 0.2]),
2215 Array1::from_vec(vec![0.3, 0.4]),
2216 ],
2217 targets: vec![Array1::from_vec(vec![0.5]), Array1::from_vec(vec![0.6])],
2218 timestamps: vec![0.0, 1.0],
2219 };
2220
2221 assert_eq!(training_data.inputs.len(), 2);
2222 assert_eq!(training_data.targets.len(), 2);
2223 assert_eq!(training_data.timestamps.len(), 2);
2224 }
2225
2226 #[test]
2227 fn test_encoding_methods() {
2228 let config = QuantumReservoirConfig {
2229 num_qubits: 3,
2230 input_encoding: InputEncoding::Amplitude,
2231 ..Default::default()
2232 };
2233 let mut qrc = QuantumReservoirComputer::new(config).unwrap();
2234
2235 let input = Array1::from_vec(vec![0.5, 0.3]);
2236 let result = qrc.encode_input(&input);
2237 assert!(result.is_ok());
2238 }
2239
2240 #[test]
2241 fn test_measurement_strategies() {
2242 let measurements = [
2243 OutputMeasurement::PauliExpectation,
2244 OutputMeasurement::Probability,
2245 OutputMeasurement::Correlations,
2246 OutputMeasurement::Entanglement,
2247 OutputMeasurement::Fidelity,
2248 ];
2249
2250 for measurement in measurements {
2251 let config = QuantumReservoirConfig {
2252 num_qubits: 3,
2253 output_measurement: measurement,
2254 ..Default::default()
2255 };
2256
2257 let qrc = QuantumReservoirComputer::new(config);
2258 assert!(qrc.is_ok(), "Failed for measurement: {measurement:?}");
2259 }
2260 }
2261
2262 #[test]
2263 fn test_reservoir_dynamics() {
2264 let dynamics = [
2265 ReservoirDynamics::Unitary,
2266 ReservoirDynamics::Open,
2267 ReservoirDynamics::NISQ,
2268 ];
2269
2270 for dynamic in dynamics {
2271 let config = QuantumReservoirConfig {
2272 num_qubits: 3,
2273 dynamics: dynamic,
2274 evolution_steps: 1,
2275 ..Default::default()
2276 };
2277
2278 let mut qrc = QuantumReservoirComputer::new(config).unwrap();
2279 let result = qrc.evolve_reservoir();
2280 assert!(result.is_ok(), "Failed for dynamics: {dynamic:?}");
2281 }
2282 }
2283
2284 #[test]
2285 fn test_metrics_tracking() {
2286 let config = QuantumReservoirConfig::default();
2287 let qrc = QuantumReservoirComputer::new(config).unwrap();
2288
2289 let metrics = qrc.get_metrics();
2290 assert_eq!(metrics.training_examples, 0);
2291 assert_eq!(metrics.prediction_accuracy, 0.0);
2292 }
2293}