sPyNNaker neural_modelling  development
neuron_model_izh_impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 The University of Manchester
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * https://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
19 #ifndef _NEURON_MODEL_IZH_CURR_IMPL_H_
20 #define _NEURON_MODEL_IZH_CURR_IMPL_H_
21 
22 #include "neuron_model.h"
23 
25 struct neuron_params_t {
26  // nominally 'fixed' parameters
27  REAL A;
28  REAL B;
29  REAL C;
30  REAL D;
31 
32  // Variable-state parameters
33  REAL V;
34  REAL U;
35 
37  REAL I_offset;
38 
41 
44 };
45 
47 struct neuron_t {
48  // nominally 'fixed' parameters
49  REAL A;
50  REAL B;
51  REAL C;
52  REAL D;
53 
54  // Variable-state parameters
55  REAL V;
56  REAL U;
57 
59  REAL I_offset;
60 
63 
66 };
67 
68 static inline void neuron_model_initialise(neuron_t *state, neuron_params_t *params,
69  uint32_t n_steps_per_timestep) {
70  state->A = params->A;
71  state->B = params->B;
72  state->C = params->C;
73  state->D = params->D;
74  state->V = params->V;
75  state->U = params->U;
76  state->I_offset = params->I_offset;
77  state->this_h = params->next_h;
78  state->reset_h = kdivui(params->time_step, n_steps_per_timestep);
79 }
80 
81 static inline void neuron_model_save_state(neuron_t *state, neuron_params_t *params) {
82  params->next_h = state->this_h;
83  params->V = state->V;
84  params->U = state->U;
85 }
86 
91 static const REAL SIMPLE_TQ_OFFSET = REAL_CONST(1.85);
92 
94 #if 0
95 // definition for Izhikevich neuron
96 static inline void neuron_ode(
97  REAL t, REAL stateVar[], REAL dstateVar_dt[],
99  REAL V_now = stateVar[1];
100  REAL U_now = stateVar[2];
101  log_debug(" sv1 %9.4k V %9.4k --- sv2 %9.4k U %9.4k\n", stateVar[1],
102  neuron->V, stateVar[2], neuron->U);
103 
104  // Update V
105  dstateVar_dt[1] =
106  REAL_CONST(140.0)
107  + (REAL_CONST(5.0) + REAL_CONST(0.0400) * V_now) * V_now - U_now
109 
110  // Update U
111  dstateVar_dt[2] = neuron->A * (neuron->B * V_now - U_now);
112 }
113 #endif
114 
119 static const REAL MAGIC_MULTIPLIER = REAL_CONST(0.040008544921875);
120 
129 static inline void rk2_kernel_midpoint(
130  REAL h, neuron_t *neuron, REAL input_this_timestep) {
131  // to match Mathematica names
132  REAL lastV1 = neuron->V;
133  REAL lastU1 = neuron->U;
134  REAL a = neuron->A;
135  REAL b = neuron->B;
136 
137  REAL pre_alph = REAL_CONST(140.0) + input_this_timestep - lastU1;
138  REAL alpha = pre_alph
139  + (REAL_CONST(5.0) + MAGIC_MULTIPLIER * lastV1) * lastV1;
140  REAL eta = lastV1 + REAL_HALF(h * alpha);
141 
142  // could be represented as a long fract?
143  REAL beta = REAL_HALF(h * (b * lastV1 - lastU1) * a);
144 
145  neuron->V += h * (pre_alph - beta
146  + (REAL_CONST(5.0) + MAGIC_MULTIPLIER * eta) * eta);
147 
148  neuron->U += a * h * (-lastU1 - beta + b * eta);
149 }
150 
167  uint16_t num_excitatory_inputs, const input_t *exc_input,
168  uint16_t num_inhibitory_inputs, const input_t *inh_input,
169  input_t external_bias, REAL current_offset, neuron_t *restrict neuron) {
170  REAL total_exc = ZERO;
171  REAL total_inh = ZERO;
172 
173  for (int i =0; i<num_excitatory_inputs; i++) {
174  total_exc += exc_input[i];
175  }
176  for (int i =0; i<num_inhibitory_inputs; i++) {
177  total_inh += inh_input[i];
178  }
179 
180  input_t input_this_timestep = total_exc - total_inh
181  + external_bias + neuron->I_offset + current_offset;
182 
183  // the best AR update so far
184  rk2_kernel_midpoint(neuron->this_h, neuron, input_this_timestep);
185  neuron->this_h = neuron->reset_h;
186 
187  return neuron->V;
188 }
189 
193 static inline void neuron_model_has_spiked(neuron_t *restrict neuron) {
194  // reset membrane voltage
195  neuron->V = neuron->C;
196 
197  // offset 2nd state variable
198  neuron->U += neuron->D;
199 
200  // simple threshold correction - next timestep (only) gets a bump
201  neuron->this_h = neuron->reset_h * SIMPLE_TQ_OFFSET;
202 }
203 
209 static inline state_t neuron_model_get_membrane_voltage(const neuron_t *neuron) {
210  return neuron->V;
211 }
212 
213 static inline void neuron_model_print_state_variables(const neuron_t *neuron) {
214  log_debug("V = %11.4k ", neuron->V);
215  log_debug("U = %11.4k ", neuron->U);
216  log_debug("This h = %11.4k", neuron->this_h);
217 }
218 
219 static inline void neuron_model_print_parameters(const neuron_t *neuron) {
220  log_debug("A = %11.4k ", neuron->A);
221  log_debug("B = %11.4k ", neuron->B);
222  log_debug("C = %11.4k ", neuron->C);
223  log_debug("D = %11.4k ", neuron->D);
224 
225  log_debug("I = %11.4k \n", neuron->I_offset);
226  log_debug("Reset h = %11.4k", neuron->reset_h);
227 }
228 
229 #endif // _NEURON_MODEL_IZH_CURR_IMPL_H_
#define REAL_CONST(x)
Define a constant of type REAL.
Definition: maths-util.h:104
accum REAL
Type used for "real" numbers.
Definition: maths-util.h:91
static REAL kdivui(REAL a, uint32_t b)
Divides an accum by an unsigned integer.
Definition: maths-util.h:258
#define ZERO
A REAL 0.0.
Definition: maths-util.h:123
#define REAL_HALF(x)
Divide by two.
Definition: maths-util.h:202
REAL state_t
The type of a state variable.
REAL input_t
The type of an input.
static uint n_steps_per_timestep
The number of steps to run per timestep.
The API for neuron models themselves.
static void neuron_model_print_state_variables(const neuron_t *neuron)
printout of state variables i.e. those values that might change
static void neuron_model_initialise(neuron_t *state, neuron_params_t *params, uint32_t n_steps_per_timestep)
initialise the structure from the parameters
static void neuron_model_save_state(neuron_t *state, neuron_params_t *params)
save parameters and state back to SDRAM for reading by host and recovery on restart
static void neuron_model_print_parameters(const neuron_t *neuron)
printout of parameters i.e. those values that don't change
static const REAL SIMPLE_TQ_OFFSET
For linear membrane voltages, 1.5 is the correct value. However with actual membrane voltage behaviou...
static state_t neuron_model_get_membrane_voltage(const neuron_t *neuron)
get the neuron membrane voltage for a given neuron parameter set
static state_t neuron_model_state_update(uint16_t num_excitatory_inputs, const input_t *exc_input, uint16_t num_inhibitory_inputs, const input_t *inh_input, input_t external_bias, REAL current_offset, neuron_t *restrict neuron)
primary function called in timer loop after synaptic updates
static void neuron_model_has_spiked(neuron_t *restrict neuron)
Indicates that the neuron has spiked.
static const REAL MAGIC_MULTIPLIER
The original model uses 0.04, but this (1 ULP larger?) gives better numeric stability.
static void rk2_kernel_midpoint(REAL h, neuron_t *neuron, REAL input_this_timestep)
Midpoint is best balance between speed and accuracy so far.
REAL reset_h
timestep to reset to when not just spiked
REAL next_h
next value of this_h (saved)
REAL I_offset
offset current [nA]
UREAL time_step
The timestep of the neuron being used.
REAL this_h
current timestep
REAL I_offset
offset current [nA]
definition of neuron parameters
definition for LIF neuron state
static uint16_t * input_this_timestep
The inputs to be sent at the end of this timestep.
static stdp_params params
Configuration parameters.