sc_neurocore_engine/bindings/maps/
aihara_map.rs1use numpy::{IntoPyArray, PyReadonlyArray1};
10use pyo3::exceptions::{PyFloatingPointError, PyValueError};
11use pyo3::prelude::*;
12use pyo3::types::PyDict;
13
14use crate::neurons::{self, AiharaMapError};
15
16fn map_error(error: AiharaMapError) -> PyErr {
17 match error {
18 AiharaMapError::NonFiniteCandidate => PyFloatingPointError::new_err(error.to_string()),
19 _ => PyValueError::new_err(error.to_string()),
20 }
21}
22
23#[pyclass(
24 name = "AiharaMapNeuron",
25 module = "sc_neurocore_engine.sc_neurocore_engine"
26)]
27#[derive(Clone)]
28pub struct PyAiharaMapNeuron {
29 inner: neurons::AiharaMapNeuron,
30}
31
32#[pymethods]
33impl PyAiharaMapNeuron {
34 #[new]
35 fn new() -> Self {
36 Self {
37 inner: neurons::AiharaMapNeuron::default(),
38 }
39 }
40
41 fn step(&mut self, current: f64) -> PyResult<i32> {
42 self.inner.try_step(current).map_err(map_error)
43 }
44
45 fn reset(&mut self) {
46 self.inner.reset();
47 }
48
49 fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
50 let state = PyDict::new(py);
51 state.set_item("y", self.inner.y)?;
52 state.set_item("x", self.inner.output())?;
53 Ok(state.into_any().unbind())
54 }
55}
56
57pub(super) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> {
59 module.add_class::<PyAiharaMapNeuron>()?;
60 module.add_function(wrap_pyfunction!(py_aihara_map_simulate, module)?)?;
61 Ok(())
62}
63
64#[pyfunction]
65#[pyo3(signature = (y, k, alpha, bias, epsilon, current))]
66fn py_aihara_map_simulate<'py>(
67 py: Python<'py>,
68 y: f64,
69 k: f64,
70 alpha: f64,
71 bias: f64,
72 epsilon: f64,
73 current: PyReadonlyArray1<'py, f64>,
74) -> PyResult<Py<PyAny>> {
75 let result = neurons::simulate_aihara_map(y, k, alpha, bias, epsilon, current.as_slice()?)
76 .map_err(map_error)?;
77 let mapping = PyDict::new(py);
78 mapping.set_item("y", result.y.into_pyarray(py))?;
79 mapping.set_item("x", result.x.into_pyarray(py))?;
80 mapping.set_item("spikes", result.spikes.into_pyarray(py))?;
81 mapping.set_item("y_final", result.y_final)?;
82 mapping.set_item("x_final", result.x_final)?;
83 mapping.set_item("spike_count", result.spike_count)?;
84 Ok(mapping.into_any().unbind())
85}