sc_neurocore_engine/neurons/multi_compartment/
dendrify.rs1#[derive(Clone, Debug)]
13pub struct DendrifyNeuron {
14 pub v_s: f64,
15 pub v_d: f64,
16 pub d_active: bool,
17 pub d_timer: f64,
18 pub tau_s: f64,
19 pub tau_d: f64,
20 pub g_c: f64,
21 pub d_threshold: f64,
22 pub d_amplitude: f64,
23 pub d_duration: f64,
24 pub v_rest: f64,
25 pub v_threshold: f64,
26 pub v_reset: f64,
27 pub dt: f64,
28}
29
30impl DendrifyNeuron {
31 pub fn new() -> Self {
32 Self {
33 v_s: -65.0,
34 v_d: -65.0,
35 d_active: false,
36 d_timer: 0.0,
37 tau_s: 10.0,
38 tau_d: 20.0,
39 g_c: 0.8,
40 d_threshold: -35.0,
41 d_amplitude: 30.0,
42 d_duration: 10.0,
43 v_rest: -65.0,
44 v_threshold: -50.0,
45 v_reset: -65.0,
46 dt: 0.1,
47 }
48 }
49 pub fn step(&mut self, current: f64) -> i32 {
50 let d_input = if self.d_active { self.d_amplitude } else { 0.0 };
51 self.v_d += (-(self.v_d - self.v_rest) + current + d_input
52 - self.g_c * (self.v_d - self.v_s))
53 / self.tau_d
54 * self.dt;
55 self.v_s +=
56 (-(self.v_s - self.v_rest) + self.g_c * (self.v_d - self.v_s)) / self.tau_s * self.dt;
57 if self.d_active {
58 self.d_timer -= self.dt;
59 if self.d_timer <= 0.0 {
60 self.d_active = false;
61 }
62 } else if self.v_d >= self.d_threshold {
63 self.d_active = true;
64 self.d_timer = self.d_duration;
65 }
66 if self.v_s >= self.v_threshold {
67 self.v_s = self.v_reset;
68 1
69 } else {
70 0
71 }
72 }
73 pub fn reset(&mut self) {
74 self.v_s = -65.0;
75 self.v_d = -65.0;
76 self.d_active = false;
77 self.d_timer = 0.0;
78 }
79}
80impl Default for DendrifyNeuron {
81 fn default() -> Self {
82 Self::new()
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn dendrify_fires() {
92 let mut n = DendrifyNeuron::new();
93 let t: i32 = (0..2000).map(|_| n.step(50.0)).sum();
94 assert!(t > 0);
95 }
96
97 #[test]
98 fn dendrify_reset() {
99 let mut n = DendrifyNeuron::new();
100 for _ in 0..100 {
101 n.step(50.0);
102 }
103 n.reset();
104 assert!((n.v_s - (-65.0)).abs() < 1e-10);
105 }
106
107 #[test]
108 fn dendrify_bounded() {
109 let mut n = DendrifyNeuron::new();
110 for _ in 0..2000 {
111 n.step(200.0);
112 }
113 assert!(n.v_s.is_finite());
114 }
115
116 #[test]
117 fn dendrify_nan_no_panic() {
118 DendrifyNeuron::new().step(f64::NAN);
119 }
120}