use numpy::{IntoPyArray, PyArray1};
use pyo3::prelude::*;
use pyo3::types::PyDict;
use crate::neurons;
macro_rules! py_neuron_default {
($pylit:literal, $pyname:ident, $rust:ty $(, state $sname:ident)*) => {
#[pyclass(name = $pylit, module = "sc_neurocore_engine.sc_neurocore_engine")]
#[derive(Clone)]
pub struct $pyname { inner: $rust }
#[pymethods]
impl $pyname {
#[new]
fn new() -> Self { Self { inner: <$rust>::default() } }
fn step(&mut self, current: f64) -> i32 { self.inner.step(current) }
fn reset(&mut self) { self.inner.reset(); }
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
$(d.set_item(stringify!($sname), self.inner.$sname)?;)*
Ok(d.into_any().unbind())
}
}
};
}
py_neuron_default!("MultiTimescaleNeuron", PyMultiTimescaleNeuron, neurons::MultiTimescaleNeuron, state v_fast, state v_medium, state v_slow);
py_neuron_default!("AttentionGatedNeuron", PyAttentionGatedNeuron, neurons::AttentionGatedNeuron, state v);
py_neuron_default!("PredictiveCodingNeuron", PyPredictiveCodingNeuron, neurons::PredictiveCodingNeuron, state v, state pred);
py_neuron_default!("SelfReferentialNeuron", PySelfReferentialNeuron, neurons::SelfReferentialNeuron, state v);
py_neuron_default!("CompositionalBindingNeuron", PyCompositionalBindingNeuron, neurons::CompositionalBindingNeuron, state phi, state amplitude);
py_neuron_default!("DifferentiableSurrogateNeuron", PyDifferentiableSurrogateNeuron, neurons::DifferentiableSurrogateNeuron, state v);
py_neuron_default!("MetaPlasticNeuron", PyMetaPlasticNeuron, neurons::MetaPlasticNeuron, state v, state error_trace, state expected_reward);
py_neuron_default!("ArcaneNeuron", PyArcaneNeuron, neurons::ArcaneNeuron, state v_fast, state v_work, state v_deep);
#[pyclass(
name = "RustContinuousAttractorNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyContinuousAttractorNeuron {
inner: neurons::ContinuousAttractorNeuron,
}
#[pymethods]
impl PyContinuousAttractorNeuron {
#[new]
#[pyo3(signature = (n_units=16))]
fn new(n_units: usize) -> Self {
Self {
inner: neurons::ContinuousAttractorNeuron::new(n_units),
}
}
fn step(&mut self, current: f64) -> i32 {
self.inner.step(current)
}
fn bump_position(&self) -> usize {
self.inner.bump_position()
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("u", self.inner.u.clone().into_pyarray(py))?;
Ok(d.into_any().unbind())
}
}
py_neuron_default!("QuadraticIFNeuron", PyQuadraticIFNeuron, neurons::QuadraticIFNeuron, state v);
py_neuron_default!("ThetaNeuron", PyThetaNeuron, neurons::ThetaNeuron, state theta);
py_neuron_default!("PerfectIntegratorNeuron", PyPerfectIntegratorNeuron, neurons::PerfectIntegratorNeuron, state v);
py_neuron_default!("GatedLIFNeuron", PyGatedLIFNeuron, neurons::GatedLIFNeuron, state v);
py_neuron_default!("NonlinearLIFNeuron", PyNonlinearLIFNeuron, neurons::NonlinearLIFNeuron, state v, state w);
py_neuron_default!("SFANeuron", PySFANeuron, neurons::SFANeuron, state v, state g_sfa);
py_neuron_default!("MATNeuron", PyMATNeuron, neurons::MATNeuron, state v, state theta1, state theta2);
py_neuron_default!("KLIFNeuron", PyKLIFNeuron, neurons::KLIFNeuron, state v);
py_neuron_default!("InhibitoryLIFNeuron", PyInhibitoryLIFNeuron, neurons::InhibitoryLIFNeuron, state v, state inh_trace);
py_neuron_default!("ComplementaryLIFNeuron", PyComplementaryLIFNeuron, neurons::ComplementaryLIFNeuron, state v_pos, state v_neg);
py_neuron_default!("ParametricLIFNeuron", PyParametricLIFNeuron, neurons::ParametricLIFNeuron, state v);
py_neuron_default!("NonResettingLIFNeuron", PyNonResettingLIFNeuron, neurons::NonResettingLIFNeuron, state v, state theta);
py_neuron_default!("AdaptiveThresholdIFNeuron", PyAdaptiveThresholdIFNeuron, neurons::AdaptiveThresholdIFNeuron, state v, state theta);
py_neuron_default!("SigmaDeltaNeuron", PySigmaDeltaNeuron, neurons::SigmaDeltaNeuron, state sigma);
py_neuron_default!("EnergyLIFNeuron", PyEnergyLIFNeuron, neurons::EnergyLIFNeuron, state v, state epsilon);
py_neuron_default!("ClosedFormContinuousNeuron", PyClosedFormContinuousNeuron, neurons::ClosedFormContinuousNeuron, state x);
#[pyclass(
name = "IntegerQIFNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyIntegerQIFNeuron {
inner: neurons::IntegerQIFNeuron,
}
#[pymethods]
impl PyIntegerQIFNeuron {
#[new]
#[pyo3(signature = (k=6, v_threshold=1024))]
fn new(k: i32, v_threshold: i32) -> Self {
Self {
inner: neurons::IntegerQIFNeuron::new(k, v_threshold),
}
}
fn step(&mut self, current: i32) -> i32 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "EscapeRateNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyEscapeRateNeuron {
inner: neurons::EscapeRateNeuron,
}
#[pymethods]
impl PyEscapeRateNeuron {
#[new]
#[pyo3(signature = (seed=42))]
fn new(seed: u64) -> Self {
Self {
inner: neurons::EscapeRateNeuron::new(seed),
}
}
fn step(&mut self, current: f64) -> i32 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
Ok(d.into_any().unbind())
}
}
py_neuron_default!("FitzHughNagumoNeuron", PyFitzHughNagumoNeuron, neurons::FitzHughNagumoNeuron, state v, state w);
py_neuron_default!("MorrisLecarNeuron", PyMorrisLecarNeuron, neurons::MorrisLecarNeuron, state v, state w);
py_neuron_default!("HindmarshRoseNeuron", PyHindmarshRoseNeuron, neurons::HindmarshRoseNeuron, state x, state y, state z);
py_neuron_default!("ResonateAndFireNeuron", PyResonateAndFireNeuron, neurons::ResonateAndFireNeuron, state x, state y);
py_neuron_default!("FitzHughRinzelNeuron", PyFitzHughRinzelNeuron, neurons::FitzHughRinzelNeuron, state v, state w, state y);
py_neuron_default!("McKeanNeuron", PyMcKeanNeuron, neurons::McKeanNeuron, state v, state w);
py_neuron_default!("TermanWangOscillator", PyTermanWangOscillator, neurons::TermanWangOscillator, state v, state w);
py_neuron_default!("GutkinErmentroutNeuron", PyGutkinErmentroutNeuron, neurons::GutkinErmentroutNeuron, state v, state n);
py_neuron_default!("WilsonHRNeuron", PyWilsonHRNeuron, neurons::WilsonHRNeuron, state v, state r);
py_neuron_default!("ChayNeuron", PyChayNeuron, neurons::ChayNeuron, state v, state n, state ca);
py_neuron_default!("ChayKeizerNeuron", PyChayKeizerNeuron, neurons::ChayKeizerNeuron, state v, state n, state ca);
py_neuron_default!("ShermanRinzelKeizerNeuron", PyShermanRinzelKeizerNeuron, neurons::ShermanRinzelKeizerNeuron, state v, state n, state s);
py_neuron_default!("ButeraRespiratoryNeuron", PyButeraRespiratoryNeuron, neurons::ButeraRespiratoryNeuron, state v, state n, state h_nap);
py_neuron_default!("LearnableNeuronModel", PyLearnableNeuronModel, neurons::LearnableNeuronModel, state v);
py_neuron_default!("PernarowskiNeuron", PyPernarowskiNeuron, neurons::PernarowskiNeuron, state v, state w, state z);
#[pyclass(
name = "AlphaNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyAlphaNeuron {
inner: neurons::AlphaNeuron,
}
#[pymethods]
impl PyAlphaNeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::AlphaNeuron::new(),
}
}
#[pyo3(signature = (exc_current, inh_current=0.0))]
fn step(&mut self, exc_current: f64, inh_current: f64) -> i32 {
self.inner.step(exc_current, inh_current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
d.set_item("i_exc", self.inner.i_exc)?;
d.set_item("i_inh", self.inner.i_inh)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "COBALIFNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyCOBALIFNeuron {
inner: neurons::COBALIFNeuron,
}
#[pymethods]
impl PyCOBALIFNeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::COBALIFNeuron::new(),
}
}
#[pyo3(signature = (current, delta_ge=0.0, delta_gi=0.0))]
fn step(&mut self, current: f64, delta_ge: f64, delta_gi: f64) -> i32 {
self.inner.step(current, delta_ge, delta_gi)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
d.set_item("g_e", self.inner.g_e)?;
d.set_item("g_i", self.inner.g_i)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "EPropALIFNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyEPropALIFNeuron {
inner: neurons::EPropALIFNeuron,
}
#[pymethods]
impl PyEPropALIFNeuron {
#[new]
#[pyo3(signature = (tau_m=20.0, tau_a=200.0, dt=1.0))]
fn new(tau_m: f64, tau_a: f64, dt: f64) -> Self {
Self {
inner: neurons::EPropALIFNeuron::new(tau_m, tau_a, dt),
}
}
fn step(&mut self, current: f64) -> i32 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
d.set_item("a", self.inner.a)?;
d.set_item("e_trace", self.inner.e_trace)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "SuperSpikeNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PySuperSpikeNeuron {
inner: neurons::SuperSpikeNeuron,
}
#[pymethods]
impl PySuperSpikeNeuron {
#[new]
#[pyo3(signature = (tau_m=10.0, tau_e=10.0, dt=1.0))]
fn new(tau_m: f64, tau_e: f64, dt: f64) -> Self {
Self {
inner: neurons::SuperSpikeNeuron::new(tau_m, tau_e, dt),
}
}
fn step(&mut self, current: f64) -> i32 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
d.set_item("trace", self.inner.trace)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "BendaHerzNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyBendaHerzNeuron {
inner: neurons::BendaHerzNeuron,
}
#[pymethods]
impl PyBendaHerzNeuron {
#[new]
#[pyo3(signature = (seed=42))]
fn new(seed: u64) -> Self {
Self {
inner: neurons::BendaHerzNeuron::new(seed),
}
}
fn step(&mut self, current: f64) -> i32 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("a", self.inner.a)?;
Ok(d.into_any().unbind())
}
}
py_neuron_default!("ChialvoMapNeuron", PyChialvoMapNeuron, neurons::ChialvoMapNeuron, state x, state y);
py_neuron_default!("RulkovMapNeuron", PyRulkovMapNeuron, neurons::RulkovMapNeuron, state x, state y);
py_neuron_default!("IbarzTanakaMapNeuron", PyIbarzTanakaMapNeuron, neurons::IbarzTanakaMapNeuron, state x, state y);
py_neuron_default!("MedvedevMapNeuron", PyMedvedevMapNeuron, neurons::MedvedevMapNeuron, state x);
py_neuron_default!("CazellesMapNeuron", PyCazellesMapNeuron, neurons::CazellesMapNeuron, state x, state y);
py_neuron_default!("CourageNekorkinMapNeuron", PyCourageNekorkinMapNeuron, neurons::CourageNekorkinMapNeuron, state x, state y);
py_neuron_default!("HodgkinHuxleyNeuron", PyHodgkinHuxleyNeuron, neurons::HodgkinHuxleyNeuron, state v, state m, state h, state n);
py_neuron_default!("TraubMilesNeuron", PyTraubMilesNeuron, neurons::TraubMilesNeuron, state v, state m, state h, state n);
py_neuron_default!("WangBuzsakiNeuron", PyWangBuzsakiNeuron, neurons::WangBuzsakiNeuron, state v, state h, state n);
py_neuron_default!("ConnorStevensNeuron", PyConnorStevensNeuron, neurons::ConnorStevensNeuron, state v, state m, state h, state n, state a, state b);
py_neuron_default!("DestexheThalamicNeuron", PyDestexheThalamicNeuron, neurons::DestexheThalamicNeuron, state v, state h_na, state n_k, state m_t, state h_t);
py_neuron_default!("HuberBraunNeuron", PyHuberBraunNeuron, neurons::HuberBraunNeuron, state v, state a_sd, state a_sr);
py_neuron_default!("GolombFSNeuron", PyGolombFSNeuron, neurons::GolombFSNeuron, state v, state h, state n, state p);
py_neuron_default!("PospischilNeuron", PyPospischilNeuron, neurons::PospischilNeuron, state v, state m, state h, state n, state p);
py_neuron_default!("MainenSejnowskiNeuron", PyMainenSejnowskiNeuron, neurons::MainenSejnowskiNeuron, state vs, state va, state m, state h, state n);
py_neuron_default!("DeSchutterPurkinjeNeuron", PyDeSchutterPurkinjeNeuron, neurons::DeSchutterPurkinjeNeuron, state v, state h_na, state n_k, state m_cap, state h_cap, state q_kca, state ca);
py_neuron_default!("PlantR15Neuron", PyPlantR15Neuron, neurons::PlantR15Neuron, state v, state m, state h, state n, state ca);
py_neuron_default!("PrescottNeuron", PyPrescottNeuron, neurons::PrescottNeuron, state v, state w);
py_neuron_default!("MihalasNieburNeuron", PyMihalasNieburNeuron, neurons::MihalasNieburNeuron, state v, state theta, state i1, state i2);
py_neuron_default!("GLIFNeuron", PyGLIFNeuron, neurons::GLIFNeuron, state v, state theta, state i_asc1, state i_asc2);
py_neuron_default!("AvRonCardiacNeuron", PyAvRonCardiacNeuron, neurons::AvRonCardiacNeuron, state v, state h, state n, state s);
py_neuron_default!("DurstewitzDopamineNeuron", PyDurstewitzDopamineNeuron, neurons::DurstewitzDopamineNeuron, state v, state h_na, state n_k);
py_neuron_default!("HillTononiNeuron", PyHillTononiNeuron, neurons::HillTononiNeuron, state v, state h_na, state n_k, state m_h, state h_t, state na_i);
py_neuron_default!("BertramPhantomBurster", PyBertramPhantomBurster, neurons::BertramPhantomBurster, state v, state s1, state s2);
py_neuron_default!("YamadaNeuron", PyYamadaNeuron, neurons::YamadaNeuron, state v, state n, state q);
#[pyclass(
name = "GIFPopulationNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyGIFPopulationNeuron {
inner: neurons::GIFPopulationNeuron,
}
#[pymethods]
impl PyGIFPopulationNeuron {
#[new]
#[pyo3(signature = (seed=42))]
fn new(seed: u64) -> Self {
Self {
inner: neurons::GIFPopulationNeuron::new(seed),
}
}
fn step(&mut self, current: f64) -> i32 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
d.set_item("theta", self.inner.theta)?;
d.set_item("eta", self.inner.eta)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "PinskyRinzelNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyPinskyRinzelNeuron {
inner: neurons::PinskyRinzelNeuron,
}
#[pymethods]
impl PyPinskyRinzelNeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::PinskyRinzelNeuron::new(),
}
}
#[pyo3(signature = (current_soma, current_dend=0.0))]
fn step(&mut self, current_soma: f64, current_dend: f64) -> i32 {
self.inner.step(current_soma, current_dend)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v_s", self.inner.v_s)?;
d.set_item("v_d", self.inner.v_d)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "HayL5PyramidalNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyHayL5PyramidalNeuron {
inner: neurons::HayL5PyramidalNeuron,
}
#[pymethods]
impl PyHayL5PyramidalNeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::HayL5PyramidalNeuron::new(),
}
}
#[pyo3(signature = (current_soma, current_tuft=0.0))]
fn step(&mut self, current_soma: f64, current_tuft: f64) -> i32 {
self.inner.step(current_soma, current_tuft)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v_s", self.inner.v_s)?;
d.set_item("v_t", self.inner.v_t)?;
d.set_item("v_a", self.inner.v_a)?;
Ok(d.into_any().unbind())
}
}
py_neuron_default!("MarderSTGNeuron", PyMarderSTGNeuron, neurons::MarderSTGNeuron, state v, state ca);
py_neuron_default!("BoothRinzelNeuron", PyBoothRinzelNeuron, neurons::BoothRinzelNeuron, state vs, state vd, state ca);
py_neuron_default!("DendrifyNeuron", PyDendrifyNeuron, neurons::DendrifyNeuron, state v_s, state v_d);
#[pyclass(
name = "RallCableNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyRallCableNeuron {
inner: neurons::RallCableNeuron,
}
#[pymethods]
impl PyRallCableNeuron {
#[new]
#[pyo3(signature = (n_comp=5))]
fn new(n_comp: usize) -> Self {
Self {
inner: neurons::RallCableNeuron::new(n_comp),
}
}
fn step(&mut self, current: f64) -> i32 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v.clone())?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "TwoCompartmentLIFNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyTwoCompartmentLIFNeuron {
inner: neurons::TwoCompartmentLIFNeuron,
}
#[pymethods]
impl PyTwoCompartmentLIFNeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::TwoCompartmentLIFNeuron::new(),
}
}
#[pyo3(signature = (i_soma, i_dend=0.0))]
fn step(&mut self, i_soma: f64, i_dend: f64) -> i32 {
self.inner.step(i_soma, i_dend)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v_s", self.inner.v_s)?;
d.set_item("v_d", self.inner.v_d)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "PoissonNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyPoissonNeuron {
inner: neurons::PoissonNeuron,
}
#[pymethods]
impl PyPoissonNeuron {
#[new]
#[pyo3(signature = (rate_hz=100.0, dt_ms=1.0, seed=42))]
fn new(rate_hz: f64, dt_ms: f64, seed: u64) -> Self {
Self {
inner: neurons::PoissonNeuron::new(rate_hz, dt_ms, seed),
}
}
#[pyo3(signature = (rate_override=-1.0))]
fn step(&mut self, rate_override: f64) -> i32 {
self.inner.step(rate_override)
}
fn reset(&mut self) {
self.inner.reset();
}
}
#[pyclass(
name = "InhomogeneousPoissonNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyInhomogeneousPoissonNeuron {
inner: neurons::InhomogeneousPoissonNeuron,
}
#[pymethods]
impl PyInhomogeneousPoissonNeuron {
#[new]
#[pyo3(signature = (dt_ms=1.0, seed=42))]
fn new(dt_ms: f64, seed: u64) -> Self {
Self {
inner: neurons::InhomogeneousPoissonNeuron::new(dt_ms, seed),
}
}
fn step(&mut self, rate_hz: f64) -> i32 {
self.inner.step(rate_hz)
}
fn reset(&mut self) {
self.inner.reset();
}
}
#[pyclass(
name = "GammaRenewalNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyGammaRenewalNeuron {
inner: neurons::GammaRenewalNeuron,
}
#[pymethods]
impl PyGammaRenewalNeuron {
#[new]
#[pyo3(signature = (rate_hz=50.0, shape_k=3, seed=42))]
fn new(rate_hz: f64, shape_k: u32, seed: u64) -> Self {
Self {
inner: neurons::GammaRenewalNeuron::new(rate_hz, shape_k, seed),
}
}
#[pyo3(signature = (rate_override=-1.0))]
fn step(&mut self, rate_override: f64) -> i32 {
self.inner.step(rate_override)
}
fn reset(&mut self) {
self.inner.reset();
}
}
#[pyclass(
name = "StochasticIFNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyStochasticIFNeuron {
inner: neurons::StochasticIFNeuron,
}
#[pymethods]
impl PyStochasticIFNeuron {
#[new]
#[pyo3(signature = (seed=42))]
fn new(seed: u64) -> Self {
Self {
inner: neurons::StochasticIFNeuron::new(seed),
}
}
fn step(&mut self, current: f64) -> i32 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "GalvesLocherbachNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyGalvesLocherbachNeuron {
inner: neurons::GalvesLocherbachNeuron,
}
#[pymethods]
impl PyGalvesLocherbachNeuron {
#[new]
#[pyo3(signature = (seed=42))]
fn new(seed: u64) -> Self {
Self {
inner: neurons::GalvesLocherbachNeuron::new(seed),
}
}
fn step(&mut self, weighted_input: f64) -> i32 {
self.inner.step(weighted_input)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
Ok(d.into_any().unbind())
}
}
py_neuron_default!("SpikeResponseNeuron", PySpikeResponseNeuron, neurons::SpikeResponseNeuron, state v, state time_since_spike);
#[pyclass(name = "GLMNeuron", module = "sc_neurocore_engine.sc_neurocore_engine")]
#[derive(Clone)]
pub struct PyGLMNeuron {
inner: neurons::GLMNeuron,
}
#[pymethods]
impl PyGLMNeuron {
#[new]
#[pyo3(signature = (n_k=10, n_h=20, seed=42))]
fn new(n_k: usize, n_h: usize, seed: u64) -> Self {
Self {
inner: neurons::GLMNeuron::new(n_k, n_h, seed),
}
}
fn step(&mut self, stimulus: f64) -> i32 {
self.inner.step(stimulus)
}
fn reset(&mut self) {
self.inner.reset();
}
}
#[pyclass(
name = "WilsonCowanUnit",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyWilsonCowanUnit {
inner: neurons::WilsonCowanUnit,
}
#[pymethods]
impl PyWilsonCowanUnit {
#[new]
fn new() -> Self {
Self {
inner: neurons::WilsonCowanUnit::new(),
}
}
#[pyo3(signature = (ext_input=0.0))]
fn step(&mut self, ext_input: f64) -> f64 {
self.inner.step(ext_input)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("e", self.inner.e)?;
d.set_item("i", self.inner.i)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "JansenRitUnit",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyJansenRitUnit {
inner: neurons::JansenRitUnit,
}
#[pymethods]
impl PyJansenRitUnit {
#[new]
fn new() -> Self {
Self {
inner: neurons::JansenRitUnit::new(),
}
}
#[pyo3(signature = (p_ext=220.0))]
fn step(&mut self, p_ext: f64) -> f64 {
self.inner.step(p_ext)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("y", self.inner.y.to_vec())?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "WongWangUnit",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyWongWangUnit {
inner: neurons::WongWangUnit,
}
#[pymethods]
impl PyWongWangUnit {
#[new]
#[pyo3(signature = (seed=42))]
fn new(seed: u64) -> Self {
Self {
inner: neurons::WongWangUnit::new(seed),
}
}
#[pyo3(signature = (stim1=0.0, stim2=0.0))]
fn step(&mut self, stim1: f64, stim2: f64) -> (f64, f64) {
self.inner.step(stim1, stim2)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("s1", self.inner.s1)?;
d.set_item("s2", self.inner.s2)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "ErmentroutKopellPopulation",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyErmentroutKopellPopulation {
inner: neurons::ErmentroutKopellPopulation,
}
#[pymethods]
impl PyErmentroutKopellPopulation {
#[new]
fn new() -> Self {
Self {
inner: neurons::ErmentroutKopellPopulation::new(),
}
}
#[pyo3(signature = (ext_input=0.0))]
fn step(&mut self, ext_input: f64) -> f64 {
self.inner.step(ext_input)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("r", self.inner.r)?;
d.set_item("v", self.inner.v)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "WendlingNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyWendlingNeuron {
inner: neurons::WendlingNeuron,
}
#[pymethods]
impl PyWendlingNeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::WendlingNeuron::new(),
}
}
#[pyo3(signature = (p_ext=220.0))]
fn step(&mut self, p_ext: f64) -> f64 {
self.inner.step(p_ext)
}
fn reset(&mut self) {
self.inner.reset();
}
}
#[pyclass(
name = "LarterBreakspearNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyLarterBreakspearNeuron {
inner: neurons::LarterBreakspearNeuron,
}
#[pymethods]
impl PyLarterBreakspearNeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::LarterBreakspearNeuron::new(),
}
}
#[pyo3(signature = (coupling=0.0))]
fn step(&mut self, coupling: f64) -> f64 {
self.inner.step(coupling)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
d.set_item("w", self.inner.w)?;
d.set_item("z", self.inner.z)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "LoihiCUBANeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyLoihiCUBANeuron {
inner: neurons::LoihiCUBANeuron,
}
#[pymethods]
impl PyLoihiCUBANeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::LoihiCUBANeuron::new(),
}
}
fn step(&mut self, weighted_input: i32) -> i32 {
self.inner.step(weighted_input)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
d.set_item("u", self.inner.u)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "Loihi2Neuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyLoihi2Neuron {
inner: neurons::Loihi2Neuron,
}
#[pymethods]
impl PyLoihi2Neuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::Loihi2Neuron::new(),
}
}
fn step(&mut self, weighted_input: i32) -> i32 {
self.inner.step(weighted_input)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("s1", self.inner.s1)?;
d.set_item("s2", self.inner.s2)?;
d.set_item("s3", self.inner.s3)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "TrueNorthNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyTrueNorthNeuron {
inner: neurons::TrueNorthNeuron,
}
#[pymethods]
impl PyTrueNorthNeuron {
#[new]
#[pyo3(signature = (threshold=100))]
fn new(threshold: i32) -> Self {
Self {
inner: neurons::TrueNorthNeuron::new(threshold),
}
}
fn step(&mut self, weighted_input: i32) -> i32 {
self.inner.step(weighted_input)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
Ok(d.into_any().unbind())
}
}
py_neuron_default!("BrainScaleSAdExNeuron", PyBrainScaleSAdExNeuron, neurons::BrainScaleSAdExNeuron, state v, state w);
py_neuron_default!("SpiNNakerLIFNeuron", PySpiNNakerLIFNeuron, neurons::SpiNNakerLIFNeuron, state v, state refrac_count);
#[pyclass(
name = "SpiNNaker2Neuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PySpiNNaker2Neuron {
inner: neurons::SpiNNaker2Neuron,
}
#[pymethods]
impl PySpiNNaker2Neuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::SpiNNaker2Neuron::new(),
}
}
fn step(&mut self, current: i32) -> i32 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
Ok(d.into_any().unbind())
}
}
py_neuron_default!("DPINeuron", PyDPINeuron, neurons::DPINeuron, state i_mem);
#[pyclass(
name = "AkidaNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyAkidaNeuron {
inner: neurons::AkidaNeuron,
}
#[pymethods]
impl PyAkidaNeuron {
#[new]
#[pyo3(signature = (threshold=100))]
fn new(threshold: i32) -> Self {
Self {
inner: neurons::AkidaNeuron::new(threshold),
}
}
fn step(&mut self, weight: i32) -> i32 {
self.inner.step(weight)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
d.set_item("rank", self.inner.rank)?;
Ok(d.into_any().unbind())
}
}
py_neuron_default!("NeuroGridNeuron", PyNeuroGridNeuron, neurons::NeuroGridNeuron, state v_s, state v_d);
#[pyclass(
name = "McCullochPittsNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyMcCullochPittsNeuron {
inner: neurons::McCullochPittsNeuron,
}
#[pymethods]
impl PyMcCullochPittsNeuron {
#[new]
#[pyo3(signature = (theta=1.0))]
fn new(theta: f64) -> Self {
Self {
inner: neurons::McCullochPittsNeuron::new(theta),
}
}
fn step(&self, weighted_input: f64) -> i32 {
self.inner.step(weighted_input)
}
}
#[pyclass(
name = "SigmoidRateNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PySigmoidRateNeuron {
inner: neurons::SigmoidRateNeuron,
}
#[pymethods]
impl PySigmoidRateNeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::SigmoidRateNeuron::new(),
}
}
fn step(&mut self, current: f64) -> f64 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("r", self.inner.r)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "ThresholdLinearRateNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyThresholdLinearRateNeuron {
inner: neurons::ThresholdLinearRateNeuron,
}
#[pymethods]
impl PyThresholdLinearRateNeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::ThresholdLinearRateNeuron::new(),
}
}
fn step(&mut self, current: f64) -> f64 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
}
#[pyclass(
name = "AstrocyteModel",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyAstrocyteModel {
inner: neurons::AstrocyteModel,
}
#[pymethods]
impl PyAstrocyteModel {
#[new]
fn new() -> Self {
Self {
inner: neurons::AstrocyteModel::new(),
}
}
fn step(&mut self, current: f64) -> f64 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("ca", self.inner.ca)?;
d.set_item("h", self.inner.h)?;
d.set_item("ip3", self.inner.ip3)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "TsodyksMarkramNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyTsodyksMarkramNeuron {
inner: neurons::TsodyksMarkramNeuron,
}
#[pymethods]
impl PyTsodyksMarkramNeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::TsodyksMarkramNeuron::new(),
}
}
#[pyo3(signature = (current, presynaptic_spike=false))]
fn step(&mut self, current: f64, presynaptic_spike: bool) -> i32 {
self.inner.step(current, presynaptic_spike)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
d.set_item("x", self.inner.x)?;
d.set_item("u", self.inner.u)?;
Ok(d.into_any().unbind())
}
}
py_neuron_default!("LiquidTimeConstantNeuron", PyLiquidTimeConstantNeuron, neurons::LiquidTimeConstantNeuron, state x);
#[pyclass(
name = "CompteWMNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyCompteWMNeuron {
inner: neurons::CompteWMNeuron,
}
#[pymethods]
impl PyCompteWMNeuron {
#[new]
fn new() -> Self {
Self {
inner: neurons::CompteWMNeuron::new(),
}
}
#[pyo3(signature = (current, spike_in=false))]
fn step(&mut self, current: f64, spike_in: bool) -> i32 {
self.inner.step(current, spike_in)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
d.set_item("s_nmda", self.inner.s_nmda)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "SiegertTransferFunction",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PySiegertTransferFunction {
inner: neurons::SiegertTransferFunction,
}
#[pymethods]
impl PySiegertTransferFunction {
#[new]
fn new() -> Self {
Self {
inner: neurons::SiegertTransferFunction::new(),
}
}
fn step(&self, current: f64) -> f64 {
self.inner.step(current)
}
}
#[pyclass(
name = "FractionalLIFNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyFractionalLIFNeuron {
inner: neurons::FractionalLIFNeuron,
}
#[pymethods]
impl PyFractionalLIFNeuron {
#[new]
#[pyo3(signature = (alpha=0.8, max_hist=50))]
fn new(alpha: f64, max_hist: usize) -> Self {
Self {
inner: neurons::FractionalLIFNeuron::new(alpha, max_hist),
}
}
fn step(&mut self, current: f64) -> i32 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v)?;
Ok(d.into_any().unbind())
}
}
#[pyclass(
name = "ParallelSpikingNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyParallelSpikingNeuron {
inner: neurons::ParallelSpikingNeuron,
}
#[pymethods]
impl PyParallelSpikingNeuron {
#[new]
#[pyo3(signature = (kernel_size=8, v_threshold=1.0))]
fn new(kernel_size: usize, v_threshold: f64) -> Self {
Self {
inner: neurons::ParallelSpikingNeuron::new(kernel_size, v_threshold),
}
}
fn step(&mut self, current: f64) -> i32 {
self.inner.step(current)
}
fn reset(&mut self) {
self.inner.reset();
}
}
#[pyclass(
name = "AmariNeuralField",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyAmariNeuralField {
inner: neurons::AmariNeuralField,
}
#[pymethods]
impl PyAmariNeuralField {
#[new]
#[pyo3(signature = (n=64))]
fn new(n: usize) -> Self {
Self {
inner: neurons::AmariNeuralField::new(n),
}
}
fn step(&mut self, input: Vec<f64>) -> f64 {
self.inner.step(&input)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray1<f64>> {
self.inner.u.clone().into_pyarray(py)
}
}
pub fn register_neuron_classes(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<PyMultiTimescaleNeuron>()?;
m.add_class::<PyAttentionGatedNeuron>()?;
m.add_class::<PyPredictiveCodingNeuron>()?;
m.add_class::<PySelfReferentialNeuron>()?;
m.add_class::<PyCompositionalBindingNeuron>()?;
m.add_class::<PyDifferentiableSurrogateNeuron>()?;
m.add_class::<PyContinuousAttractorNeuron>()?;
m.add_class::<PyMetaPlasticNeuron>()?;
m.add_class::<PyQuadraticIFNeuron>()?;
m.add_class::<PyThetaNeuron>()?;
m.add_class::<PyPerfectIntegratorNeuron>()?;
m.add_class::<PyGatedLIFNeuron>()?;
m.add_class::<PyNonlinearLIFNeuron>()?;
m.add_class::<PySFANeuron>()?;
m.add_class::<PyMATNeuron>()?;
m.add_class::<PyEscapeRateNeuron>()?;
m.add_class::<PyKLIFNeuron>()?;
m.add_class::<PyInhibitoryLIFNeuron>()?;
m.add_class::<PyComplementaryLIFNeuron>()?;
m.add_class::<PyParametricLIFNeuron>()?;
m.add_class::<PyNonResettingLIFNeuron>()?;
m.add_class::<PyAdaptiveThresholdIFNeuron>()?;
m.add_class::<PySigmaDeltaNeuron>()?;
m.add_class::<PyEnergyLIFNeuron>()?;
m.add_class::<PyIntegerQIFNeuron>()?;
m.add_class::<PyClosedFormContinuousNeuron>()?;
m.add_class::<PyFitzHughNagumoNeuron>()?;
m.add_class::<PyMorrisLecarNeuron>()?;
m.add_class::<PyHindmarshRoseNeuron>()?;
m.add_class::<PyResonateAndFireNeuron>()?;
m.add_class::<PyFitzHughRinzelNeuron>()?;
m.add_class::<PyMcKeanNeuron>()?;
m.add_class::<PyTermanWangOscillator>()?;
m.add_class::<PyBendaHerzNeuron>()?;
m.add_class::<PyAlphaNeuron>()?;
m.add_class::<PyCOBALIFNeuron>()?;
m.add_class::<PyGutkinErmentroutNeuron>()?;
m.add_class::<PyWilsonHRNeuron>()?;
m.add_class::<PyChayNeuron>()?;
m.add_class::<PyChayKeizerNeuron>()?;
m.add_class::<PyShermanRinzelKeizerNeuron>()?;
m.add_class::<PyButeraRespiratoryNeuron>()?;
m.add_class::<PyEPropALIFNeuron>()?;
m.add_class::<PySuperSpikeNeuron>()?;
m.add_class::<PyLearnableNeuronModel>()?;
m.add_class::<PyPernarowskiNeuron>()?;
m.add_class::<PyChialvoMapNeuron>()?;
m.add_class::<PyRulkovMapNeuron>()?;
m.add_class::<PyIbarzTanakaMapNeuron>()?;
m.add_class::<PyMedvedevMapNeuron>()?;
m.add_class::<PyCazellesMapNeuron>()?;
m.add_class::<PyCourageNekorkinMapNeuron>()?;
m.add_class::<PyHodgkinHuxleyNeuron>()?;
m.add_class::<PyTraubMilesNeuron>()?;
m.add_class::<PyWangBuzsakiNeuron>()?;
m.add_class::<PyConnorStevensNeuron>()?;
m.add_class::<PyDestexheThalamicNeuron>()?;
m.add_class::<PyHuberBraunNeuron>()?;
m.add_class::<PyGolombFSNeuron>()?;
m.add_class::<PyPospischilNeuron>()?;
m.add_class::<PyMainenSejnowskiNeuron>()?;
m.add_class::<PyDeSchutterPurkinjeNeuron>()?;
m.add_class::<PyPlantR15Neuron>()?;
m.add_class::<PyPrescottNeuron>()?;
m.add_class::<PyMihalasNieburNeuron>()?;
m.add_class::<PyGLIFNeuron>()?;
m.add_class::<PyGIFPopulationNeuron>()?;
m.add_class::<PyAvRonCardiacNeuron>()?;
m.add_class::<PyDurstewitzDopamineNeuron>()?;
m.add_class::<PyHillTononiNeuron>()?;
m.add_class::<PyBertramPhantomBurster>()?;
m.add_class::<PyYamadaNeuron>()?;
m.add_class::<PyPinskyRinzelNeuron>()?;
m.add_class::<PyHayL5PyramidalNeuron>()?;
m.add_class::<PyMarderSTGNeuron>()?;
m.add_class::<PyRallCableNeuron>()?;
m.add_class::<PyBoothRinzelNeuron>()?;
m.add_class::<PyDendrifyNeuron>()?;
m.add_class::<PyTwoCompartmentLIFNeuron>()?;
m.add_class::<PyPoissonNeuron>()?;
m.add_class::<PyInhomogeneousPoissonNeuron>()?;
m.add_class::<PyGammaRenewalNeuron>()?;
m.add_class::<PyStochasticIFNeuron>()?;
m.add_class::<PyGalvesLocherbachNeuron>()?;
m.add_class::<PySpikeResponseNeuron>()?;
m.add_class::<PyGLMNeuron>()?;
m.add_class::<PyWilsonCowanUnit>()?;
m.add_class::<PyJansenRitUnit>()?;
m.add_class::<PyWongWangUnit>()?;
m.add_class::<PyErmentroutKopellPopulation>()?;
m.add_class::<PyWendlingNeuron>()?;
m.add_class::<PyLarterBreakspearNeuron>()?;
m.add_class::<PyLoihiCUBANeuron>()?;
m.add_class::<PyLoihi2Neuron>()?;
m.add_class::<PyTrueNorthNeuron>()?;
m.add_class::<PyBrainScaleSAdExNeuron>()?;
m.add_class::<PySpiNNakerLIFNeuron>()?;
m.add_class::<PySpiNNaker2Neuron>()?;
m.add_class::<PyDPINeuron>()?;
m.add_class::<PyAkidaNeuron>()?;
m.add_class::<PyNeuroGridNeuron>()?;
m.add_class::<PyMcCullochPittsNeuron>()?;
m.add_class::<PySigmoidRateNeuron>()?;
m.add_class::<PyThresholdLinearRateNeuron>()?;
m.add_class::<PyAstrocyteModel>()?;
m.add_class::<PyTsodyksMarkramNeuron>()?;
m.add_class::<PyLiquidTimeConstantNeuron>()?;
m.add_class::<PyCompteWMNeuron>()?;
m.add_class::<PySiegertTransferFunction>()?;
m.add_class::<PyFractionalLIFNeuron>()?;
m.add_class::<PyParallelSpikingNeuron>()?;
m.add_class::<PyAmariNeuralField>()?;
m.add_class::<PyLeakyCompeteFireNeuron>()?;
m.add_class::<PyArcaneNeuron>()?;
Ok(())
}
#[pyclass(
name = "LeakyCompeteFireNeuron",
module = "sc_neurocore_engine.sc_neurocore_engine"
)]
#[derive(Clone)]
pub struct PyLeakyCompeteFireNeuron {
inner: neurons::LeakyCompeteFireNeuron,
}
#[pymethods]
impl PyLeakyCompeteFireNeuron {
#[new]
#[pyo3(signature = (n_units=4))]
fn new(n_units: usize) -> Self {
Self {
inner: neurons::LeakyCompeteFireNeuron::new(n_units),
}
}
fn step(&mut self, currents: Vec<f64>) -> Vec<i32> {
self.inner.step(¤ts)
}
fn reset(&mut self) {
self.inner.reset();
}
fn get_state(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let d = PyDict::new(py);
d.set_item("v", self.inner.v.clone())?;
Ok(d.into_any().unbind())
}
}