sc_neurocore_engine/neurons/hardware/
akida.rs1#[derive(Clone, Debug)]
11pub struct AkidaNeuron {
12 pub v: i32,
13 pub threshold: i32,
14 pub modulation: f64,
15 pub rank: i32,
16 pub spiked: bool,
17}
18
19impl AkidaNeuron {
20 pub fn new(threshold: i32) -> Self {
21 Self {
22 v: 0,
23 threshold,
24 modulation: 0.75,
25 rank: 0,
26 spiked: false,
27 }
28 }
29 pub fn step(&mut self, weight: f64) -> i32 {
30 if self.spiked {
31 return 0;
32 }
33 self.v += (weight * self.modulation.powi(self.rank)) as i32;
34 self.rank += 1;
35 if self.v >= self.threshold {
36 self.spiked = true;
37 1
38 } else {
39 0
40 }
41 }
42 pub fn reset(&mut self) {
43 self.v = 0;
44 self.rank = 0;
45 self.spiked = false;
46 }
47}
48impl Default for AkidaNeuron {
49 fn default() -> Self {
50 Self::new(100)
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn akida_fires() {
60 let mut n = AkidaNeuron::default();
61 let t: i32 = (0..10).map(|_| n.step(50.0)).sum();
62 assert!(t > 0);
63 }
64 #[test]
65 fn akida_silent() {
66 let mut n = AkidaNeuron::default();
67 let t: i32 = (0..100).map(|_| n.step(0.0)).sum();
68 assert_eq!(t, 0);
69 }
70 #[test]
71 fn akida_reset() {
72 let mut n = AkidaNeuron::default();
73 for _ in 0..10 {
74 n.step(50.0);
75 }
76 n.reset();
77 }
78 #[test]
79 fn akida_nan_no_panic() {
80 AkidaNeuron::default().step(f64::NAN);
81 }
82}