Rate models
Rate and WilsonCowan (rate units, same dynamics) and HetRec (stochastic spiking with heterogeneous dendritic time constants).
Rate units: Rate
\[\frac{dx}{dt} = -x + g + I, \qquad r = \tanh(x)\]
Time constant 1 ms, no parameters. $g$ is the input of the step (written by RateSynapse, reset after each step), $I$ an external input. Record :x or :r.
using SpikingNeuralNetworks
SNN.@load_units
R = SNN.Rate(N = 100)
syn = SNN.RateSynapse(R, R; μ = 1.0, p = 0.2)
model = SNN.compose(; R, syn)
SNN.monitor!(R, [:r])
SNN.sim!(model, 50ms)SNNModels.Rate — Type
Rate(; N = 100, name = "Rate", kwargs...)Population of rate units with a tanh transfer function.
Equations
\[\frac{dx}{dt} = -x + g + I, \qquad r = \tanh(x)\]
with $t$ in ms, i.e. the time constant is fixed to 1 ms. $g$ is the input written by RateSynapse ($g_i \mathrel{+}= \sum_j W_{ij} r_j$ each step), $I$ an external input.
Integration
Forward Euler, x += dt * (-x + g + I), then r = tanh(x), then g is set to zero: $g$ is the synaptic input of one step, written by the connections after the population update (RateSynapse adds $W r$, the FORCE connections overwrite it). Use I for a constant input. The population has no fire field, so only :x, :r, :g can be recorded; populations are recorded right after their update, so a recorded :g is zero.
Fields
id::String = randstring(12),name::String = "Rate",param::RateParameter = RateParameter().N::Int32 = 100.VFT = Vector{Float32}: type of the state vectors;Vector{Float64}gives aFloat64population (seefloat_type).x::VFT = 0.5randn(N): internal state.r::VFT = tanh.(x): output rate, in $(-1, 1)$.g::VFT: synaptic input, zeros; the target ofRateSynapse(any target symbol is mapped to:g).I::VFT: external input, zeros.records::Dict.
References
Example
using SpikingNeuralNetworks
SNN.@load_units
R = SNN.Rate(N = 10)
R.I .= 0.5
SNN.monitor!(R, [:r])
SNN.sim!([R]; duration = 20ms)SNNModels.RateParameter — Type
RateParameter <: AbstractPopulationParameterParameter type of the Rate population. It has no fields: the model has a fixed unit time constant and a tanh transfer function. Not exported (SNNModels.RateParameter).
SNNModels.integrate! — Method
integrate!(p::Rate, param::RateParameter, dt)One forward-Euler step of the rate units: x += dt * (-x + g + I), r = tanh(x), then g = 0 (see Rate).
WilsonCowan
Same dynamics as Rate; not the coupled E/I equations of Wilson and Cowan (1972).
using SpikingNeuralNetworks
SNN.@load_units
W = SNN.WilsonCowan(N = 10)
W.I .= 0.2
SNN.monitor!(W, [:r])
SNN.sim!([W]; duration = 20ms)SNNModels.WCParameter — Type
WCParameter <: AbstractPopulationParameterParameter type of WilsonCowan; it has no fields. Not exported (SNNModels.WCParameter).
SNNModels.WilsonCowan — Type
WilsonCowan(; N = 100, name = "WilsonCowan", kwargs...)Population of rate units named after the Wilson-Cowan model. Its dynamics are identical to Rate: a single variable per unit with unit time constant and tanh transfer function. It does not implement the coupled excitatory/inhibitory Wilson-Cowan equations (no separate E and I variables, no refractory term, no sigmoid parameters).
Equations
\[\frac{dx}{dt} = -x + g + I, \qquad r = \tanh(x)\]
($t$ in ms), integrated with forward Euler; g is reset to zero after each step, as in Rate.
Fields
id::String = randstring(12),name::String = "WilsonCowan",param::WCParameter.N::Int32 = 100;x = 0.5randn(N);r = tanh.(x);g,I: inputs, zeros;records::Dict.VFT = Vector{Float32}: type of the state vectors;Vector{Float64}gives aFloat64population (seefloat_type).
RateSynapse (and the FORCE connections) target g, as for Rate (any target symbol is mapped to :g).
References
Wilson H. R., Cowan J. D. (1972). Excitatory and inhibitory interactions in localized populations of model neurons. Biophys. J. 12:1-24 (not implemented in full, see above).
Example
using SpikingNeuralNetworks
SNN.@load_units
W = SNN.WilsonCowan(N = 10)
SNN.monitor!(W, [:r])
SNN.sim!([W]; duration = 20ms)Heterogeneous dendritic timescales: HetRec
Each neuron owns Nd dendrites with time constants sampled from τd; its soma also reads each dendrite of the other neurons with probability overlap. Inputs target the dendrites (:glu, :gaba, size N * Nd).
\[\begin{aligned} \tau_d\, \frac{dv_d}{dt} &= -v_d + g_E - g_I \\ \tau_m\, \frac{dv_s^i}{dt} &= \sum_{d \in \mathcal{D}_i} \left(v_d - v_s^i\right) \\ P(\text{spike of } i \text{ in } dt) &= r_i\, \sigma\!\left(k\, (v_s^i - a_i)\right) dt, \qquad \sigma(x) = \frac{1}{1 + e^{-x}} \end{aligned}\]
$r_i$ (from rate) is the maximal rate, $k$ = steepness, $a_i$ an adaptive baseline (time constant τrate, +1 per spike).
| Field | Default | Units | Meaning |
|---|---|---|---|
Nd | 2 | - | dendrites per neuron |
overlap | 0.5 | - | probability of reading another neuron's dendrite |
τd | Uniform(10, 100) | ms | distribution of dendritic time constants |
rate | Uniform(0, 1) | 1/ms | distribution of maximal rates |
τabs | 5ms | ms | absolute refractory period |
steepness | 1 | 1/mV | slope of the sigmoid |
τm | 20ms | ms | somatic time constant |
τrate | 100ms | ms | time constant of the adaptive baseline |
using SpikingNeuralNetworks
SNN.@load_units
H = SNN.Population(SNN.HetRecParameter(Nd = 3, overlap = 0.2); N = 20)
P = SNN.Poisson(N = 50, param = SNN.PoissonParameter(20Hz))
s = SNN.SpikingSynapse(P, H, :glu; conn = (μ = 1, p = 0.2))
model = SNN.compose(; P, H, s)
SNN.monitor!(H, [:fire, :v_s])
SNN.sim!(model, 200ms)SNNModels.HetRec — Type
Population(param::HetRecParameter; N = 100)
HetRecPopulation of N stochastic spiking neurons, each with param.Nd leaky dendritic compartments with heterogeneous time constants. Create it with Population(HetRecParameter(...); N), which samples τd and r, builds the dendrite-to-soma mapping and the sparse matrix of the mapping.
Input connections target the dendrites: the presynaptic spikes are written into receptors.glu / receptors.gaba (use the target symbols :glu, :gaba; size N * Nd) and filtered by a CurrentSynapse ($τ_e = 6$ ms, $τ_i = 2$ ms).
Equations
For dendrite $d$ and neuron $i$ ($g_E$, $g_I$: exponentially decaying current-based synaptic variables of the CurrentSynapse):
\[\begin{aligned} \tau_d\, \frac{dv_d}{dt} &= -v_d + g_E - g_I \\ \tau_m\, \frac{dv_s^i}{dt} &= \sum_{d \in \mathcal{D}_i} \left(W_{id}\, v_d - v_s^i\right) \\ \tau_{rate}\, \frac{da_i}{dt} &= -a_i + [\text{not refractory}]\,(v_s^i - a_i) + \tau_{rate} \textstyle\sum_f \delta(t - t_i^f) \\ P(\text{spike of } i \text{ in } [t, t + dt]) &= r_i\, \sigma\!\left(k\, (v_s^i - a_i)\right) dt \end{aligned}\]
with $\sigma(x) = 1 / (1 + e^{-x})$, $k$ = steepness, $\mathcal{D}_i$ the dendrites read by neuron $i$ (its own Nd dendrites plus those of other neurons selected with probability overlap, $W_{id} = 1$) and $a_i$ the adaptive baseline trace.
Integration
Per step: synapse update; dendrites v_d += dt * (-v_d - is) / τd with is = -(g_E - g_I); for each neuron, one forward-Euler step of the somatic equation, v_s += dt / τm * Σ_d (W v_d - v_s) (with $k_i$ connected dendrites the soma relaxes to their mean with time constant $τ_m / k_i$); tabs -= 1, fire = false, trace += dt * (-trace / τrate); if not refractory, trace += dt * (v_s - trace) / τrate and the neuron fires with the probability above, which sets tabs = round(Int, τabs / dt) and trace += 1.
Fields
id,name = "HetRec",N::Int32 = 100,param::HetRecParameter.v_d(lengthN * Nd),v_s(lengthN): dendritic and somatic potentials.M::Matrix{Float32}: dense mapping (unused after construction, zeros by default).r: maximal rates (1/ms);fire;tabs;trace: adaptive baseline;randcache.spikes::SpikeIndex: neurons that fired in the step (seespike_index).τd: dendritic time constants (ms).rowptr,colptr,I,J,index,W: CSC representation of the dendrite-to-soma mapping (columns = neurons, rows = dendrites).is: dendritic synaptic current;synapse = CurrentSynapse(),synvars,receptors(sizeN * Nd);records::Dict.
Example
using SpikingNeuralNetworks
SNN.@load_units
H = SNN.Population(SNN.HetRecParameter(Nd = 3, overlap = 0.2); N = 20)
P = SNN.Poisson(N = 50, param = SNN.PoissonParameter(20Hz))
s = SNN.SpikingSynapse(P, H, :glu; conn = (μ = 1, p = 0.2))
model = SNN.compose(; P, H, s)
SNN.monitor!(H, [:fire, :v_s])
SNN.sim!(model, 200ms)SNNModels.HetRecParameter — Type
HetRecParameter(; Nd = 2, overlap = 0.5, τd = Uniform(10, 100), rate = Uniform(0, 1),
τabs = 5ms, steepness = 1, τm = 20ms, τrate = 100ms)Parameters of the HetRec population: stochastic spiking units whose input is filtered by Nd dendritic compartments per neuron with heterogeneous time constants. The docstring of the original code describes it as a heterogeneous-timescale, non-recurrent layer.
Fields
Nd::Int = 2: number of dendritic compartments per neuron (the population hasN * Nddendrites).overlap::Float32 = 0.5: probability that the soma of neuron $i$ also reads dendrite $j$ of another neuron $k \neq i$;0= each soma reads only its ownNddendrites,1= every soma reads all dendrites.τd::Distribution = Uniform(10.0f0, 100.0f0): distribution of the dendritic time constants (ms), one sample per dendrite.rate::Distribution = Uniform(0.0f0, 1.0f0): distribution of the maximal firing rate $r_i$ of each neuron, in spikes per ms (1 = 1 kHz).τabs::Float32 = 5ms: absolute refractory period (ms).steepness::Float32 = 1.0: slope of the sigmoid firing nonlinearity (1/mV).τm::Float32 = 20ms: somatic integration time constant (ms).τrate::Float32 = 100ms: time constant of the adaptive firing baselinetrace(ms).
The number of neurons is not a field: it is the N keyword of Population. Reference not given in the code.