1use ndarray::{Array1, Array2};
28use num_complex::Complex64;
29use serde::{Deserialize, Serialize};
30use std::collections::{HashMap, VecDeque};
31
32use crate::circuit_interfaces::{
33 CircuitInterface, InterfaceCircuit, InterfaceGate, InterfaceGateType,
34};
35use crate::error::Result;
36use crate::hardware_aware_qml::AdaptationState;
37use crate::quantum_reservoir_computing_enhanced::MemoryMetrics;
38use crate::statevector::StateVectorSimulator;
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
42pub enum QuantumReservoirArchitecture {
43 RandomCircuit,
45 SpinChain,
47 TransverseFieldIsing,
49 SmallWorld,
51 FullyConnected,
53 ScaleFree,
55 HierarchicalModular,
57 AdaptiveTopology,
59 QuantumCellularAutomaton,
61 Ring,
63 Grid,
65 Tree,
67 Hypergraph,
69 TensorNetwork,
71 Custom,
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
77pub enum ReservoirDynamics {
78 Unitary,
80 Open,
82 NISQ,
84 Adiabatic,
86 Floquet,
88 QuantumWalk,
90 ContinuousTime,
92 DigitalQuantum,
94 Variational,
96 HamiltonianLearning,
98 ManyBodyLocalized,
100 QuantumChaotic,
102}
103
104#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
106pub enum InputEncoding {
107 Amplitude,
109 Phase,
111 BasisState,
113 Coherent,
115 Squeezed,
117 Angle,
119 IQP,
121 DataReUploading,
123 QuantumFeatureMap,
125 VariationalEncoding,
127 TemporalEncoding,
129 FourierEncoding,
131 WaveletEncoding,
133 HaarRandom,
135 GraphEncoding,
137}
138
139#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
141pub enum OutputMeasurement {
142 PauliExpectation,
144 Probability,
146 Correlations,
148 Entanglement,
150 Fidelity,
152 QuantumFisherInformation,
154 Variance,
156 HigherOrderMoments,
158 SpectralProperties,
160 QuantumCoherence,
162 Purity,
164 QuantumMutualInformation,
166 ProcessTomography,
168 TemporalCorrelations,
170 NonLinearReadout,
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
176pub struct QuantumReservoirConfig {
177 pub num_qubits: usize,
179 pub architecture: QuantumReservoirArchitecture,
181 pub dynamics: ReservoirDynamics,
183 pub input_encoding: InputEncoding,
185 pub output_measurement: OutputMeasurement,
187 pub learning_config: AdvancedLearningConfig,
189 pub time_series_config: TimeSeriesConfig,
191 pub topology_config: TopologyConfig,
193 pub adaptive_config: AdaptiveLearningConfig,
195 pub memory_config: MemoryAnalysisConfig,
197 pub hardware_config: HardwareOptimizationConfig,
199 pub benchmark_config: BenchmarkingConfig,
201 pub time_step: f64,
203 pub evolution_steps: usize,
205 pub coupling_strength: f64,
207 pub noise_level: f64,
209 pub memory_capacity: usize,
211 pub adaptive_learning: bool,
213 pub learning_rate: f64,
215 pub washout_period: usize,
217 pub random_seed: Option<u64>,
219 pub enable_qec: bool,
221 pub precision: f64,
223}
224
225impl Default for QuantumReservoirConfig {
226 fn default() -> Self {
227 Self {
228 num_qubits: 8,
229 architecture: QuantumReservoirArchitecture::RandomCircuit,
230 dynamics: ReservoirDynamics::Unitary,
231 input_encoding: InputEncoding::Amplitude,
232 output_measurement: OutputMeasurement::PauliExpectation,
233 learning_config: AdvancedLearningConfig::default(),
234 time_series_config: TimeSeriesConfig::default(),
235 topology_config: TopologyConfig::default(),
236 adaptive_config: AdaptiveLearningConfig::default(),
237 memory_config: MemoryAnalysisConfig::default(),
238 hardware_config: HardwareOptimizationConfig::default(),
239 benchmark_config: BenchmarkingConfig::default(),
240 time_step: 0.1,
241 evolution_steps: 10,
242 coupling_strength: 1.0,
243 noise_level: 0.01,
244 memory_capacity: 100,
245 adaptive_learning: true,
246 learning_rate: 0.01,
247 washout_period: 50,
248 random_seed: None,
249 enable_qec: false,
250 precision: 1e-8,
251 }
252 }
253}
254
255#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
257pub enum LearningAlgorithm {
258 Ridge,
260 LASSO,
262 ElasticNet,
264 RecursiveLeastSquares,
266 KalmanFilter,
268 ExtendedKalmanFilter,
270 NeuralNetwork,
272 SupportVectorRegression,
274 GaussianProcess,
276 RandomForest,
278 GradientBoosting,
280 OnlineGradientDescent,
282 Adam,
284 MetaLearning,
286}
287
288#[derive(Debug, Clone, Serialize, Deserialize)]
290pub struct AdvancedLearningConfig {
291 pub algorithm: LearningAlgorithm,
293 pub regularization: f64,
295 pub l1_ratio: f64,
297 pub forgetting_factor: f64,
299 pub process_noise: f64,
301 pub measurement_noise: f64,
303 pub nn_architecture: Vec<usize>,
305 pub nn_activation: ActivationFunction,
307 pub epochs: usize,
309 pub batch_size: usize,
311 pub early_stopping_patience: usize,
313 pub cv_folds: usize,
315 pub enable_ensemble: bool,
317 pub ensemble_size: usize,
319}
320
321impl Default for AdvancedLearningConfig {
322 fn default() -> Self {
323 Self {
324 algorithm: LearningAlgorithm::Ridge,
325 regularization: 1e-6,
326 l1_ratio: 0.5,
327 forgetting_factor: 0.99,
328 process_noise: 1e-4,
329 measurement_noise: 1e-3,
330 nn_architecture: vec![64, 32, 16],
331 nn_activation: ActivationFunction::ReLU,
332 epochs: 100,
333 batch_size: 32,
334 early_stopping_patience: 10,
335 cv_folds: 5,
336 enable_ensemble: false,
337 ensemble_size: 5,
338 }
339 }
340}
341
342#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
344pub enum ActivationFunction {
345 ReLU,
347 LeakyReLU,
349 ELU,
351 Sigmoid,
353 Tanh,
355 Swish,
357 GELU,
359 Linear,
361}
362
363#[derive(Debug, Clone, Serialize, Deserialize)]
365pub struct TimeSeriesConfig {
366 pub enable_arima: bool,
368 pub ar_order: usize,
370 pub ma_order: usize,
372 pub diff_order: usize,
374 pub enable_nar: bool,
376 pub nar_order: usize,
378 pub memory_kernel: MemoryKernel,
380 pub kernel_params: Vec<f64>,
382 pub enable_seasonal: bool,
384 pub seasonal_period: usize,
386 pub trend_method: TrendDetectionMethod,
388 pub enable_changepoint: bool,
390 pub anomaly_threshold: f64,
392}
393
394impl Default for TimeSeriesConfig {
395 fn default() -> Self {
396 Self {
397 enable_arima: true,
398 ar_order: 2,
399 ma_order: 1,
400 diff_order: 1,
401 enable_nar: true,
402 nar_order: 3,
403 memory_kernel: MemoryKernel::Exponential,
404 kernel_params: vec![0.9, 0.1],
405 enable_seasonal: false,
406 seasonal_period: 12,
407 trend_method: TrendDetectionMethod::LinearRegression,
408 enable_changepoint: false,
409 anomaly_threshold: 2.0,
410 }
411 }
412}
413
414#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
416pub enum MemoryKernel {
417 Exponential,
419 PowerLaw,
421 Gaussian,
423 Polynomial,
425 Rational,
427 Sinusoidal,
429 Custom,
431}
432
433#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
435pub enum TrendDetectionMethod {
436 LinearRegression,
438 Polynomial,
440 MovingAverage,
442 HodrickPrescott,
444 KalmanFilter,
446 Spectral,
448}
449
450#[derive(Debug, Clone, Serialize, Deserialize)]
452pub struct TopologyConfig {
453 pub connectivity_density: f64,
455 pub clustering_coefficient: f64,
457 pub rewiring_probability: f64,
459 pub power_law_exponent: f64,
461 pub hierarchical_levels: usize,
463 pub modularity_strength: f64,
465 pub num_modules: usize,
467 pub enable_adaptive: bool,
469 pub adaptation_rate: f64,
471 pub min_connection_strength: f64,
473 pub max_connection_strength: f64,
475 pub pruning_threshold: f64,
477}
478
479impl Default for TopologyConfig {
480 fn default() -> Self {
481 Self {
482 connectivity_density: 0.1,
483 clustering_coefficient: 0.3,
484 rewiring_probability: 0.1,
485 power_law_exponent: 2.5,
486 hierarchical_levels: 3,
487 modularity_strength: 0.5,
488 num_modules: 4,
489 enable_adaptive: false,
490 adaptation_rate: 0.01,
491 min_connection_strength: 0.1,
492 max_connection_strength: 2.0,
493 pruning_threshold: 0.05,
494 }
495 }
496}
497
498#[derive(Debug, Clone, Serialize, Deserialize)]
500pub struct AdaptiveLearningConfig {
501 pub enable_online: bool,
503 pub lr_schedule: LearningRateSchedule,
505 pub initial_lr: f64,
507 pub min_lr: f64,
509 pub lr_decay: f64,
511 pub adaptation_window: usize,
513 pub plasticity_type: PlasticityType,
515 pub enable_homeostasis: bool,
517 pub target_activity: f64,
519 pub regulation_rate: f64,
521 pub enable_meta_learning: bool,
523 pub meta_update_frequency: usize,
525}
526
527impl Default for AdaptiveLearningConfig {
528 fn default() -> Self {
529 Self {
530 enable_online: true,
531 lr_schedule: LearningRateSchedule::Exponential,
532 initial_lr: 0.01,
533 min_lr: 1e-6,
534 lr_decay: 0.95,
535 adaptation_window: 100,
536 plasticity_type: PlasticityType::Hebbian,
537 enable_homeostasis: false,
538 target_activity: 0.5,
539 regulation_rate: 0.001,
540 enable_meta_learning: false,
541 meta_update_frequency: 1000,
542 }
543 }
544}
545
546#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
548pub enum LearningRateSchedule {
549 Constant,
551 Exponential,
553 Step,
555 Polynomial,
557 CosineAnnealing,
559 WarmRestart,
561 Adaptive,
563}
564
565#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
567pub enum PlasticityType {
568 Hebbian,
570 AntiHebbian,
572 STDP,
574 Homeostatic,
576 Metaplasticity,
578 Quantum,
580}
581
582#[derive(Debug, Clone, Serialize, Deserialize)]
584pub struct MemoryAnalysisConfig {
585 pub enable_capacity_estimation: bool,
587 pub capacity_tasks: Vec<MemoryTask>,
589 pub enable_nonlinear: bool,
591 pub nonlinearity_orders: Vec<usize>,
593 pub enable_temporal_correlation: bool,
595 pub correlation_lags: Vec<usize>,
597 pub enable_ipc: bool,
599 pub ipc_functions: Vec<IPCFunction>,
601 pub enable_entropy: bool,
603 pub entropy_measures: Vec<EntropyMeasure>,
605}
606
607impl Default for MemoryAnalysisConfig {
608 fn default() -> Self {
609 Self {
610 enable_capacity_estimation: true,
611 capacity_tasks: vec![
612 MemoryTask::DelayLine,
613 MemoryTask::TemporalXOR,
614 MemoryTask::Parity,
615 ],
616 enable_nonlinear: true,
617 nonlinearity_orders: vec![2, 3, 4],
618 enable_temporal_correlation: true,
619 correlation_lags: (1..=20).collect(),
620 enable_ipc: true,
621 ipc_functions: vec![
622 IPCFunction::Linear,
623 IPCFunction::Quadratic,
624 IPCFunction::Cubic,
625 ],
626 enable_entropy: true,
627 entropy_measures: vec![
628 EntropyMeasure::Shannon,
629 EntropyMeasure::Renyi,
630 EntropyMeasure::VonNeumann,
631 ],
632 }
633 }
634}
635
636#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
638pub enum MemoryTask {
639 DelayLine,
641 TemporalXOR,
643 Parity,
645 SequencePrediction,
647 PatternCompletion,
649 TemporalIntegration,
651}
652
653#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
655pub enum IPCFunction {
656 Linear,
658 Quadratic,
660 Cubic,
662 Sine,
664 Product,
666 XOR,
668}
669
670#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
672pub enum EntropyMeasure {
673 Shannon,
675 Renyi,
677 VonNeumann,
679 Tsallis,
681 MutualInformation,
683 TransferEntropy,
685}
686
687#[derive(Debug, Clone, Serialize, Deserialize)]
689pub struct HardwareOptimizationConfig {
690 pub platform: QuantumPlatform,
692 pub enable_noise_aware: bool,
694 pub error_mitigation: Vec<ErrorMitigationMethod>,
696 pub enable_circuit_optimization: bool,
698 pub native_gate_set: Vec<NativeGate>,
700 pub connectivity_constraints: ConnectivityConstraints,
702 pub enable_calibration: bool,
704 pub calibration_frequency: usize,
706 pub enable_monitoring: bool,
708 pub enable_hardware_adaptation: bool,
710}
711
712impl Default for HardwareOptimizationConfig {
713 fn default() -> Self {
714 Self {
715 platform: QuantumPlatform::Simulator,
716 enable_noise_aware: true,
717 error_mitigation: vec![ErrorMitigationMethod::ZNE, ErrorMitigationMethod::PEC],
718 enable_circuit_optimization: true,
719 native_gate_set: vec![NativeGate::RZ, NativeGate::SX, NativeGate::CNOT],
720 connectivity_constraints: ConnectivityConstraints::AllToAll,
721 enable_calibration: false,
722 calibration_frequency: 100,
723 enable_monitoring: true,
724 enable_hardware_adaptation: false,
725 }
726 }
727}
728
729#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
731pub enum QuantumPlatform {
732 Simulator,
734 IBM,
736 Google,
738 IonQ,
740 Rigetti,
742 Quantinuum,
744 Xanadu,
746 AtomComputing,
748 GenericNISQ,
750}
751
752#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
754pub enum ErrorMitigationMethod {
755 ZNE,
757 PEC,
759 ReadoutCorrection,
761 SymmetryVerification,
763 VirtualDistillation,
765 MeasurementCorrection,
767}
768
769#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
771pub enum NativeGate {
772 RZ,
774 SX,
776 CNOT,
778 CZ,
780 ISwap,
782 MS,
784 U3,
786}
787
788#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
790pub enum ConnectivityConstraints {
791 AllToAll,
793 Linear,
795 Grid2D,
797 HeavyHex,
799 Custom,
801}
802
803#[derive(Debug, Clone, Serialize, Deserialize)]
805pub struct BenchmarkingConfig {
806 pub enable_comprehensive: bool,
808 pub datasets: Vec<BenchmarkDataset>,
810 pub metrics: Vec<PerformanceMetric>,
812 pub statistical_tests: Vec<StatisticalTest>,
814 pub comparison_methods: Vec<ComparisonMethod>,
816 pub num_runs: usize,
818 pub confidence_level: f64,
820 pub enable_cross_validation: bool,
822 pub cv_strategy: CrossValidationStrategy,
824}
825
826impl Default for BenchmarkingConfig {
827 fn default() -> Self {
828 Self {
829 enable_comprehensive: true,
830 datasets: vec![
831 BenchmarkDataset::MackeyGlass,
832 BenchmarkDataset::Lorenz,
833 BenchmarkDataset::Sine,
834 BenchmarkDataset::Chaotic,
835 ],
836 metrics: vec![
837 PerformanceMetric::MSE,
838 PerformanceMetric::MAE,
839 PerformanceMetric::R2,
840 PerformanceMetric::MemoryCapacity,
841 ],
842 statistical_tests: vec![
843 StatisticalTest::TTest,
844 StatisticalTest::WilcoxonRankSum,
845 StatisticalTest::KruskalWallis,
846 ],
847 comparison_methods: vec![
848 ComparisonMethod::ESN,
849 ComparisonMethod::LSTM,
850 ComparisonMethod::GRU,
851 ],
852 num_runs: 10,
853 confidence_level: 0.95,
854 enable_cross_validation: true,
855 cv_strategy: CrossValidationStrategy::KFold,
856 }
857 }
858}
859
860#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
862pub enum BenchmarkDataset {
863 MackeyGlass,
865 Lorenz,
867 Sine,
869 Chaotic,
871 Financial,
873 Weather,
875 EEG,
877 Speech,
879 SyntheticNonlinear,
881}
882
883#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
885pub enum PerformanceMetric {
886 MSE,
888 MAE,
890 RMSE,
892 R2,
894 MemoryCapacity,
896 ProcessingSpeed,
898 TrainingTime,
900 GeneralizationError,
902 IPC,
904 QuantumAdvantage,
906}
907
908#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
910pub enum StatisticalTest {
911 TTest,
913 WilcoxonRankSum,
915 KruskalWallis,
917 ANOVA,
919 Friedman,
921 Bootstrap,
923}
924
925#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
927pub enum ComparisonMethod {
928 ESN,
930 LSTM,
932 GRU,
934 Transformer,
936 SVM,
938 RandomForest,
940 LinearRegression,
942}
943
944#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
946pub enum CrossValidationStrategy {
947 KFold,
949 TimeSeriesSplit,
951 LeaveOneOut,
953 StratifiedKFold,
955 GroupKFold,
957}
958
959#[derive(Debug, Clone)]
961pub struct QuantumReservoirState {
962 pub state_vector: Array1<Complex64>,
964 pub state_history: VecDeque<Array1<Complex64>>,
966 pub observables: HashMap<String, f64>,
968 pub correlations: Array2<f64>,
970 pub higher_order_correlations: HashMap<String, f64>,
972 pub entanglement_measures: HashMap<String, f64>,
974 pub memory_metrics: MemoryMetrics,
976 pub time_index: usize,
978 pub last_update: f64,
980 pub activity_level: f64,
982 pub adaptation_state: AdaptationState,
984 pub performance_history: VecDeque<f64>,
986}
987
988impl QuantumReservoirState {
989 pub fn new(num_qubits: usize, memory_capacity: usize) -> Self {
991 let state_size = 1 << num_qubits;
992 let mut state_vector = Array1::zeros(state_size);
993 state_vector[0] = Complex64::new(1.0, 0.0); Self {
996 state_vector,
997 state_history: VecDeque::with_capacity(memory_capacity),
998 observables: HashMap::new(),
999 correlations: Array2::zeros((num_qubits, num_qubits)),
1000 higher_order_correlations: HashMap::new(),
1001 entanglement_measures: HashMap::new(),
1002 memory_metrics: MemoryMetrics::default(),
1003 time_index: 0,
1004 last_update: 0.0,
1005 activity_level: 0.0,
1006 adaptation_state: AdaptationState::default(),
1007 performance_history: VecDeque::with_capacity(memory_capacity),
1008 }
1009 }
1010
1011 pub fn update_state(&mut self, new_state: Array1<Complex64>) {
1013 self.state_history.push_back(self.state_vector.clone());
1014 if self.state_history.len() > self.state_history.capacity() {
1015 self.state_history.pop_front();
1016 }
1017 self.state_vector = new_state;
1018 self.time_index += 1;
1019 }
1020}
1021
1022#[derive(Debug, Clone)]
1024pub struct ReservoirTrainingData {
1025 pub inputs: Vec<Array1<f64>>,
1027 pub targets: Vec<Array1<f64>>,
1029 pub timestamps: Vec<f64>,
1031}
1032
1033pub struct QuantumReservoirComputer {
1035 config: QuantumReservoirConfig,
1037 reservoir_state: QuantumReservoirState,
1039 reservoir_circuit: InterfaceCircuit,
1041 input_coupling_circuit: InterfaceCircuit,
1043 output_weights: Array2<f64>,
1045 simulator: StateVectorSimulator,
1047 circuit_interface: CircuitInterface,
1049 metrics: ReservoirMetrics,
1051 training_history: VecDeque<TrainingExample>,
1053}
1054
1055#[derive(Debug, Clone)]
1057pub struct TrainingExample {
1058 pub input: Array1<f64>,
1060 pub reservoir_state: Array1<f64>,
1062 pub target: Array1<f64>,
1064 pub error: f64,
1066}
1067
1068#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1070pub struct ReservoirMetrics {
1071 pub training_examples: usize,
1073 pub prediction_accuracy: f64,
1075 pub memory_capacity: f64,
1077 pub processing_capacity: f64,
1079 pub generalization_error: f64,
1081 pub echo_state_property: f64,
1083 pub avg_processing_time_ms: f64,
1085 pub quantum_resource_usage: f64,
1087}
1088
1089impl QuantumReservoirComputer {
1090 pub fn new(config: QuantumReservoirConfig) -> Result<Self> {
1092 let circuit_interface = CircuitInterface::new(Default::default())?;
1093 let simulator = StateVectorSimulator::new();
1094
1095 let reservoir_state = QuantumReservoirState::new(config.num_qubits, config.memory_capacity);
1096
1097 let reservoir_circuit = Self::generate_reservoir_circuit(&config)?;
1099
1100 let input_coupling_circuit = Self::generate_input_coupling_circuit(&config)?;
1102
1103 let output_size = match config.output_measurement {
1105 OutputMeasurement::PauliExpectation => config.num_qubits * 3, OutputMeasurement::Probability => 1 << config.num_qubits, OutputMeasurement::Correlations => config.num_qubits * config.num_qubits,
1108 OutputMeasurement::Entanglement => config.num_qubits,
1109 OutputMeasurement::Fidelity => 1,
1110 OutputMeasurement::QuantumFisherInformation => config.num_qubits,
1111 OutputMeasurement::Variance => config.num_qubits,
1112 OutputMeasurement::HigherOrderMoments => config.num_qubits * 4,
1113 OutputMeasurement::SpectralProperties => config.num_qubits,
1114 OutputMeasurement::QuantumCoherence => config.num_qubits,
1115 _ => config.num_qubits, };
1117
1118 let feature_size = Self::calculate_feature_size(&config);
1119 let mut output_weights = Array2::zeros((output_size, feature_size));
1120
1121 let scale = (2.0 / (output_size + feature_size) as f64).sqrt();
1123 for elem in output_weights.iter_mut() {
1124 *elem = (fastrand::f64() - 0.5) * 2.0 * scale;
1125 }
1126
1127 Ok(Self {
1128 config,
1129 reservoir_state,
1130 reservoir_circuit,
1131 input_coupling_circuit,
1132 output_weights,
1133 simulator,
1134 circuit_interface,
1135 metrics: ReservoirMetrics::default(),
1136 training_history: VecDeque::with_capacity(10000),
1137 })
1138 }
1139
1140 fn generate_reservoir_circuit(config: &QuantumReservoirConfig) -> Result<InterfaceCircuit> {
1142 let mut circuit = InterfaceCircuit::new(config.num_qubits, 0);
1143
1144 match config.architecture {
1145 QuantumReservoirArchitecture::RandomCircuit => {
1146 Self::generate_random_circuit(&mut circuit, config)?;
1147 }
1148 QuantumReservoirArchitecture::SpinChain => {
1149 Self::generate_spin_chain_circuit(&mut circuit, config)?;
1150 }
1151 QuantumReservoirArchitecture::TransverseFieldIsing => {
1152 Self::generate_tfim_circuit(&mut circuit, config)?;
1153 }
1154 QuantumReservoirArchitecture::SmallWorld => {
1155 Self::generate_small_world_circuit(&mut circuit, config)?;
1156 }
1157 QuantumReservoirArchitecture::FullyConnected => {
1158 Self::generate_fully_connected_circuit(&mut circuit, config)?;
1159 }
1160 QuantumReservoirArchitecture::Custom => {
1161 Self::generate_random_circuit(&mut circuit, config)?;
1163 }
1164 QuantumReservoirArchitecture::ScaleFree => {
1165 Self::generate_small_world_circuit(&mut circuit, config)?; }
1167 QuantumReservoirArchitecture::HierarchicalModular => {
1168 Self::generate_random_circuit(&mut circuit, config)?; }
1170 QuantumReservoirArchitecture::AdaptiveTopology => {
1171 Self::generate_random_circuit(&mut circuit, config)?; }
1173 QuantumReservoirArchitecture::QuantumCellularAutomaton => {
1174 Self::generate_spin_chain_circuit(&mut circuit, config)?; }
1176 QuantumReservoirArchitecture::Ring => {
1177 Self::generate_spin_chain_circuit(&mut circuit, config)?; }
1179 _ => {
1180 Self::generate_random_circuit(&mut circuit, config)?;
1182 }
1183 }
1184
1185 Ok(circuit)
1186 }
1187
1188 fn generate_random_circuit(
1190 circuit: &mut InterfaceCircuit,
1191 config: &QuantumReservoirConfig,
1192 ) -> Result<()> {
1193 let depth = config.evolution_steps;
1194
1195 for _ in 0..depth {
1196 for qubit in 0..config.num_qubits {
1198 let angle = fastrand::f64() * 2.0 * std::f64::consts::PI;
1199 let gate_type = match fastrand::usize(0..3) {
1200 0 => InterfaceGateType::RX(angle),
1201 1 => InterfaceGateType::RY(angle),
1202 _ => InterfaceGateType::RZ(angle),
1203 };
1204 circuit.add_gate(InterfaceGate::new(gate_type, vec![qubit]));
1205 }
1206
1207 for _ in 0..(config.num_qubits / 2) {
1209 let qubit1 = fastrand::usize(0..config.num_qubits);
1210 let qubit2 = fastrand::usize(0..config.num_qubits);
1211 if qubit1 != qubit2 {
1212 circuit.add_gate(InterfaceGate::new(
1213 InterfaceGateType::CNOT,
1214 vec![qubit1, qubit2],
1215 ));
1216 }
1217 }
1218 }
1219
1220 Ok(())
1221 }
1222
1223 fn generate_spin_chain_circuit(
1225 circuit: &mut InterfaceCircuit,
1226 config: &QuantumReservoirConfig,
1227 ) -> Result<()> {
1228 let coupling = config.coupling_strength;
1229
1230 for _ in 0..config.evolution_steps {
1231 for i in 0..config.num_qubits - 1 {
1233 circuit.add_gate(InterfaceGate::new(
1235 InterfaceGateType::RZ(coupling * config.time_step),
1236 vec![i],
1237 ));
1238 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1239 circuit.add_gate(InterfaceGate::new(
1240 InterfaceGateType::RZ(coupling * config.time_step),
1241 vec![i + 1],
1242 ));
1243 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1244 }
1245 }
1246
1247 Ok(())
1248 }
1249
1250 fn generate_tfim_circuit(
1252 circuit: &mut InterfaceCircuit,
1253 config: &QuantumReservoirConfig,
1254 ) -> Result<()> {
1255 let coupling = config.coupling_strength;
1256 let field = coupling * 0.5; for _ in 0..config.evolution_steps {
1259 for qubit in 0..config.num_qubits {
1261 circuit.add_gate(InterfaceGate::new(
1262 InterfaceGateType::RX(field * config.time_step),
1263 vec![qubit],
1264 ));
1265 }
1266
1267 for i in 0..config.num_qubits - 1 {
1269 circuit.add_gate(InterfaceGate::new(
1270 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1271 vec![i],
1272 ));
1273 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1274 circuit.add_gate(InterfaceGate::new(
1275 InterfaceGateType::RZ(coupling * config.time_step),
1276 vec![i + 1],
1277 ));
1278 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, i + 1]));
1279 circuit.add_gate(InterfaceGate::new(
1280 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1281 vec![i],
1282 ));
1283 }
1284 }
1285
1286 Ok(())
1287 }
1288
1289 fn generate_small_world_circuit(
1291 circuit: &mut InterfaceCircuit,
1292 config: &QuantumReservoirConfig,
1293 ) -> Result<()> {
1294 let coupling = config.coupling_strength;
1295 let rewiring_prob = 0.1; for _ in 0..config.evolution_steps {
1298 for i in 0..config.num_qubits {
1300 let next = (i + 1) % config.num_qubits;
1301
1302 let target = if fastrand::f64() < rewiring_prob {
1304 fastrand::usize(0..config.num_qubits)
1305 } else {
1306 next
1307 };
1308
1309 if target != i {
1310 circuit.add_gate(InterfaceGate::new(
1311 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1312 vec![i],
1313 ));
1314 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, target]));
1315 circuit.add_gate(InterfaceGate::new(
1316 InterfaceGateType::RZ(coupling * config.time_step),
1317 vec![target],
1318 ));
1319 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, target]));
1320 circuit.add_gate(InterfaceGate::new(
1321 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1322 vec![i],
1323 ));
1324 }
1325 }
1326 }
1327
1328 Ok(())
1329 }
1330
1331 fn generate_fully_connected_circuit(
1333 circuit: &mut InterfaceCircuit,
1334 config: &QuantumReservoirConfig,
1335 ) -> Result<()> {
1336 let coupling = config.coupling_strength / config.num_qubits as f64; for _ in 0..config.evolution_steps {
1339 for i in 0..config.num_qubits {
1341 for j in i + 1..config.num_qubits {
1342 circuit.add_gate(InterfaceGate::new(
1343 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1344 vec![i],
1345 ));
1346 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1347 circuit.add_gate(InterfaceGate::new(
1348 InterfaceGateType::RZ(coupling * config.time_step),
1349 vec![j],
1350 ));
1351 circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![i, j]));
1352 circuit.add_gate(InterfaceGate::new(
1353 InterfaceGateType::RZ(coupling * config.time_step / 2.0),
1354 vec![i],
1355 ));
1356 }
1357 }
1358 }
1359
1360 Ok(())
1361 }
1362
1363 fn generate_input_coupling_circuit(
1365 config: &QuantumReservoirConfig,
1366 ) -> Result<InterfaceCircuit> {
1367 let mut circuit = InterfaceCircuit::new(config.num_qubits, 0);
1368
1369 match config.input_encoding {
1370 InputEncoding::Amplitude => {
1371 for qubit in 0..config.num_qubits {
1373 circuit.add_gate(InterfaceGate::new(
1374 InterfaceGateType::RY(0.0), vec![qubit],
1376 ));
1377 }
1378 }
1379 InputEncoding::Phase => {
1380 for qubit in 0..config.num_qubits {
1382 circuit.add_gate(InterfaceGate::new(
1383 InterfaceGateType::RZ(0.0), vec![qubit],
1385 ));
1386 }
1387 }
1388 InputEncoding::BasisState => {
1389 for qubit in 0..config.num_qubits {
1391 circuit.add_gate(InterfaceGate::new(InterfaceGateType::X, vec![qubit]));
1393 }
1394 }
1395 _ => {
1396 for qubit in 0..config.num_qubits {
1398 circuit.add_gate(InterfaceGate::new(InterfaceGateType::RY(0.0), vec![qubit]));
1399 }
1400 }
1401 }
1402
1403 Ok(circuit)
1404 }
1405
1406 fn calculate_feature_size(config: &QuantumReservoirConfig) -> usize {
1408 match config.output_measurement {
1409 OutputMeasurement::PauliExpectation => config.num_qubits * 3,
1410 OutputMeasurement::Probability => 1 << config.num_qubits.min(10), OutputMeasurement::Correlations => config.num_qubits * config.num_qubits,
1412 OutputMeasurement::Entanglement => config.num_qubits,
1413 OutputMeasurement::Fidelity => 1,
1414 OutputMeasurement::QuantumFisherInformation => config.num_qubits,
1415 OutputMeasurement::Variance => config.num_qubits,
1416 OutputMeasurement::HigherOrderMoments => config.num_qubits * 4,
1417 OutputMeasurement::SpectralProperties => config.num_qubits,
1418 OutputMeasurement::QuantumCoherence => config.num_qubits,
1419 _ => config.num_qubits, }
1421 }
1422
1423 pub fn process_input(&mut self, input: &Array1<f64>) -> Result<Array1<f64>> {
1425 let start_time = std::time::Instant::now();
1426
1427 self.encode_input(input)?;
1429
1430 self.evolve_reservoir()?;
1432
1433 let features = self.extract_features()?;
1435
1436 let processing_time = start_time.elapsed().as_secs_f64() * 1000.0;
1438 self.update_processing_time(processing_time);
1439
1440 Ok(features)
1441 }
1442
1443 fn encode_input(&mut self, input: &Array1<f64>) -> Result<()> {
1445 match self.config.input_encoding {
1446 InputEncoding::Amplitude => {
1447 self.encode_amplitude(input)?;
1448 }
1449 InputEncoding::Phase => {
1450 self.encode_phase(input)?;
1451 }
1452 InputEncoding::BasisState => {
1453 self.encode_basis_state(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] * std::f64::consts::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 * std::f64::consts::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 apply_single_qubit_rotation(
1501 &mut self,
1502 qubit: usize,
1503 gate_type: InterfaceGateType,
1504 ) -> Result<()> {
1505 let mut temp_circuit = InterfaceCircuit::new(self.config.num_qubits, 0);
1507 temp_circuit.add_gate(InterfaceGate::new(gate_type, vec![qubit]));
1508
1509 self.simulator.apply_interface_circuit(&temp_circuit)?;
1511
1512 Ok(())
1513 }
1514
1515 fn apply_single_qubit_gate(
1517 &mut self,
1518 qubit: usize,
1519 gate_type: InterfaceGateType,
1520 ) -> Result<()> {
1521 let mut temp_circuit = InterfaceCircuit::new(self.config.num_qubits, 0);
1522 temp_circuit.add_gate(InterfaceGate::new(gate_type, vec![qubit]));
1523
1524 self.simulator.apply_interface_circuit(&temp_circuit)?;
1525
1526 Ok(())
1527 }
1528
1529 fn evolve_reservoir(&mut self) -> Result<()> {
1531 match self.config.dynamics {
1532 ReservoirDynamics::Unitary => {
1533 self.evolve_unitary()?;
1534 }
1535 ReservoirDynamics::Open => {
1536 self.evolve_open_system()?;
1537 }
1538 ReservoirDynamics::NISQ => {
1539 self.evolve_nisq()?;
1540 }
1541 ReservoirDynamics::Adiabatic => {
1542 self.evolve_adiabatic()?;
1543 }
1544 ReservoirDynamics::Floquet => {
1545 self.evolve_unitary()?; }
1547 ReservoirDynamics::QuantumWalk => {
1548 self.evolve_unitary()?; }
1550 ReservoirDynamics::ContinuousTime => {
1551 self.evolve_open_system()?; }
1553 ReservoirDynamics::DigitalQuantum => {
1554 self.evolve_unitary()?; }
1556 ReservoirDynamics::Variational => {
1557 self.evolve_unitary()?; }
1559 ReservoirDynamics::HamiltonianLearning => {
1560 self.evolve_unitary()?; }
1562 ReservoirDynamics::ManyBodyLocalized => {
1563 self.evolve_unitary()?; }
1565 ReservoirDynamics::QuantumChaotic => {
1566 self.evolve_unitary()?; }
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 apply_decoherence(&mut self) -> Result<()> {
1614 let decoherence_rate = self.config.noise_level;
1615
1616 for amplitude in self.reservoir_state.state_vector.iter_mut() {
1617 let phase_noise =
1619 (fastrand::f64() - 0.5) * decoherence_rate * 2.0 * std::f64::consts::PI;
1620 *amplitude *= Complex64::new(0.0, phase_noise).exp();
1621
1622 let damping = (1.0 - decoherence_rate).sqrt();
1624 *amplitude *= damping;
1625 }
1626
1627 let norm: f64 = self
1629 .reservoir_state
1630 .state_vector
1631 .iter()
1632 .map(|x| x.norm_sqr())
1633 .sum::<f64>()
1634 .sqrt();
1635
1636 if norm > 1e-15 {
1637 self.reservoir_state.state_vector.mapv_inplace(|x| x / norm);
1638 }
1639
1640 Ok(())
1641 }
1642
1643 fn apply_gate_errors(&mut self) -> Result<()> {
1645 let error_rate = self.config.noise_level;
1646
1647 for qubit in 0..self.config.num_qubits {
1648 if fastrand::f64() < error_rate {
1649 let error_type = fastrand::usize(0..3);
1650 let gate_type = match error_type {
1651 0 => InterfaceGateType::X,
1652 1 => InterfaceGateType::PauliY,
1653 _ => InterfaceGateType::PauliZ,
1654 };
1655 self.apply_single_qubit_gate(qubit, gate_type)?;
1656 }
1657 }
1658
1659 Ok(())
1660 }
1661
1662 fn apply_measurement_errors(&mut self) -> Result<()> {
1664 let error_rate = self.config.noise_level * 0.1; if fastrand::f64() < error_rate {
1668 let qubit = fastrand::usize(0..self.config.num_qubits);
1670 self.apply_single_qubit_gate(qubit, InterfaceGateType::X)?;
1671 }
1672
1673 Ok(())
1674 }
1675
1676 fn extract_features(&mut self) -> Result<Array1<f64>> {
1678 match self.config.output_measurement {
1679 OutputMeasurement::PauliExpectation => self.measure_pauli_expectations(),
1680 OutputMeasurement::Probability => self.measure_probabilities(),
1681 OutputMeasurement::Correlations => self.measure_correlations(),
1682 OutputMeasurement::Entanglement => self.measure_entanglement(),
1683 OutputMeasurement::Fidelity => self.measure_fidelity(),
1684 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(), }
1691 }
1692
1693 fn measure_pauli_expectations(&self) -> Result<Array1<f64>> {
1695 let mut expectations = Vec::new();
1696
1697 for qubit in 0..self.config.num_qubits {
1698 let x_exp = self.calculate_single_qubit_expectation(
1700 qubit,
1701 &[
1702 Complex64::new(0.0, 0.0),
1703 Complex64::new(1.0, 0.0),
1704 Complex64::new(1.0, 0.0),
1705 Complex64::new(0.0, 0.0),
1706 ],
1707 )?;
1708 expectations.push(x_exp);
1709
1710 let y_exp = self.calculate_single_qubit_expectation(
1712 qubit,
1713 &[
1714 Complex64::new(0.0, 0.0),
1715 Complex64::new(0.0, -1.0),
1716 Complex64::new(0.0, 1.0),
1717 Complex64::new(0.0, 0.0),
1718 ],
1719 )?;
1720 expectations.push(y_exp);
1721
1722 let z_exp = self.calculate_single_qubit_expectation(
1724 qubit,
1725 &[
1726 Complex64::new(1.0, 0.0),
1727 Complex64::new(0.0, 0.0),
1728 Complex64::new(0.0, 0.0),
1729 Complex64::new(-1.0, 0.0),
1730 ],
1731 )?;
1732 expectations.push(z_exp);
1733 }
1734
1735 Ok(Array1::from_vec(expectations))
1736 }
1737
1738 fn calculate_single_qubit_expectation(
1740 &self,
1741 qubit: usize,
1742 pauli_matrix: &[Complex64; 4],
1743 ) -> Result<f64> {
1744 let state = &self.reservoir_state.state_vector;
1745 let mut expectation = 0.0;
1746
1747 for i in 0..state.len() {
1748 for j in 0..state.len() {
1749 let i_bit = (i >> qubit) & 1;
1750 let j_bit = (j >> qubit) & 1;
1751 let matrix_element = pauli_matrix[i_bit * 2 + j_bit];
1752
1753 expectation += (state[i].conj() * matrix_element * state[j]).re;
1754 }
1755 }
1756
1757 Ok(expectation)
1758 }
1759
1760 fn measure_probabilities(&self) -> Result<Array1<f64>> {
1762 let probabilities: Vec<f64> = self
1763 .reservoir_state
1764 .state_vector
1765 .iter()
1766 .map(|x| x.norm_sqr())
1767 .collect();
1768
1769 let max_size = 1 << 10; if probabilities.len() > max_size {
1772 let mut sampled = Vec::with_capacity(max_size);
1774 for _ in 0..max_size {
1775 let idx = fastrand::usize(0..probabilities.len());
1776 sampled.push(probabilities[idx]);
1777 }
1778 Ok(Array1::from_vec(sampled))
1779 } else {
1780 Ok(Array1::from_vec(probabilities))
1781 }
1782 }
1783
1784 fn measure_correlations(&mut self) -> Result<Array1<f64>> {
1786 let mut correlations = Vec::new();
1787
1788 for i in 0..self.config.num_qubits {
1789 for j in 0..self.config.num_qubits {
1790 if i != j {
1791 let corr = self.calculate_two_qubit_correlation(i, j)?;
1793 correlations.push(corr);
1794 self.reservoir_state.correlations[[i, j]] = corr;
1795 } else {
1796 correlations.push(1.0); self.reservoir_state.correlations[[i, j]] = 1.0;
1798 }
1799 }
1800 }
1801
1802 Ok(Array1::from_vec(correlations))
1803 }
1804
1805 fn calculate_two_qubit_correlation(&self, qubit1: usize, qubit2: usize) -> Result<f64> {
1807 let state = &self.reservoir_state.state_vector;
1808 let mut correlation = 0.0;
1809
1810 for i in 0..state.len() {
1811 let bit1 = (i >> qubit1) & 1;
1812 let bit2 = (i >> qubit2) & 1;
1813 let sign = if bit1 == bit2 { 1.0 } else { -1.0 };
1814 correlation += sign * state[i].norm_sqr();
1815 }
1816
1817 Ok(correlation)
1818 }
1819
1820 fn measure_entanglement(&self) -> Result<Array1<f64>> {
1822 let mut entanglement_measures = Vec::new();
1823
1824 for qubit in 0..self.config.num_qubits {
1826 let entropy = self.calculate_von_neumann_entropy(qubit)?;
1828 entanglement_measures.push(entropy);
1829 }
1830
1831 Ok(Array1::from_vec(entanglement_measures))
1832 }
1833
1834 fn calculate_von_neumann_entropy(&self, _qubit: usize) -> Result<f64> {
1836 let state = &self.reservoir_state.state_vector;
1838 let mut entropy = 0.0;
1839
1840 for amplitude in state.iter() {
1841 let prob = amplitude.norm_sqr();
1842 if prob > 1e-15 {
1843 entropy -= prob * prob.ln();
1844 }
1845 }
1846
1847 Ok(entropy / (state.len() as f64).ln()) }
1849
1850 fn measure_fidelity(&self) -> Result<Array1<f64>> {
1852 let fidelity = self.reservoir_state.state_vector[0].norm_sqr();
1854 Ok(Array1::from_vec(vec![fidelity]))
1855 }
1856
1857 pub fn train(&mut self, training_data: &ReservoirTrainingData) -> Result<TrainingResult> {
1859 let start_time = std::time::Instant::now();
1860
1861 let mut all_features = Vec::new();
1862 let mut all_targets = Vec::new();
1863
1864 for i in 0..self.config.washout_period.min(training_data.inputs.len()) {
1866 let _ = self.process_input(&training_data.inputs[i])?;
1867 }
1868
1869 for i in self.config.washout_period..training_data.inputs.len() {
1871 let features = self.process_input(&training_data.inputs[i])?;
1872 all_features.push(features);
1873
1874 if i < training_data.targets.len() {
1875 all_targets.push(training_data.targets[i].clone());
1876 }
1877 }
1878
1879 self.train_output_weights(&all_features, &all_targets)?;
1881
1882 let (training_error, test_error) =
1884 self.evaluate_performance(&all_features, &all_targets)?;
1885
1886 let training_time = start_time.elapsed().as_secs_f64() * 1000.0;
1887
1888 self.metrics.training_examples += all_features.len();
1890 self.metrics.generalization_error = test_error;
1891
1892 Ok(TrainingResult {
1893 training_error,
1894 test_error,
1895 training_time_ms: training_time,
1896 num_examples: all_features.len(),
1897 echo_state_property: self.estimate_echo_state_property()?,
1898 })
1899 }
1900
1901 fn train_output_weights(
1903 &mut self,
1904 features: &[Array1<f64>],
1905 targets: &[Array1<f64>],
1906 ) -> Result<()> {
1907 if features.is_empty() || targets.is_empty() {
1908 return Ok(());
1909 }
1910
1911 let n_samples = features.len().min(targets.len());
1912 let n_features = features[0].len();
1913 let n_outputs = targets[0].len().min(self.output_weights.nrows());
1914
1915 let mut feature_matrix = Array2::zeros((n_samples, n_features));
1917 for (i, feature_vec) in features.iter().enumerate().take(n_samples) {
1918 for (j, &val) in feature_vec.iter().enumerate().take(n_features) {
1919 feature_matrix[[i, j]] = val;
1920 }
1921 }
1922
1923 let mut target_matrix = Array2::zeros((n_samples, n_outputs));
1925 for (i, target_vec) in targets.iter().enumerate().take(n_samples) {
1926 for (j, &val) in target_vec.iter().enumerate().take(n_outputs) {
1927 target_matrix[[i, j]] = val;
1928 }
1929 }
1930
1931 let lambda = 1e-6; let xtx = feature_matrix.t().dot(&feature_matrix);
1936
1937 let mut xtx_reg = xtx;
1939 for i in 0..xtx_reg.nrows().min(xtx_reg.ncols()) {
1940 xtx_reg[[i, i]] += lambda;
1941 }
1942
1943 let xty = feature_matrix.t().dot(&target_matrix);
1945
1946 self.solve_linear_system(&xtx_reg, &xty)?;
1949
1950 Ok(())
1951 }
1952
1953 fn solve_linear_system(&mut self, a: &Array2<f64>, b: &Array2<f64>) -> Result<()> {
1955 let min_dim = a.nrows().min(a.ncols()).min(b.nrows());
1959
1960 for i in 0..min_dim.min(self.output_weights.nrows()) {
1961 for j in 0..b.ncols().min(self.output_weights.ncols()) {
1962 if a[[i, i]].abs() > 1e-15 {
1963 self.output_weights[[i, j]] = b[[i, j]] / a[[i, i]];
1964 }
1965 }
1966 }
1967
1968 Ok(())
1969 }
1970
1971 fn evaluate_performance(
1973 &self,
1974 features: &[Array1<f64>],
1975 targets: &[Array1<f64>],
1976 ) -> Result<(f64, f64)> {
1977 if features.is_empty() || targets.is_empty() {
1978 return Ok((0.0, 0.0));
1979 }
1980
1981 let mut total_error = 0.0;
1982 let n_samples = features.len().min(targets.len());
1983
1984 for i in 0..n_samples {
1985 let prediction = self.predict_output(&features[i])?;
1986 let error = self.calculate_prediction_error(&prediction, &targets[i]);
1987 total_error += error;
1988 }
1989
1990 let training_error = total_error / n_samples as f64;
1991
1992 let test_error = training_error;
1994
1995 Ok((training_error, test_error))
1996 }
1997
1998 fn predict_output(&self, features: &Array1<f64>) -> Result<Array1<f64>> {
2000 let feature_size = features.len().min(self.output_weights.ncols());
2001 let output_size = self.output_weights.nrows();
2002
2003 let mut output = Array1::zeros(output_size);
2004
2005 for i in 0..output_size {
2006 for j in 0..feature_size {
2007 output[i] += self.output_weights[[i, j]] * features[j];
2008 }
2009 }
2010
2011 Ok(output)
2012 }
2013
2014 fn calculate_prediction_error(&self, prediction: &Array1<f64>, target: &Array1<f64>) -> f64 {
2016 let min_len = prediction.len().min(target.len());
2017 let mut error = 0.0;
2018
2019 for i in 0..min_len {
2020 let diff = prediction[i] - target[i];
2021 error += diff * diff;
2022 }
2023
2024 (error / min_len as f64).sqrt() }
2026
2027 fn estimate_echo_state_property(&self) -> Result<f64> {
2029 let coupling = self.config.coupling_strength;
2033 let estimated_spectral_radius = coupling.tanh(); Ok(if estimated_spectral_radius < 1.0 {
2037 1.0
2038 } else {
2039 1.0 / estimated_spectral_radius
2040 })
2041 }
2042
2043 fn update_processing_time(&mut self, time_ms: f64) {
2045 let count = self.metrics.training_examples as f64;
2046 self.metrics.avg_processing_time_ms =
2047 (self.metrics.avg_processing_time_ms * count + time_ms) / (count + 1.0);
2048 }
2049
2050 pub fn get_metrics(&self) -> &ReservoirMetrics {
2052 &self.metrics
2053 }
2054
2055 pub fn reset(&mut self) -> Result<()> {
2057 self.reservoir_state =
2058 QuantumReservoirState::new(self.config.num_qubits, self.config.memory_capacity);
2059 self.metrics = ReservoirMetrics::default();
2060 self.training_history.clear();
2061 Ok(())
2062 }
2063}
2064
2065#[derive(Debug, Clone, Serialize, Deserialize)]
2067pub struct TrainingResult {
2068 pub training_error: f64,
2070 pub test_error: f64,
2072 pub training_time_ms: f64,
2074 pub num_examples: usize,
2076 pub echo_state_property: f64,
2078}
2079
2080pub fn benchmark_quantum_reservoir_computing() -> Result<HashMap<String, f64>> {
2082 let mut results = HashMap::new();
2083
2084 let configs = [
2086 QuantumReservoirConfig {
2087 num_qubits: 6,
2088 architecture: QuantumReservoirArchitecture::RandomCircuit,
2089 ..Default::default()
2090 },
2091 QuantumReservoirConfig {
2092 num_qubits: 8,
2093 architecture: QuantumReservoirArchitecture::SpinChain,
2094 ..Default::default()
2095 },
2096 QuantumReservoirConfig {
2097 num_qubits: 6,
2098 architecture: QuantumReservoirArchitecture::TransverseFieldIsing,
2099 ..Default::default()
2100 },
2101 ];
2102
2103 for (i, config) in configs.iter().enumerate() {
2104 let start = std::time::Instant::now();
2105
2106 let mut qrc = QuantumReservoirComputer::new(config.clone())?;
2107
2108 let training_data = ReservoirTrainingData {
2110 inputs: (0..100)
2111 .map(|i| Array1::from_vec(vec![(i as f64 * 0.1).sin(), (i as f64 * 0.1).cos()]))
2112 .collect(),
2113 targets: (0..100)
2114 .map(|i| Array1::from_vec(vec![(i as f64 * 0.1 + 1.0).sin()]))
2115 .collect(),
2116 timestamps: (0..100).map(|i| i as f64 * 0.1).collect(),
2117 };
2118
2119 let _training_result = qrc.train(&training_data)?;
2121
2122 let time = start.elapsed().as_secs_f64() * 1000.0;
2123 results.insert(format!("config_{}", i), time);
2124
2125 let metrics = qrc.get_metrics();
2127 results.insert(
2128 format!("config_{}_accuracy", i),
2129 metrics.prediction_accuracy,
2130 );
2131 results.insert(format!("config_{}_memory", i), metrics.memory_capacity);
2132 }
2133
2134 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)
2140}
2141
2142#[cfg(test)]
2143mod tests {
2144 use super::*;
2145
2146 #[test]
2147 fn test_quantum_reservoir_creation() {
2148 let config = QuantumReservoirConfig::default();
2149 let qrc = QuantumReservoirComputer::new(config);
2150 assert!(qrc.is_ok());
2151 }
2152
2153 #[test]
2154 fn test_reservoir_state_creation() {
2155 let state = QuantumReservoirState::new(3, 10);
2156 assert_eq!(state.state_vector.len(), 8); assert_eq!(state.state_history.capacity(), 10);
2158 assert_eq!(state.time_index, 0);
2159 }
2160
2161 #[test]
2162 fn test_input_processing() {
2163 let config = QuantumReservoirConfig {
2164 num_qubits: 3,
2165 evolution_steps: 2,
2166 ..Default::default()
2167 };
2168 let mut qrc = QuantumReservoirComputer::new(config).unwrap();
2169
2170 let input = Array1::from_vec(vec![0.5, 0.3, 0.8]);
2171 let result = qrc.process_input(&input);
2172 assert!(result.is_ok());
2173
2174 let features = result.unwrap();
2175 assert!(!features.is_empty());
2176 }
2177
2178 #[test]
2179 fn test_different_architectures() {
2180 let architectures = [
2181 QuantumReservoirArchitecture::RandomCircuit,
2182 QuantumReservoirArchitecture::SpinChain,
2183 QuantumReservoirArchitecture::TransverseFieldIsing,
2184 ];
2185
2186 for arch in architectures {
2187 let config = QuantumReservoirConfig {
2188 num_qubits: 4,
2189 architecture: arch,
2190 evolution_steps: 2,
2191 ..Default::default()
2192 };
2193
2194 let qrc = QuantumReservoirComputer::new(config);
2195 assert!(qrc.is_ok(), "Failed for architecture: {:?}", arch);
2196 }
2197 }
2198
2199 #[test]
2200 fn test_feature_extraction() {
2201 let config = QuantumReservoirConfig {
2202 num_qubits: 3,
2203 output_measurement: OutputMeasurement::PauliExpectation,
2204 ..Default::default()
2205 };
2206 let mut qrc = QuantumReservoirComputer::new(config).unwrap();
2207
2208 let features = qrc.extract_features().unwrap();
2209 assert_eq!(features.len(), 9); }
2211
2212 #[test]
2213 fn test_training_data() {
2214 let training_data = ReservoirTrainingData {
2215 inputs: vec![
2216 Array1::from_vec(vec![0.1, 0.2]),
2217 Array1::from_vec(vec![0.3, 0.4]),
2218 ],
2219 targets: vec![Array1::from_vec(vec![0.5]), Array1::from_vec(vec![0.6])],
2220 timestamps: vec![0.0, 1.0],
2221 };
2222
2223 assert_eq!(training_data.inputs.len(), 2);
2224 assert_eq!(training_data.targets.len(), 2);
2225 assert_eq!(training_data.timestamps.len(), 2);
2226 }
2227
2228 #[test]
2229 fn test_encoding_methods() {
2230 let config = QuantumReservoirConfig {
2231 num_qubits: 3,
2232 input_encoding: InputEncoding::Amplitude,
2233 ..Default::default()
2234 };
2235 let mut qrc = QuantumReservoirComputer::new(config).unwrap();
2236
2237 let input = Array1::from_vec(vec![0.5, 0.3]);
2238 let result = qrc.encode_input(&input);
2239 assert!(result.is_ok());
2240 }
2241
2242 #[test]
2243 fn test_measurement_strategies() {
2244 let measurements = [
2245 OutputMeasurement::PauliExpectation,
2246 OutputMeasurement::Probability,
2247 OutputMeasurement::Correlations,
2248 OutputMeasurement::Entanglement,
2249 OutputMeasurement::Fidelity,
2250 ];
2251
2252 for measurement in measurements {
2253 let config = QuantumReservoirConfig {
2254 num_qubits: 3,
2255 output_measurement: measurement,
2256 ..Default::default()
2257 };
2258
2259 let qrc = QuantumReservoirComputer::new(config);
2260 assert!(qrc.is_ok(), "Failed for measurement: {:?}", measurement);
2261 }
2262 }
2263
2264 #[test]
2265 fn test_reservoir_dynamics() {
2266 let dynamics = [
2267 ReservoirDynamics::Unitary,
2268 ReservoirDynamics::Open,
2269 ReservoirDynamics::NISQ,
2270 ];
2271
2272 for dynamic in dynamics {
2273 let config = QuantumReservoirConfig {
2274 num_qubits: 3,
2275 dynamics: dynamic,
2276 evolution_steps: 1,
2277 ..Default::default()
2278 };
2279
2280 let mut qrc = QuantumReservoirComputer::new(config).unwrap();
2281 let result = qrc.evolve_reservoir();
2282 assert!(result.is_ok(), "Failed for dynamics: {:?}", dynamic);
2283 }
2284 }
2285
2286 #[test]
2287 fn test_metrics_tracking() {
2288 let config = QuantumReservoirConfig::default();
2289 let qrc = QuantumReservoirComputer::new(config).unwrap();
2290
2291 let metrics = qrc.get_metrics();
2292 assert_eq!(metrics.training_examples, 0);
2293 assert_eq!(metrics.prediction_accuracy, 0.0);
2294 }
2295}