Skip to content

Add Liquid State Machine (LSM) model on top of SciMLProblemReservoir #494

Description

@Saswatsusmoy

Motivation

The fellowship roadmap (#397) originally scoped Liquid State Machines as PR5 (weeks 10-11). PR5 has since been redirected to ESN + Universal Differential Equations (per Francesco 2026-07-30), but LSM still deserves a landed implementation on top of the SciMLProblemReservoir + RCODEReservoirExt infrastructure now in place (#446, #450, #456, #479, #480).

Scope: a solid foundation for continuous-time spiking reservoirs — not a demo — with extension seams for future neuron models, encoders, and readouts. Modelled on how ContinuousESN landed.

Architectural principles

  • Neuron model is pluggable via AbstractSpikingNeuron. Ship LIF; future Izhikevich / AdEx / HH slot in without touching the model layer.
  • Input encoding is a first-class abstraction. Ship current-injection + Poisson rate encoders.
  • Readout is a first-class abstraction. Ship spike-count, exponential-filter, and filtered-voltage readouts.
  • E/I structure baked into initializers (Dale-compliant), not just rand_sparse.
  • Callback semantics (refractory, threshold crossing, reset ordering) implemented once, correctly.

Files to add

Core dynamics

  • src/layers/abstract_spiking.jlAbstractSpikingNeuron contract: neuron_rhs!, reset!, spike_condition.
  • src/layers/lif_cell.jlLIFCell <: AbstractSpikingNeuron. Parameters: τ_m, V_rest, V_reset, V_th, τ_ref, R_m.

Connectivity

  • src/inits/inits_lsm.jldale_sparse (E/I-balanced, default 4:1 per Maass), distance_dependent_sparse (optional).

Input encoding

  • src/encoders/abstract_encoder.jlAbstractInputEncoder contract.
  • src/encoders/current_injection.jlCurrentInjection (direct scaled current).
  • src/encoders/poisson_rate.jlPoissonRateEncoder (rate-coded Poisson spikes, RNG state in st.encoder).

Readouts (spike-side)

  • src/readouts/spike_readout.jlAbstractSpikeReadout contract.
  • SpikeCountReadout(window) — binned counts, non-differentiable, ridge-only, teacher-forced only.
  • ExponentialFilterReadout(τ) — leaky low-pass over spike train, smooth, supports AR.
  • FilteredVoltageReadout — samples membrane potential (diagnostics / parity).

Model

  • src/models/lsm.jlLSM(in_dims, res_dims, out_dims; neuron=LIFCell(), encoder=CurrentInjection(), readout=ExponentialFilterReadout(...), connectivity=dale_sparse, kwargs...). Wires into SciMLProblemReservoir with VectorContinuousCallback for threshold crossings + refractory bookkeeping.

Extension wiring

  • ext/RCODEReservoirExt.jl — verify remake preserves callbacks; extend as needed. Compose encoder-driven callbacks + reset callbacks via CallbackSet.

Validation

Unit correctness

  • Single LIF neuron, constant suprathreshold current → analytical ISI within <1% of τ_m·ln((RI − V_rest)/(RI − V_th)).
  • Refractory period enforced exact to callback tolerance.
  • Reset atomic at threshold crossing.
  • dale_sparse E/I ratio + row-sum balance within tolerance.
  • Determinism: same seed → identical spike train.

Network dynamics

  • Rich vs quiet regime demo: W scaling to land mean firing rate in 5–30 Hz for random input.
  • ESP-equivalent: two initializations converge on same input stream (van Rossum spike distance).

End-to-end

  • Regression: Mackey-Glass or Lorenz continuation, same protocol as ContinuousESN tutorial. Report honest NRMSE (expected ~2-3× worse than ContinuousESN at same N — spiking has lower capacity per neuron).
  • Classification: one binary temporal task (pattern discrimination on random spike inputs, or MNIST-1D) with train/test split + baseline.

State-collection parity

  • collectstates(::LSM, ...) returns (state_dims, T) — shape-compatible with ContinuousESN code paths.

Docs

  • docs/src/api/models.md — LSM entry.
  • docs/src/api/layers.mdLIFCell, AbstractSpikingNeuron.
  • docs/src/api/encoders.md — new section (encoders + readouts).
  • docs/src/tutorials/lsm.md — mathematical intro (LIF + Maass framework), one regression + one classification task, capacity caveat vs ContinuousESN.
  • docs/src/refs.bib — Maass 2002, Legenstein & Maass 2007 (edge of chaos), Vreeken 2003 (LSM review), Gerstner & Kistler LIF chapter.

Risks + mitigations

  • Callback × adaptive stepper — rare spike misses on stiff regimes. Default Tsit5 with explicit dtmax = τ_ref/4; document tradeoffs; test suite includes stiff-regime case.
  • Poisson encoder reproducibility. RNG state lives in st.encoder, never in global state.
  • remake + callbacks. Verify SciMLBase behavior early; ship workaround with upstream issue link if broken.
  • AR predict with SpikeCountReadout. No continuous inverse — teacher-forced only, documented in docstring. ExponentialFilterReadout supports AR.

Deferred (extension seams left in place)

Scope

  • ~1500-2500 LOC (code + tests + docs).
  • Single PR (or 2 stacked: infra + model+demos).
  • Estimated ~3 weeks solid work, mirroring ContinuousESN (feat(models): ContinuousESN #456) delivery cadence.

Related: #397 (fellowship tracking).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions