sc_neurocore_engine/neurons/rate/
parallel_spiking.rs1#[derive(Clone, Debug)]
11pub struct ParallelSpikingNeuron {
12 pub kernel: Vec<f64>,
13 pub buffer: Vec<f64>,
14 pub v_threshold: f64,
15 ptr: usize,
16}
17
18impl ParallelSpikingNeuron {
19 pub fn new(kernel_size: usize, v_threshold: f64) -> Self {
20 let k = 1.0 / kernel_size as f64;
21 Self {
22 kernel: vec![k; kernel_size],
23 buffer: vec![0.0; kernel_size],
24 v_threshold,
25 ptr: 0,
26 }
27 }
28 pub fn step(&mut self, current: f64) -> i32 {
29 let ks = self.buffer.len();
30 self.buffer[self.ptr % ks] = current;
31 self.ptr += 1;
32 let n = self.ptr.min(ks);
33 let score: f64 = self.kernel[..n]
34 .iter()
35 .zip(self.buffer[..n].iter())
36 .map(|(&w, &b)| w * b)
37 .sum();
38 if score >= self.v_threshold {
39 self.buffer.fill(0.0);
40 1
41 } else {
42 0
43 }
44 }
45 pub fn reset(&mut self) {
46 self.buffer.fill(0.0);
47 self.ptr = 0;
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn psn_fires() {
57 let mut n = ParallelSpikingNeuron::new(4, 0.5);
58 let t: i32 = (0..20).map(|_| n.step(1.0)).sum();
59 assert!(t > 0);
60 }
61
62 #[test]
63 fn psn_reset() {
64 let mut n = ParallelSpikingNeuron::new(4, 0.5);
65 for _ in 0..20 {
66 n.step(1.0);
67 }
68 n.reset();
69 }
70
71 #[test]
72 fn psn_nan_no_panic() {
73 ParallelSpikingNeuron::new(4, 0.5).step(f64::NAN);
74 }
75}