Skip to main content

sc_neurocore_engine/bindings/
exp_if.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 — Exponential integrate-and-fire PyO3 binding
8
9//! Python binding for the exponential integrate-and-fire neuron.
10
11use pyo3::prelude::*;
12use pyo3::types::PyDict;
13
14use crate::neuron;
15
16/// Register the exponential integrate-and-fire neuron with the extension module.
17pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> {
18    module.add_class::<PyExpIFNeuron>()?;
19    Ok(())
20}
21
22/// Register the historical mixed-case class alias.
23pub(crate) fn register_legacy_alias(module: &Bound<'_, PyModule>) -> PyResult<()> {
24    module.add_class::<PyExpIfNeuron>()?;
25    Ok(())
26}
27
28#[pyclass(
29    name = "ExpIFNeuron",
30    module = "sc_neurocore_engine.sc_neurocore_engine"
31)]
32#[derive(Clone)]
33pub struct PyExpIFNeuron {
34    inner: neuron::ExpIfNeuron,
35}
36
37#[pymethods]
38impl PyExpIFNeuron {
39    #[new]
40    fn new() -> Self {
41        Self {
42            inner: neuron::ExpIfNeuron::new(),
43        }
44    }
45
46    fn step(&mut self, current: f64) -> i32 {
47        self.inner.step(current)
48    }
49
50    fn reset(&mut self) {
51        self.inner.reset();
52    }
53
54    fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
55        let d = PyDict::new(py);
56        d.set_item("v", self.inner.v)?;
57        d.set_item("refractory_remaining", self.inner.refractory_remaining)?;
58        Ok(d.into_any().unbind())
59    }
60}
61
62#[pyclass(
63    name = "ExpIfNeuron",
64    module = "sc_neurocore_engine.sc_neurocore_engine"
65)]
66#[derive(Clone)]
67pub struct PyExpIfNeuron {
68    inner: neuron::ExpIfNeuron,
69}
70
71#[pymethods]
72impl PyExpIfNeuron {
73    #[new]
74    fn new() -> Self {
75        Self {
76            inner: neuron::ExpIfNeuron::new(),
77        }
78    }
79    fn step(&mut self, current: f64) -> i32 {
80        self.inner.step(current)
81    }
82    fn reset(&mut self) {
83        self.inner.reset();
84    }
85    fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
86        let d = PyDict::new(py);
87        d.set_item("v", self.inner.v)?;
88        d.set_item("refractory_remaining", self.inner.refractory_remaining)?;
89        Ok(d.into_any().unbind())
90    }
91}