Spaces:
Sleeping
Sleeping
Download src/core/neuron_models.py from ThomasHeisig/MHRN-Space: direct link, hf CLI and curl.
- Browser
- Download file 5.73 kB
-
https://huggingface.co/spaces/ThomasHeisig/MHRN-Space/resolve/main/src/core/neuron_models.py
- Command line
-
hf download hf://spaces/ThomasHeisig/MHRN-Space/src/core/neuron_models.py
-
curl -L -o neuron_models.py https://huggingface.co/spaces/ThomasHeisig/MHRN-Space/resolve/main/src/core/neuron_models.py
5.73 kB
| """Versioned, deterministic single-neuron dynamics models for MHRN. | |
| The registry in this module is deliberately small. A model is added only when | |
| its transition equations, spike rule, reset rule and version are explicit. | |
| This keeps model selection a scientific treatment rather than an untracked | |
| implementation detail. | |
| """ | |
| from __future__ import annotations | |
| from dataclasses import dataclass | |
| from enum import Enum | |
| from typing import Final | |
| class NeuronModel(str, Enum): | |
| """Implemented membrane-dynamics model families.""" | |
| IZHIKEVICH = "izhikevich-2003" | |
| LEAKY_INTEGRATE_AND_FIRE = "lif-current-v1" | |
| class NeuronModelDescriptor: | |
| """Stable provenance metadata for one implemented dynamics model.""" | |
| model: NeuronModel | |
| version: str | |
| family: str | |
| state_variables: tuple[str, ...] | |
| integration_rule: str | |
| spike_rule: str | |
| reset_rule: str | |
| canonical: bool | |
| citation: str | |
| def to_dict(self) -> dict[str, object]: | |
| return { | |
| "model": self.model.value, | |
| "version": self.version, | |
| "family": self.family, | |
| "state_variables": list(self.state_variables), | |
| "integration_rule": self.integration_rule, | |
| "spike_rule": self.spike_rule, | |
| "reset_rule": self.reset_rule, | |
| "canonical": self.canonical, | |
| "citation": self.citation, | |
| } | |
| MODEL_REGISTRY: Final[dict[NeuronModel, NeuronModelDescriptor]] = { | |
| NeuronModel.IZHIKEVICH: NeuronModelDescriptor( | |
| model=NeuronModel.IZHIKEVICH, | |
| version="mhrn-1.0", | |
| family="quadratic integrate-and-fire with recovery variable", | |
| state_variables=("v", "u"), | |
| integration_rule="two half Euler steps for v, one Euler step for u", | |
| spike_rule="v >= 30 mV plus optional adaptive threshold offset", | |
| reset_rule="v = c; u = u + d", | |
| canonical=True, | |
| citation=( | |
| "E. M. Izhikevich, Simple model of spiking neurons, " | |
| "IEEE Transactions on Neural Networks 14(6), 2003, " | |
| "doi:10.1109/TNN.2003.820440" | |
| ), | |
| ), | |
| NeuronModel.LEAKY_INTEGRATE_AND_FIRE: NeuronModelDescriptor( | |
| model=NeuronModel.LEAKY_INTEGRATE_AND_FIRE, | |
| version="mhrn-1.0", | |
| family="current-based leaky integrate-and-fire", | |
| state_variables=("v",), | |
| integration_rule="forward Euler membrane leak/current integration", | |
| spike_rule="v >= configured lif_threshold plus optional adaptation", | |
| reset_rule="v = configured lif_reset", | |
| canonical=False, | |
| citation="Reference current-based LIF implementation; model parameters are persisted.", | |
| ), | |
| } | |
| _MODEL_ALIASES: Final[dict[str, NeuronModel]] = { | |
| "izhikevich": NeuronModel.IZHIKEVICH, | |
| "izhikevich-2003": NeuronModel.IZHIKEVICH, | |
| "izh": NeuronModel.IZHIKEVICH, | |
| "lif": NeuronModel.LEAKY_INTEGRATE_AND_FIRE, | |
| "leaky-integrate-and-fire": NeuronModel.LEAKY_INTEGRATE_AND_FIRE, | |
| "lif-current-v1": NeuronModel.LEAKY_INTEGRATE_AND_FIRE, | |
| } | |
| def coerce_neuron_model(value: NeuronModel | str) -> NeuronModel: | |
| """Resolve a model enum or documented alias to a stable model identifier.""" | |
| if isinstance(value, NeuronModel): | |
| return value | |
| key = str(value).strip().lower() | |
| try: | |
| return _MODEL_ALIASES[key] | |
| except KeyError as exc: | |
| supported = ", ".join(model.value for model in NeuronModel) | |
| raise ValueError( | |
| f"Unknown neuron model {value!r}; supported: {supported}" | |
| ) from exc | |
| def get_model_descriptor(value: NeuronModel | str) -> NeuronModelDescriptor: | |
| """Return immutable provenance metadata for an implemented model.""" | |
| return MODEL_REGISTRY[coerce_neuron_model(value)] | |
| def available_neuron_models() -> tuple[NeuronModelDescriptor, ...]: | |
| """Return model descriptors in stable enum order.""" | |
| return tuple(MODEL_REGISTRY[model] for model in NeuronModel) | |
| def integrate_membrane( | |
| model: NeuronModel | str, | |
| *, | |
| v: float, | |
| u: float, | |
| input_current: float, | |
| dt_ms: float, | |
| a: float, | |
| b: float, | |
| lif_resting_potential: float, | |
| lif_tau_m_ms: float, | |
| lif_resistance: float, | |
| ) -> tuple[float, float]: | |
| """Advance only membrane-model state by one deterministic time step.""" | |
| selected = coerce_neuron_model(model) | |
| if selected is NeuronModel.IZHIKEVICH: | |
| half_dt = 0.5 * dt_ms | |
| v += half_dt * (0.04 * v * v + 5.0 * v + 140.0 - u + input_current) | |
| v += half_dt * (0.04 * v * v + 5.0 * v + 140.0 - u + input_current) | |
| u += dt_ms * a * (b * v - u) | |
| return v, u | |
| dv = ((lif_resting_potential - v) + lif_resistance * input_current) * ( | |
| dt_ms / lif_tau_m_ms | |
| ) | |
| return v + dv, u | |
| def spike_threshold( | |
| model: NeuronModel | str, | |
| *, | |
| izhikevich_threshold: float, | |
| lif_threshold: float, | |
| ) -> float: | |
| """Return the non-adaptive spike threshold for a model.""" | |
| selected = coerce_neuron_model(model) | |
| if selected is NeuronModel.IZHIKEVICH: | |
| return izhikevich_threshold | |
| return lif_threshold | |
| def apply_spike_reset( | |
| model: NeuronModel | str, | |
| *, | |
| v: float, | |
| u: float, | |
| c: float, | |
| d: float, | |
| lif_reset: float, | |
| ) -> tuple[float, float]: | |
| """Apply the model-specific state transition immediately after a spike.""" | |
| selected = coerce_neuron_model(model) | |
| if selected is NeuronModel.IZHIKEVICH: | |
| return c, u + d | |
| return lif_reset, u | |
| __all__ = [ | |
| "MODEL_REGISTRY", | |
| "NeuronModel", | |
| "NeuronModelDescriptor", | |
| "apply_spike_reset", | |
| "available_neuron_models", | |
| "coerce_neuron_model", | |
| "get_model_descriptor", | |
| "integrate_membrane", | |
| "spike_threshold", | |
| ] | |