Skip to main content

sc_neurocore_engine/neuron/
dendritic_neuron.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Commercial license available
3// © Concepts 1996–2026 Miroslav Šotek. All rights reserved.
4// © Code 2020–2026 Miroslav Šotek. All rights reserved.
5// ORCID: 0009-0009-3560-0851
6// Contact: www.anulum.li | protoscience@anulum.li
7// SC-NeuroCore — XOR-nonlinearity dendritic neuron
8
9/// XOR-nonlinearity dendritic neuron.
10///
11/// Koch, Biophysics of Computation, 1999, Ch. 12.
12/// Output = 1 if `(d1 + d2 - 2*d1*d2) > threshold`.
13#[derive(Clone, Debug)]
14pub struct DendriticNeuron {
15    pub threshold: f64,
16    last_current: f64,
17}
18
19impl DendriticNeuron {
20    pub fn new(threshold: f64) -> Self {
21        Self {
22            threshold,
23            last_current: 0.0,
24        }
25    }
26
27    pub fn with_defaults() -> Self {
28        Self::new(0.5)
29    }
30
31    pub fn step(&mut self, input_a: f64, input_b: f64) -> i32 {
32        self.last_current = input_a + input_b - 2.0 * input_a * input_b;
33        if self.last_current > self.threshold {
34            1
35        } else {
36            0
37        }
38    }
39
40    pub fn reset(&mut self) {
41        self.last_current = 0.0;
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::DendriticNeuron;
48
49    #[test]
50    fn xor_nonlinearity_matches_truth_table() {
51        let mut neuron = DendriticNeuron::new(0.5);
52        assert_eq!(neuron.step(0.0, 0.0), 0);
53        assert_eq!(neuron.step(1.0, 0.0), 1);
54        assert_eq!(neuron.step(0.0, 1.0), 1);
55        assert_eq!(neuron.step(1.0, 1.0), 0);
56    }
57
58    #[test]
59    fn subthreshold_current_does_not_fire() {
60        let mut neuron = DendriticNeuron::new(0.5);
61        assert_eq!(neuron.step(0.2, 0.1), 0);
62    }
63
64    #[test]
65    fn reset_clears_last_current() {
66        let mut neuron = DendriticNeuron::with_defaults();
67        neuron.step(1.0, 0.0);
68        neuron.reset();
69        assert!(neuron.last_current.abs() < 1e-12);
70    }
71}