sc_neurocore_engine/neurons/rate/
tsodyks_markram.rs1#[derive(Clone, Debug)]
11pub struct TsodyksMarkramNeuron {
12 pub v: f64,
13 pub x: f64,
14 pub u: f64,
15 pub v_rest: f64,
16 pub v_reset: f64,
17 pub v_threshold: f64,
18 pub tau_m: f64,
19 pub tau_d: f64,
20 pub tau_f: f64,
21 pub u_se: f64,
22 pub a_se: f64,
23 pub r_m: f64,
24 pub dt: f64,
25}
26
27impl TsodyksMarkramNeuron {
28 pub fn new() -> Self {
29 Self {
30 v: -65.0,
31 x: 1.0,
32 u: 0.2,
33 v_rest: -65.0,
34 v_reset: -65.0,
35 v_threshold: -50.0,
36 tau_m: 20.0,
37 tau_d: 200.0,
38 tau_f: 600.0,
39 u_se: 0.2,
40 a_se: 50.0,
41 r_m: 1.0,
42 dt: 0.1,
43 }
44 }
45 pub fn step(&mut self, current: f64, presynaptic_spike: bool) -> i32 {
46 self.x += (1.0 - self.x) / self.tau_d * self.dt;
47 self.u += (self.u_se - self.u) / self.tau_f * self.dt;
48 let mut i_syn = 0.0;
49 if presynaptic_spike {
50 self.u += self.u_se * (1.0 - self.u);
51 i_syn = self.a_se * self.u * self.x;
52 self.x -= self.u * self.x;
53 }
54 self.v += (-(self.v - self.v_rest) + self.r_m * (i_syn + current)) / self.tau_m * self.dt;
55 if self.v >= self.v_threshold {
56 self.v = self.v_reset;
57 1
58 } else {
59 0
60 }
61 }
62 pub fn reset(&mut self) {
63 self.v = self.v_rest;
64 self.x = 1.0;
65 self.u = self.u_se;
66 }
67}
68impl Default for TsodyksMarkramNeuron {
69 fn default() -> Self {
70 Self::new()
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn tm_fires() {
80 let mut n = TsodyksMarkramNeuron::new();
81 let t: i32 = (0..500).map(|_| n.step(50.0, false)).sum();
82 assert!(t > 0);
83 }
84
85 #[test]
86 fn tm_reset() {
87 let mut n = TsodyksMarkramNeuron::new();
88 for _ in 0..100 {
89 n.step(50.0, false);
90 }
91 n.reset();
92 assert!((n.v - n.v_rest).abs() < 1e-10);
93 assert!((n.x - 1.0).abs() < 1e-10);
94 }
95
96 #[test]
97 fn tm_bounded() {
98 let mut n = TsodyksMarkramNeuron::new();
99 for _ in 0..1000 {
100 n.step(1e4, false);
101 }
102 assert!(n.v.is_finite());
103 }
104
105 #[test]
106 fn tm_nan_no_panic() {
107 TsodyksMarkramNeuron::new().step(f64::NAN, false);
108 }
109
110 #[test]
111 fn tm_stp_depression() {
112 let mut n = TsodyksMarkramNeuron::new();
113 for _ in 0..500 {
114 n.step(50.0, true);
115 }
116 assert!(
118 n.x < 1.0,
119 "STP depression: x should be < 1.0 after spikes: {}",
120 n.x
121 );
122 }
123}