sPyNNaker neural_modelling  7.4.2
timing_recurrent_common.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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 
22 #ifndef _TIMING_RECURRENT_COMMON_H_
23 #define _TIMING_RECURRENT_COMMON_H_
24 
25 #include "timing.h"
27 
28 // Include debug header for log_info etc
29 #include <debug.h>
30 
31 // Include generic plasticity maths functions
34 
35 #include "random_util.h"
36 
42  uint32_t time_since_last_event, update_state_t previous_state);
43 
49  uint32_t time_since_last_event, update_state_t previous_state);
50 
55  update_state_t previous_state);
56 
61  update_state_t previous_state);
62 
68 };
69 
70 //---------------------------------------
71 // Timing dependence functions
72 //---------------------------------------
73 
74 static inline void _no_op(void) {
75 }
76 
80  return (post_trace_t){};
81 }
82 
83 static inline post_trace_t timing_decay_post(
84  UNUSED uint32_t time, UNUSED uint32_t last_time,
85  UNUSED post_trace_t last_trace) {
86  return (post_trace_t) {};
87 }
88 
89 //---------------------------------------
96  UNUSED uint32_t time, UNUSED uint32_t last_time, UNUSED post_trace_t last_trace) {
97  // Return new pre- synaptic event with decayed trace values with energy
98  // for new spike added
99  return (post_trace_t) {};
100 }
101 
102 //---------------------------------------
109  UNUSED uint32_t time, UNUSED uint32_t last_time, UNUSED pre_trace_t last_trace) {
110 
111  return (pre_trace_t){};
112 }
113 
114 //---------------------------------------
125  uint32_t time, UNUSED pre_trace_t trace, uint32_t last_pre_time,
126  UNUSED pre_trace_t last_pre_trace, uint32_t last_post_time,
127  UNUSED post_trace_t last_post_trace, update_state_t previous_state) {
128  bool update_state = false;
129  switch (previous_state.state) {
130  case STATE_IDLE:
131  // If we're idle, transition to pre-open state
132  previous_state.state = STATE_PRE_OPEN;
133  update_state = true;
134  break;
135  case STATE_PRE_OPEN:
136  // If we're in pre-open state
137  _no_op(); // <<< empty statement for C syntax reasons
138  // Get time of event relative to last pre-synaptic event
139  uint32_t time_since_last_pre = time - last_pre_time;
140 
141  if (timing_recurrent_in_pre_window(time_since_last_pre, previous_state)) {
142  // If pre-window is still open
143  previous_state.state = STATE_IDLE;
144  } else {
145  // Otherwise, leave state alone (essentially re-opening window)
146  update_state = true;
147  }
148  break;
149  case STATE_POST_OPEN:
150  // Otherwise, if we're in post-open
151  _no_op(); // <<< empty statement for C syntax reasons
152  // Get time of event relative to last post-synaptic event
153  uint32_t time_since_last_post = time - last_post_time;
154 
155  log_debug("\tTime_since_last_post_event=%u", time_since_last_post);
156 
158  time_since_last_post, previous_state)) {
160 
161  // Otherwise, if post-window is still open
162  if (previous_state.accumulator >
164  // If accumulator's not going to hit depression limit, decrement
165  // it
166  previous_state.accumulator--;
167  log_debug("\t\tDecrementing accumulator=%d",
168  previous_state.accumulator);
169  } else {
170  // Otherwise, reset accumulator and apply depression
171  previous_state.accumulator = 0;
173  previous_state.weight_state, STDP_FIXED_POINT_ONE);
174  }
175 
176  // Transition back to idle
177  previous_state.state = STATE_IDLE;
178  } else {
179  // Otherwise, if post-window has closed, skip idle state and go
180  // straight to pre-open
181  previous_state.state = STATE_PRE_OPEN;
182  update_state = true;
183  }
184  break;
185  default:
186  log_debug("\tInvalid state %u", previous_state.state);
187  }
188 
189  if (update_state) {
190  previous_state = timing_recurrent_calculate_pre_window(previous_state);
191  }
192 
193  return previous_state;
194 }
195 
196 //---------------------------------------
207  uint32_t time, UNUSED post_trace_t trace, uint32_t last_pre_time,
208  UNUSED pre_trace_t last_pre_trace, uint32_t last_post_time,
209  UNUSED post_trace_t last_post_trace, update_state_t previous_state) {
210  bool update_state = false;
211  switch (previous_state.state) {
212  case STATE_IDLE:
213  // If we're idle, transition to post-open state
214  previous_state.state = STATE_POST_OPEN;
215  update_state = true;
216  break;
217  case STATE_POST_OPEN:
218  // If we're in post-open state
219  _no_op(); // <<< empty statement for C syntax reasons
220  // Get time of event relative to last post-synaptic event
221  uint32_t time_since_last_post = time - last_post_time;
222 
224  time_since_last_post, previous_state)) {
225  // If post window's still open
226  previous_state.state = STATE_IDLE;
227  } else {
228  // Otherwise, leave state alone (essentially re-opening window)
229  update_state = true;
230  }
231  break;
232  case STATE_PRE_OPEN:
233  // Otherwise, if we're in pre-open
234  _no_op(); // <<< empty statement for C syntax reasons
235  // Get time of event relative to last pre-synaptic event
236  uint32_t time_since_last_pre = time - last_pre_time;
237 
238  log_debug("\tTime_since_last_pre_event=%u", time_since_last_pre);
239 
240  if (time_since_last_pre == 0) {
241  // If post-synaptic spike occurred at the same time, ignore it
242 
243  // Transition back to idle
244  previous_state.state = STATE_IDLE;
246  time_since_last_pre, previous_state)) {
248 
249  // Otherwise, if pre-window's still open
250  if (previous_state.accumulator <
252  // If accumulator's not going to hit potentiation limit,
253  // increment it
254  previous_state.accumulator++;
255  log_debug("\t\tIncrementing accumulator=%d",
256  previous_state.accumulator);
257  } else {
258  // Otherwise, reset accumulator and apply potentiation
259  previous_state.accumulator = 0;
261  previous_state.weight_state, STDP_FIXED_POINT_ONE);
262  }
263 
264  // Transition back to idle
265  previous_state.state = STATE_IDLE;
266  } else {
267  // Otherwise, if post-window has closed, skip idle state and go
268  // straight to pre-open
269  previous_state.state = STATE_POST_OPEN;
270  update_state = true;
271  }
272  break;
273  default:
274  log_debug("\tInvalid state %u", previous_state.state);
275  }
276 
277  if (update_state) {
278  previous_state = timing_recurrent_calculate_post_window(previous_state);
279  }
280 
281  return previous_state;
282 }
283 
284 #endif// _TIMING_RECURRENT_COMMON_H_
static uint32_t time
Simulation time.
uint32_t last_time
The time of the most recently-considered spike.
Support functions for STDP.
Utility function for random number generation.
Basic definitions for STDP.
#define STDP_FIXED_POINT_ONE
The number 1.0 in the fixed point math used by STDP.
Definition: stdp_typedefs.h:31
weight_state_t weight_state
The weight staet.
int32_t accumulator
The accumulator (in ARM-friendly format)
API for timing rules.
static post_trace_t timing_decay_post(uint32_t time, uint32_t last_time, post_trace_t last_trace)
Evolve the post trace without adding a spike.
static post_trace_t timing_add_post_spike(uint32_t time, uint32_t last_time, post_trace_t last_trace)
Add a post spike to the post trace.
static update_state_t timing_apply_pre_spike(uint32_t time, pre_trace_t trace, uint32_t last_pre_time, pre_trace_t last_pre_trace, uint32_t last_post_time, post_trace_t last_post_trace, update_state_t previous_state)
Apply a pre-spike timing rule state update.
static pre_trace_t timing_add_pre_spike(uint32_t time, uint32_t last_time, pre_trace_t last_trace)
Add a pre spike to the pre trace.
static update_state_t timing_recurrent_calculate_post_window(update_state_t previous_state)
API: Update the state with the post-window information.
static update_state_t timing_recurrent_calculate_pre_window(update_state_t previous_state)
API: Update the state with the pre-window information.
static bool timing_recurrent_in_pre_window(uint32_t time_since_last_event, update_state_t previous_state)
API: Check if there was an event in the pre-window.
static update_state_t timing_apply_post_spike(uint32_t time, post_trace_t trace, uint32_t last_pre_time, pre_trace_t last_pre_trace, uint32_t last_post_time, post_trace_t last_post_trace, update_state_t previous_state)
Apply a post-spike timing rule state update.
recurrent_state_machine_state_t
Synapse states.
@ STATE_POST_OPEN
Post-window is open.
@ STATE_IDLE
Initial state; neither window is open.
@ STATE_PRE_OPEN
Pre-window is open.
static post_trace_t timing_get_initial_post_trace(void)
Get an initial post-synaptic timing trace.
static bool timing_recurrent_in_post_window(uint32_t time_since_last_event, update_state_t previous_state)
API: Check if there was an event in the post-window.
plasticity_trace_region_data_t plasticity_trace_region_data
Global plasticity parameter data.
The type of post-spike traces.
The type of pre-spike traces.
int32_t accumulator_potentiation_minus_one
Threshold below which we won't hit potentiation trigger after increment.
int32_t accumulator_depression_plus_one
Threshold above which we won't hit depression trigger after decrement.
Configuration information about plasticity traces.
static weight_state_t weight_one_term_apply_depression(weight_state_t state, int32_t a2_minus)
Apply the depression rule to the weight state.
static weight_state_t weight_one_term_apply_potentiation(weight_state_t state, int32_t a2_plus)
Apply the potentiation rule to the weight state.
API for single-term weight dependence rules.