sc_neurocore_engine/bindings/trivial/
sigma_delta.rs1use crate::neurons;
11use numpy::{IntoPyArray, PyReadonlyArray1};
12use pyo3::exceptions::PyValueError;
13use pyo3::prelude::*;
14use pyo3::types::PyDict;
15
16#[pyclass(
17 name = "SigmaDeltaNeuron",
18 module = "sc_neurocore_engine.sc_neurocore_engine"
19)]
20#[derive(Clone)]
21pub struct PySigmaDeltaNeuron {
22 inner: neurons::SigmaDeltaNeuron,
23}
24
25#[pymethods]
26impl PySigmaDeltaNeuron {
27 #[new]
28 #[pyo3(signature=(sigma=0.0,reconstruction=0.0,delta=1.0,tau_reconstruction=10.0,dt=0.1))]
29 fn new(
30 sigma: f64,
31 reconstruction: f64,
32 delta: f64,
33 tau_reconstruction: f64,
34 dt: f64,
35 ) -> PyResult<Self> {
36 let inner = neurons::SigmaDeltaNeuron {
37 sigma,
38 reconstruction,
39 delta,
40 tau_reconstruction,
41 dt,
42 };
43 if !inner.validate() {
44 return Err(PyValueError::new_err(
45 "invalid SigmaDelta state or configuration",
46 ));
47 }
48 Ok(Self { inner })
49 }
50 fn step(&mut self, current: f64) -> PyResult<i32> {
51 self.inner.try_step(current).map_err(PyValueError::new_err)
52 }
53 fn reset(&mut self) {
54 self.inner.reset();
55 }
56 fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
57 let d = PyDict::new(py);
58 d.set_item("sigma", self.inner.sigma)?;
59 d.set_item("reconstruction", self.inner.reconstruction)?;
60 Ok(d.into_any().unbind())
61 }
62}
63
64#[pyfunction]
65#[pyo3(signature=(sigma,reconstruction,delta,tau_reconstruction,dt,currents))]
66fn py_sigma_delta_simulate<'py>(
67 py: Python<'py>,
68 sigma: f64,
69 reconstruction: f64,
70 delta: f64,
71 tau_reconstruction: f64,
72 dt: f64,
73 currents: PyReadonlyArray1<'py, f64>,
74) -> PyResult<Py<PyAny>> {
75 let mut n = neurons::SigmaDeltaNeuron {
76 sigma,
77 reconstruction,
78 delta,
79 tau_reconstruction,
80 dt,
81 };
82 if !n.validate() {
83 return Err(PyValueError::new_err(
84 "invalid SigmaDelta state or configuration",
85 ));
86 }
87 let mut sigmas = Vec::with_capacity(currents.len()?);
88 let mut reconstructions = Vec::with_capacity(currents.len()?);
89 let mut events = Vec::with_capacity(currents.len()?);
90 for ¤t in currents.as_slice()? {
91 events.push(n.try_step(current).map_err(PyValueError::new_err)?);
92 sigmas.push(n.sigma);
93 reconstructions.push(n.reconstruction);
94 }
95 let d = PyDict::new(py);
96 d.set_item("sigma", sigmas.into_pyarray(py))?;
97 d.set_item("reconstruction", reconstructions.into_pyarray(py))?;
98 d.set_item("events", events.into_pyarray(py))?;
99 d.set_item("sigma_final", n.sigma)?;
100 d.set_item("reconstruction_final", n.reconstruction)?;
101 Ok(d.into_any().unbind())
102}
103pub(super) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> {
104 module.add_class::<PySigmaDeltaNeuron>()?;
105 module.add_function(wrap_pyfunction!(py_sigma_delta_simulate, module)?)?;
106 Ok(())
107}