1use crate::error::Result;
8use crate::optimizers::Optimizer;
9use scirs2_core::ndarray::{Array1, Array2, ArrayBase, Data, DataMut, Dimension};
10use scirs2_core::numeric::Float;
11use std::collections::{HashMap, VecDeque};
12use std::fmt::Debug;
13use std::time::{Duration, Instant};
14
15pub mod energy_efficient;
16pub mod event_driven;
17pub mod spike_based;
18
19pub use energy_efficient::{EnergyBudget, EnergyEfficientOptimizer, EnergyOptimizationStrategy};
21pub use event_driven::{EventDrivenConfig, EventDrivenOptimizer, EventType};
22pub use spike_based::{SpikeTrainOptimizer, SpikingConfig, SpikingOptimizer};
23
24#[derive(Debug, Clone)]
26#[allow(dead_code)]
27pub enum NeuromorphicPlatform {
28 IntelLoihi,
30
31 SpiNNaker,
33
34 IBMTrueNorth,
36
37 BrainChipAkida,
39
40 Research,
42
43 Custom(String),
45}
46
47#[derive(Debug, Clone)]
49#[allow(dead_code)]
50pub struct NeuromorphicConfig<T: Float + Debug + Send + Sync + 'static> {
51 pub platform: NeuromorphicPlatform,
53
54 pub spike_config: SpikingConfig<T>,
56
57 pub event_config: EventDrivenConfig<T>,
59
60 pub energy_config: EnergyOptimizationConfig<T>,
62
63 pub temporal_coding: bool,
65
66 pub rate_coding: bool,
68
69 pub stdp_config: STDPConfig<T>,
71
72 pub membrane_dynamics: MembraneDynamicsConfig<T>,
74
75 pub plasticity_model: PlasticityModel,
77
78 pub homeostatic_plasticity: bool,
80
81 pub metaplasticity: bool,
83
84 pub population_config: PopulationConfig,
86}
87
88#[derive(Debug, Clone)]
90pub struct STDPConfig<T: Float + Debug + Send + Sync + 'static> {
91 pub learning_rate_pot: T,
93
94 pub learning_rate_dep: T,
96
97 pub tau_pot: T,
99
100 pub tau_dep: T,
102
103 pub weight_max: T,
105
106 pub weight_min: T,
108
109 pub enable_triplet: bool,
111
112 pub triplet_learning_rate: T,
114}
115
116#[derive(Debug, Clone)]
118pub struct MembraneDynamicsConfig<T: Float + Debug + Send + Sync + 'static> {
119 pub tau_membrane: T,
121
122 pub resting_potential: T,
124
125 pub threshold_potential: T,
127
128 pub reset_potential: T,
130
131 pub refractory_period: T,
133
134 pub capacitance: T,
136
137 pub leak_conductance: T,
139
140 pub adaptive_threshold: bool,
142
143 pub threshold_adaptation_tau: T,
145}
146
147#[derive(Debug, Clone, Copy)]
149#[allow(dead_code)]
150pub enum PlasticityModel {
151 Hebbian,
153
154 AntiHebbian,
156
157 STDP,
159
160 TripletSTDP,
162
163 VoltageDependentSTDP,
165
166 CalciumBased,
168
169 BCM,
171
172 Oja,
174}
175
176#[derive(Debug, Clone)]
178pub struct PopulationConfig {
179 pub population_size: usize,
181
182 pub lateral_inhibition: bool,
184
185 pub inhibition_strength: f64,
187
188 pub winner_take_all: bool,
190
191 pub coding_strategy: PopulationCodingStrategy,
193
194 pub enable_bursting: bool,
196
197 pub synchronization: SynchronizationMechanism,
199}
200
201#[derive(Debug, Clone, Copy)]
203#[allow(dead_code)]
204pub enum PopulationCodingStrategy {
205 Distributed,
207
208 Sparse,
210
211 Local,
213
214 Vector,
216
217 RankOrder,
219}
220
221#[derive(Debug, Clone, Copy)]
223#[allow(dead_code)]
224pub enum SynchronizationMechanism {
225 None,
227
228 GlobalClock,
230
231 PhaseLocked,
233
234 Adaptive,
236
237 NetworkOscillations,
239}
240
241#[derive(Debug, Clone)]
243#[allow(dead_code)]
244pub struct EnergyOptimizationConfig<T: Float + Debug + Send + Sync + 'static> {
245 pub energy_budget: T,
247
248 pub strategy: EnergyOptimizationStrategy,
250
251 pub dynamic_voltage_scaling: bool,
253
254 pub clock_gating: bool,
256
257 pub power_gating: bool,
259
260 pub sleep_mode_config: SleepModeConfig<T>,
262
263 pub monitoring_frequency: Duration,
265
266 pub thermal_management: ThermalManagementConfig<T>,
268}
269
270#[derive(Debug, Clone)]
272#[allow(dead_code)]
273pub struct SleepModeConfig<T: Float + Debug + Send + Sync + 'static> {
274 pub enable_sleep_mode: bool,
276
277 pub sleep_threshold: Duration,
279
280 pub wakeup_time: T,
282
283 pub sleep_power: T,
285
286 pub wakeup_energy: T,
288}
289
290#[derive(Debug, Clone)]
292#[allow(dead_code)]
293pub struct ThermalManagementConfig<T: Float + Debug + Send + Sync + 'static> {
294 pub enable_thermal_management: bool,
296
297 pub target_temperature: T,
299
300 pub max_temperature: T,
302
303 pub thermal_time_constant: T,
305
306 pub throttling_strategy: ThermalThrottlingStrategy,
308}
309
310#[derive(Debug, Clone, Copy)]
312#[allow(dead_code)]
313pub enum ThermalThrottlingStrategy {
314 FrequencyScaling,
316
317 VoltageScaling,
319
320 ActivityReduction,
322
323 SelectiveShutdown,
325
326 DynamicLoadBalancing,
328}
329
330#[derive(Debug, Clone)]
332#[allow(dead_code)]
333pub struct Spike<T: Float + Debug + Send + Sync + 'static> {
334 pub neuron_id: usize,
336
337 pub time: T,
339
340 pub amplitude: T,
342
343 pub width: Option<T>,
345
346 pub weight: T,
348
349 pub presynaptic_id: Option<usize>,
351
352 pub postsynaptic_id: Option<usize>,
354}
355
356#[derive(Debug, Clone)]
358pub struct SpikeTrain<T: Float + Debug + Send + Sync + 'static> {
359 pub neuron_id: usize,
361
362 pub spike_times: Vec<T>,
364
365 pub inter_spike_intervals: Vec<T>,
367
368 pub firing_rate: T,
370
371 pub duration: T,
373
374 pub spike_count: usize,
376}
377
378impl<T: Float + Debug + Send + Sync + 'static + std::iter::Sum> SpikeTrain<T> {
379 pub fn new(neuron_id: usize, spike_times: Vec<T>) -> Self {
381 let spike_count = spike_times.len();
382 let duration = if spike_count > 0 {
383 spike_times[spike_count - 1] - spike_times[0]
384 } else {
385 T::zero()
386 };
387
388 let firing_rate = if duration > T::zero() {
389 T::from(spike_count).unwrap_or_else(|| T::zero())
390 / (duration / T::from(1000.0).unwrap_or_else(|| T::zero()))
391 } else {
392 T::zero()
393 };
394
395 let inter_spike_intervals = if spike_count > 1 {
396 spike_times.windows(2).map(|w| w[1] - w[0]).collect()
397 } else {
398 Vec::new()
399 };
400
401 Self {
402 neuron_id,
403 spike_times,
404 inter_spike_intervals,
405 firing_rate,
406 duration,
407 spike_count,
408 }
409 }
410
411 pub fn coefficient_of_variation(&self) -> T {
413 if self.inter_spike_intervals.len() < 2 {
414 return T::zero();
415 }
416
417 let mean = self.inter_spike_intervals.iter().cloned().sum::<T>()
418 / T::from(self.inter_spike_intervals.len()).unwrap();
419
420 let variance = self
421 .inter_spike_intervals
422 .iter()
423 .map(|&isi| (isi - mean) * (isi - mean))
424 .sum::<T>()
425 / T::from(self.inter_spike_intervals.len()).unwrap();
426
427 variance.sqrt() / mean
428 }
429
430 pub fn local_variation(&self) -> T {
432 if self.inter_spike_intervals.len() < 2 {
433 return T::zero();
434 }
435
436 let mut lv_sum = T::zero();
437 for window in self.inter_spike_intervals.windows(2) {
438 let isi1 = window[0];
439 let isi2 = window[1];
440 let diff = isi1 - isi2;
441 let sum = isi1 + isi2;
442
443 if sum > T::zero() {
444 lv_sum = lv_sum + (diff * diff) / (sum * sum);
445 }
446 }
447
448 let three = T::from(3.0).unwrap_or_else(|| T::zero());
449 three * lv_sum / T::from(self.inter_spike_intervals.len() - 1).unwrap()
450 }
451}
452
453#[derive(Debug, Clone)]
455#[allow(dead_code)]
456pub struct NeuromorphicEvent<T: Float + Debug + Send + Sync + 'static> {
457 pub event_type: EventType,
459
460 pub timestamp: T,
462
463 pub source_neuron: usize,
465
466 pub target_neuron: Option<usize>,
468
469 pub value: T,
471
472 pub energy_cost: T,
474
475 pub priority: EventPriority,
477}
478
479#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
481#[allow(dead_code)]
482pub enum EventPriority {
483 Low,
484 Normal,
485 High,
486 Critical,
487 RealTime,
488}
489
490#[derive(Debug, Clone)]
492pub struct NeuromorphicMetrics<T: Float + Debug + Send + Sync + 'static> {
493 pub total_spikes: usize,
495
496 pub average_firing_rate: T,
498
499 pub energy_consumption: T,
501
502 pub power_consumption: T,
504
505 pub timing_precision: T,
507
508 pub synaptic_ops_per_sec: T,
510
511 pub plasticity_events_per_sec: T,
513
514 pub memory_bandwidth_utilization: T,
516
517 pub thermal_efficiency: T,
519
520 pub network_synchronization: T,
522}
523
524impl<T: Float + Debug + Send + Sync + 'static> Default for NeuromorphicMetrics<T> {
525 fn default() -> Self {
526 Self {
527 total_spikes: 0,
528 average_firing_rate: T::zero(),
529 energy_consumption: T::zero(),
530 power_consumption: T::zero(),
531 timing_precision: T::from(0.1).unwrap_or_else(|| T::zero()), synaptic_ops_per_sec: T::zero(),
533 plasticity_events_per_sec: T::zero(),
534 memory_bandwidth_utilization: T::zero(),
535 thermal_efficiency: T::one(),
536 network_synchronization: T::zero(),
537 }
538 }
539}
540
541impl<T: Float + Debug + Send + Sync + 'static> Default for NeuromorphicConfig<T> {
542 fn default() -> Self {
543 Self {
544 platform: NeuromorphicPlatform::IntelLoihi,
545 spike_config: SpikingConfig::default(),
546 event_config: EventDrivenConfig::default(),
547 energy_config: EnergyOptimizationConfig::default(),
548 temporal_coding: true,
549 rate_coding: false,
550 stdp_config: STDPConfig::default(),
551 membrane_dynamics: MembraneDynamicsConfig::default(),
552 plasticity_model: PlasticityModel::STDP,
553 homeostatic_plasticity: false,
554 metaplasticity: false,
555 population_config: PopulationConfig::default(),
556 }
557 }
558}
559
560impl<T: Float + Debug + Send + Sync + 'static> Default for STDPConfig<T> {
561 fn default() -> Self {
562 Self {
563 learning_rate_pot: T::from(0.01).unwrap_or_else(|| T::zero()),
564 learning_rate_dep: T::from(0.01).unwrap_or_else(|| T::zero()),
565 tau_pot: T::from(20.0).unwrap_or_else(|| T::zero()),
566 tau_dep: T::from(20.0).unwrap_or_else(|| T::zero()),
567 weight_max: T::one(),
568 weight_min: T::zero(),
569 enable_triplet: false,
570 triplet_learning_rate: T::from(0.001).unwrap_or_else(|| T::zero()),
571 }
572 }
573}
574
575impl<T: Float + Debug + Send + Sync + 'static> Default for MembraneDynamicsConfig<T> {
576 fn default() -> Self {
577 Self {
578 tau_membrane: T::from(20.0).unwrap_or_else(|| T::zero()),
579 resting_potential: T::from(-70.0).unwrap_or_else(|| T::zero()),
580 threshold_potential: T::from(-55.0).unwrap_or_else(|| T::zero()),
581 reset_potential: T::from(-80.0).unwrap_or_else(|| T::zero()),
582 refractory_period: T::from(2.0).unwrap_or_else(|| T::zero()),
583 capacitance: T::from(100.0).unwrap_or_else(|| T::zero()),
584 leak_conductance: T::from(10.0).unwrap_or_else(|| T::zero()),
585 adaptive_threshold: false,
586 threshold_adaptation_tau: T::from(100.0).unwrap_or_else(|| T::zero()),
587 }
588 }
589}
590
591impl Default for PopulationConfig {
592 fn default() -> Self {
593 Self {
594 population_size: 1000,
595 lateral_inhibition: false,
596 inhibition_strength: 0.1,
597 winner_take_all: false,
598 coding_strategy: PopulationCodingStrategy::Distributed,
599 enable_bursting: false,
600 synchronization: SynchronizationMechanism::None,
601 }
602 }
603}
604
605impl<T: Float + Debug + Send + Sync + 'static> Default for EnergyOptimizationConfig<T> {
606 fn default() -> Self {
607 Self {
608 energy_budget: T::from(10.0).unwrap_or_else(|| T::zero()), strategy: EnergyOptimizationStrategy::DynamicVoltageScaling,
610 dynamic_voltage_scaling: true,
611 clock_gating: true,
612 power_gating: false,
613 sleep_mode_config: SleepModeConfig::default(),
614 monitoring_frequency: Duration::from_millis(100),
615 thermal_management: ThermalManagementConfig::default(),
616 }
617 }
618}
619
620impl<T: Float + Debug + Send + Sync + 'static> Default for SleepModeConfig<T> {
621 fn default() -> Self {
622 Self {
623 enable_sleep_mode: true,
624 sleep_threshold: Duration::from_millis(100),
625 wakeup_time: T::from(1.0).unwrap_or_else(|| T::zero()),
626 sleep_power: T::from(0.1).unwrap_or_else(|| T::zero()),
627 wakeup_energy: T::from(0.01).unwrap_or_else(|| T::zero()),
628 }
629 }
630}
631
632impl<T: Float + Debug + Send + Sync + 'static> Default for ThermalManagementConfig<T> {
633 fn default() -> Self {
634 Self {
635 enable_thermal_management: true,
636 target_temperature: T::from(65.0).unwrap_or_else(|| T::zero()),
637 max_temperature: T::from(85.0).unwrap_or_else(|| T::zero()),
638 thermal_time_constant: T::from(10.0).unwrap_or_else(|| T::zero()),
639 throttling_strategy: ThermalThrottlingStrategy::FrequencyScaling,
640 }
641 }
642}