sc_neurocore_engine/bindings/ermentrout_kopell_map.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 — Ermentrout-Kopell map PyO3 binding
8
9//! Python binding for the Ermentrout-Kopell Type-I theta map.
10
11use numpy::{IntoPyArray, PyArray1};
12use pyo3::prelude::*;
13use pyo3::types::PyDict;
14
15use crate::neurons::ErmentroutKopellMapNeuron;
16
17py_neuron_default!("ErmentroutKopellMapNeuron", PyErmentroutKopellMapNeuron, ErmentroutKopellMapNeuron, state theta);
18
19/// Register the Ermentrout-Kopell map class and simulator.
20pub(super) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> {
21 module.add_class::<PyErmentroutKopellMapNeuron>()?;
22 module.add_function(wrap_pyfunction!(py_ermentrout_kopell_map_simulate, module)?)?;
23 Ok(())
24}
25
26/// Parity contract with
27/// `sc_neurocore.neurons.models.ermentrout_kopell_map_neuron.ErmentroutKopellMapNeuron.simulate`:
28/// for the same parameters and constant input the returned `theta` trace,
29/// upward-crossing spike count, and final `theta` state match the Python
30/// reference bit-for-bit on a shared libm (the only transcendental is `cos`,
31/// and the non-chaotic phase flow does not amplify ULP differences). This is a
32/// one-dimensional phase map, so there is no second state.
33#[pyfunction]
34#[pyo3(signature = (theta0, dt, gain, theta_threshold, n_steps, current))]
35fn py_ermentrout_kopell_map_simulate<'py>(
36 py: Python<'py>,
37 theta0: f64,
38 dt: f64,
39 gain: f64,
40 theta_threshold: f64,
41 n_steps: usize,
42 current: f64,
43) -> (Bound<'py, PyArray1<f64>>, i64, f64) {
44 let mut neuron = ErmentroutKopellMapNeuron {
45 theta: theta0,
46 dt,
47 gain,
48 theta_threshold,
49 };
50 let (trace, spikes) = neuron.simulate(n_steps, current);
51 (trace.into_pyarray(py), spikes, neuron.theta)
52}