sc_neurocore_engine/bindings/izhikevich2007.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 — Izhikevich 2007 PyO3 binding
8
9//! Python binding for the NeuroML Izhikevich 2007 model.
10
11use numpy::{IntoPyArray, PyArray1};
12use pyo3::exceptions::PyFloatingPointError;
13use pyo3::prelude::*;
14
15/// Register the Izhikevich 2007 batch simulator with the extension module.
16pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> {
17 module.add_function(wrap_pyfunction!(py_izhikevich2007_simulate, module)?)?;
18 Ok(())
19}
20
21/// Parity contract with
22/// `sc_neurocore.neurons.models.izhikevich2007.Izhikevich2007Neuron.simulate`:
23/// for the same parameters and constant input the returned `v` trace, spike
24/// count, and final `(v, u)` state are bit-identical to the Python RK4 reference
25/// (the NeuroML right-hand side `k (v-vr)(v-vt)/C` is exact arithmetic — products,
26/// a sum and a division, no transcendental functions).
27#[pyfunction]
28#[pyo3(signature = (v0, u0, cap, k, vr, vt, vpeak, a, b, c, d, dt, n_steps, current))]
29#[allow(clippy::too_many_arguments)]
30fn py_izhikevich2007_simulate<'py>(
31 py: Python<'py>,
32 v0: f64,
33 u0: f64,
34 cap: f64,
35 k: f64,
36 vr: f64,
37 vt: f64,
38 vpeak: f64,
39 a: f64,
40 b: f64,
41 c: f64,
42 d: f64,
43 dt: f64,
44 n_steps: usize,
45 current: f64,
46) -> PyResult<(Bound<'py, PyArray1<f64>>, i64, f64, f64)> {
47 let mut neuron = crate::rk4_neurons::Izhikevich2007Rk4 {
48 v: v0,
49 u: u0,
50 cap,
51 k,
52 vr,
53 vt,
54 vpeak,
55 a,
56 b,
57 c,
58 d,
59 dt,
60 };
61 let (trace, spikes) = neuron
62 .simulate(n_steps, current)
63 .map_err(PyFloatingPointError::new_err)?;
64 Ok((trace.into_pyarray(py), spikes, neuron.v, neuron.u))
65}