sc_neurocore_engine/neurons/hardware/
brainscales_adex.rs1#[derive(Clone, Debug)]
11pub struct BrainScaleSAdExNeuron {
12 pub v: f64,
13 pub w: f64,
14 pub v_rest: f64,
15 pub v_reset: f64,
16 pub v_threshold: f64,
17 pub delta_t: f64,
18 pub v_rh: f64,
19 pub tau: f64,
20 pub tau_w: f64,
21 pub a: f64,
22 pub b: f64,
23 pub hw_speedup: f64,
24 pub dt: f64,
25}
26
27impl BrainScaleSAdExNeuron {
28 pub fn new() -> Self {
29 Self {
30 v: -65.0,
31 w: 0.0,
32 v_rest: -65.0,
33 v_reset: -68.0,
34 v_threshold: -50.0,
35 delta_t: 2.0,
36 v_rh: -55.0,
37 tau: 20.0,
38 tau_w: 100.0,
39 a: 0.5,
40 b: 7.0,
41 hw_speedup: 1000.0,
42 dt: 0.1,
43 }
44 }
45 pub fn step(&mut self, current: f64) -> i32 {
46 let exp_arg = ((self.v - self.v_rh) / self.delta_t).clamp(-20.0, 20.0);
47 let exp_term = self.delta_t * exp_arg.exp();
48 let dv = (-(self.v - self.v_rest) + exp_term - self.w + current) / self.tau * self.dt;
49 let dw = (self.a * (self.v - self.v_rest) - self.w) / self.tau_w * self.dt;
50 self.v += dv;
51 self.w += dw;
52 if self.v >= self.v_threshold {
53 self.v = self.v_reset;
54 self.w += self.b;
55 1
56 } else {
57 0
58 }
59 }
60 pub fn reset(&mut self) {
61 self.v = self.v_rest;
62 self.w = 0.0;
63 }
64}
65impl Default for BrainScaleSAdExNeuron {
66 fn default() -> Self {
67 Self::new()
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn brainscales_fires() {
77 let mut n = BrainScaleSAdExNeuron::new();
78 let t: i32 = (0..2000).map(|_| n.step(500.0)).sum();
79 assert!(t > 0);
80 }
81 #[test]
82 fn brainscales_silent() {
83 let mut n = BrainScaleSAdExNeuron::new();
84 let t: i32 = (0..200).map(|_| n.step(0.0)).sum();
85 assert_eq!(t, 0);
86 }
87 #[test]
88 fn brainscales_reset() {
89 let mut n = BrainScaleSAdExNeuron::new();
90 for _ in 0..100 {
91 n.step(500.0);
92 }
93 n.reset();
94 assert!((n.v - n.v_rest).abs() < 1e-10);
95 }
96 #[test]
97 fn brainscales_bounded() {
98 let mut n = BrainScaleSAdExNeuron::new();
99 for _ in 0..2000 {
100 n.step(1e4);
101 }
102 assert!(n.v.is_finite());
103 }
104 #[test]
105 fn brainscales_nan_no_panic() {
106 BrainScaleSAdExNeuron::new().step(f64::NAN);
107 }
108}