sc_neurocore_engine/neurons/trivial/
sigma_delta.rs1#[derive(Clone, Debug)]
11pub struct SigmaDeltaNeuron {
12 pub sigma: f64,
13 pub v_threshold: f64,
14}
15
16impl SigmaDeltaNeuron {
17 pub fn new(v_threshold: f64) -> Self {
18 Self {
19 sigma: 0.0,
20 v_threshold,
21 }
22 }
23
24 pub fn step(&mut self, current: f64) -> i32 {
25 self.sigma += current;
26 if self.sigma >= self.v_threshold {
27 self.sigma -= self.v_threshold;
28 1
29 } else if self.sigma <= -self.v_threshold {
30 self.sigma += self.v_threshold;
31 -1
32 } else {
33 0
34 }
35 }
36
37 pub fn reset(&mut self) {
38 self.sigma = 0.0;
39 }
40}
41
42impl Default for SigmaDeltaNeuron {
43 fn default() -> Self {
44 Self::new(1.0)
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn sigma_delta_encodes() {
54 let mut n = SigmaDeltaNeuron::default();
55 let total: i32 = (0..10).map(|_| n.step(0.3)).sum();
56 assert!(total > 0);
57 }
58 #[test]
59 fn sd_reset_clears_state() {
60 let mut n = SigmaDeltaNeuron::default();
61 for _ in 0..10 {
62 n.step(0.3);
63 }
64 n.reset();
65 assert!((n.sigma - 0.0).abs() < 1e-10);
66 }
67 #[test]
68 fn sd_bounded() {
69 let mut n = SigmaDeltaNeuron::default();
70 for _ in 0..1000 {
71 n.step(100.0);
72 }
73 assert!(n.sigma.is_finite());
74 }
75 #[test]
76 fn sd_nan_no_panic() {
77 SigmaDeltaNeuron::default().step(f64::NAN);
78 }
79}