sc_neurocore_engine/neurons/rate/
compte_wm.rs1#[derive(Clone, Debug)]
11pub struct CompteWMNeuron {
12 pub v: f64,
13 pub s_ampa: f64,
14 pub s_nmda: f64,
15 pub x_nmda: f64,
16 pub s_gaba: f64,
17 pub g_l: f64,
18 pub g_ampa: f64,
19 pub g_nmda: f64,
20 pub g_gaba: f64,
21 pub e_l: f64,
22 pub e_exc: f64,
23 pub e_inh: f64,
24 pub c_m: f64,
25 pub mg: f64,
26 pub tau_ampa: f64,
27 pub tau_nmda: f64,
28 pub tau_x: f64,
29 pub alpha_nmda: f64,
30 pub v_threshold: f64,
31 pub v_reset: f64,
32 pub dt: f64,
33}
34
35impl CompteWMNeuron {
36 pub fn new() -> Self {
37 Self {
38 v: -70.0,
39 s_ampa: 0.0,
40 s_nmda: 0.0,
41 x_nmda: 0.0,
42 s_gaba: 0.0,
43 g_l: 0.025,
44 g_ampa: 0.005,
45 g_nmda: 0.165,
46 g_gaba: 0.013,
47 e_l: -70.0,
48 e_exc: 0.0,
49 e_inh: -70.0,
50 c_m: 0.5,
51 mg: 1.0,
52 tau_ampa: 2.0,
53 tau_nmda: 100.0,
54 tau_x: 2.0,
55 alpha_nmda: 0.5,
56 v_threshold: -50.0,
57 v_reset: -55.0,
58 dt: 0.1,
59 }
60 }
61 pub fn step(&mut self, current: f64, spike_in: bool) -> i32 {
62 if spike_in {
63 self.s_ampa += 1.0;
64 self.x_nmda += 1.0;
65 }
66 self.s_ampa *= (-self.dt / self.tau_ampa).exp();
67 self.s_nmda += (-self.s_nmda / self.tau_nmda
68 + self.alpha_nmda * self.x_nmda * (1.0 - self.s_nmda))
69 * self.dt;
70 self.x_nmda *= (-self.dt / self.tau_x).exp();
71 self.s_gaba *= (-self.dt / 5.0).exp();
72 let mg_block = 1.0 / (1.0 + self.mg / 3.57 * (-0.062 * self.v).exp());
73 let i_l = self.g_l * (self.v - self.e_l);
74 let i_ampa = self.g_ampa * self.s_ampa * (self.v - self.e_exc);
75 let i_nmda = self.g_nmda * mg_block * self.s_nmda * (self.v - self.e_exc);
76 let i_gaba = self.g_gaba * self.s_gaba * (self.v - self.e_inh);
77 self.v += (-i_l - i_ampa - i_nmda - i_gaba + current) / self.c_m * self.dt;
78 if self.v >= self.v_threshold {
79 self.v = self.v_reset;
80 self.s_gaba += 1.0;
81 1
82 } else {
83 0
84 }
85 }
86 pub fn reset(&mut self) {
87 self.v = self.e_l;
88 self.s_ampa = 0.0;
89 self.s_nmda = 0.0;
90 self.x_nmda = 0.0;
91 self.s_gaba = 0.0;
92 }
93}
94impl Default for CompteWMNeuron {
95 fn default() -> Self {
96 Self::new()
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn compte_fires() {
106 let mut n = CompteWMNeuron::new();
107 let t: i32 = (0..500).map(|_| n.step(5.0, false)).sum();
108 assert!(t > 0);
109 }
110
111 #[test]
112 fn compte_reset() {
113 let mut n = CompteWMNeuron::new();
114 for _ in 0..100 {
115 n.step(5.0, false);
116 }
117 n.reset();
118 assert!((n.v - n.e_l).abs() < 1e-10);
119 }
120
121 #[test]
122 fn compte_nan_no_panic() {
123 CompteWMNeuron::new().step(f64::NAN, false);
124 }
125}