sPyNNaker neural_modelling  7.4.2
timing_pfister_triplet_impl.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 
26 #ifndef _TIMING_PFISTER_TRIPLET_IMPL_H_
27 #define _TIMING_PFISTER_TRIPLET_IMPL_H_
28 
29 //---------------------------------------
30 // Structures
31 //---------------------------------------
33 typedef struct post_trace_t {
34  int16_t o1;
35  int16_t o2;
36  uint32_t last_spike_time;
37 } post_trace_t;
38 
40 typedef struct pre_trace_t {
41  int16_t r1;
42  int16_t r2;
43 } pre_trace_t;
44 
46 #include "timing.h"
48 
49 // Include debug header for log_info etc
50 #include <debug.h>
51 
52 // Include generic plasticity maths functions
55 
56 //---------------------------------------
57 // Externals
58 //---------------------------------------
61 extern int16_lut *tau_x_lookup;
62 extern int16_lut *tau_y_lookup;
63 
64 //---------------------------------------
65 // Timing dependence inline functions
66 //---------------------------------------
70  return (post_trace_t) {.o1 = 0, .o2 = 0};
71 }
72 
73 static inline post_trace_t timing_decay_post(
74  uint32_t time, uint32_t last_time, post_trace_t last_trace) {
75  // Get time since last spike
76  uint32_t delta_time = time - last_time;
77 
78  // Decay previous o1 trace
79  int32_t decayed_o1 = STDP_FIXED_MUL_16X16(last_trace.o1,
81 
82  // If we have already added on the last spike effect, just decay
83  // (as it's sampled BEFORE the spike),
84  // otherwise, add on energy caused by last spike and decay that
85  int32_t new_o2 = 0;
86  int32_t next_spike_time = last_trace.last_spike_time;
87  if (last_trace.last_spike_time == 0) {
88  int32_t decay = maths_lut_exponential_decay(delta_time, tau_y_lookup);
89  new_o2 = STDP_FIXED_MUL_16X16(last_trace.o2, decay);
90  } else {
91  uint32_t o2_delta = time - last_trace.last_spike_time;
92  int32_t decay = maths_lut_exponential_decay(o2_delta, tau_y_lookup);
93  new_o2 = STDP_FIXED_MUL_16X16(last_trace.o2 + STDP_FIXED_POINT_ONE, decay);
94  next_spike_time = 0;
95  }
96  return (post_trace_t) {.o1 = decayed_o1, .o2 = new_o2,
97  .last_spike_time = next_spike_time};
98 }
99 
100 //---------------------------------------
107  uint32_t time, uint32_t last_time, post_trace_t last_trace) {
108 
109  post_trace_t next_trace = timing_decay_post(time, last_time, last_trace);
110  next_trace.o1 += STDP_FIXED_POINT_ONE;
111  next_trace.last_spike_time = time;
112 
113  // Return new pre- synaptic event with decayed trace values with energy
114  // for new spike added
115  return next_trace;
116 }
117 
118 //---------------------------------------
125  uint32_t time, uint32_t last_time, pre_trace_t last_trace) {
126  // Get time since last spike
127  uint32_t delta_time = time - last_time;
128 
129  // Decay previous r1 trace and add energy caused by new spike
130  int32_t decayed_r1 = STDP_FIXED_MUL_16X16(last_trace.r1,
132  int32_t new_r1 = decayed_r1 + STDP_FIXED_POINT_ONE;
133 
134  // If this is the 1st pre-synaptic event, r2 trace is zero
135  // (as it's sampled BEFORE the spike),
136  // otherwise, add on energy caused by last spike and decay that
137  int32_t new_r2 = (last_time == 0) ? 0 :
139  last_trace.r2 + STDP_FIXED_POINT_ONE,
141 
142  log_debug("\tdelta_time=%u, r1=%d, r2=%d\n", delta_time, new_r1, new_r2);
143 
144  // Return new pre-synaptic event with decayed trace values with energy
145  // for new spike added
146  return (pre_trace_t) {.r1 = new_r1, .r2 = new_r2};
147 }
148 
149 //---------------------------------------
160  uint32_t time, pre_trace_t trace, UNUSED uint32_t last_pre_time,
161  UNUSED pre_trace_t last_pre_trace, uint32_t last_post_time,
162  post_trace_t last_post_trace, update_state_t previous_state) {
163  // Get time of event relative to last post-synaptic event
164  uint32_t time_since_last_post = time - last_post_time;
165  int32_t decayed_o1 = STDP_FIXED_MUL_16X16(last_post_trace.o1,
166  maths_lut_exponential_decay(time_since_last_post, tau_minus_lookup));
167 
168  // Calculate triplet term
169  int32_t decayed_o1_r2 = STDP_FIXED_MUL_16X16(decayed_o1, trace.r2);
170 
171  log_debug("\t\t\ttime_since_last_post_event=%u, decayed_o1=%d, r2=%d,"
172  "decayed_o1_r2=%d\n",
173  time_since_last_post, decayed_o1, trace.r2, decayed_o1_r2);
174 
175  // Apply depression to state (which is a weight_state)
177  previous_state, decayed_o1, decayed_o1_r2);
178 }
179 
180 //---------------------------------------
191  uint32_t time, post_trace_t trace, uint32_t last_pre_time,
192  pre_trace_t last_pre_trace, UNUSED uint32_t last_post_time,
193  UNUSED post_trace_t last_post_trace, update_state_t previous_state) {
194  // Get time of event relative to last pre-synaptic event
195  uint32_t time_since_last_pre = time - last_pre_time;
196  if (time_since_last_pre > 0) {
197  int32_t decayed_r1 = STDP_FIXED_MUL_16X16(last_pre_trace.r1,
198  maths_lut_exponential_decay(time_since_last_pre, tau_plus_lookup));
199 
200  // Calculate triplet term
201  int32_t decayed_r1_o2 = STDP_FIXED_MUL_16X16(decayed_r1, trace.o2);
202 
203  log_debug("\t\t\ttime_since_last_pre_event=%u, decayed_r1=%d, o2=%d,"
204  "decayed_r1_o2=%d\n",
205  time_since_last_pre, decayed_r1, trace.o2, decayed_r1_o2);
206 
207  // Apply potentiation to state (which is a weight_state)
209  previous_state, decayed_r1, decayed_r1_o2);
210  } else {
211  return previous_state;
212  }
213 }
214 
215 #endif // PFISTER_TRIPLET_IMPL_H
#define decay(x, d)
This is a type-generic decay "function".
Definition: decay.h:118
static uint32_t time
Simulation time.
uint32_t last_time
The time of the most recently-considered spike.
Support functions for STDP.
static int32_t maths_lut_exponential_decay(uint32_t time, const int16_lut *lut)
Get value from lookup table.
Definition: maths.h:79
Lookup Table of 16-bit integers.
Definition: maths.h:44
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
#define STDP_FIXED_MUL_16X16(a, b)
Multiply two STDP fixed point numbers.
Definition: stdp_typedefs.h:38
Synapses just hold weight.
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.
int16_t post_trace_t
The type of post-spike traces.
int16_t pre_trace_t
The type of pre-spike traces.
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.
int16_lut * tau_x_lookup
Lookup table for τx exponential decay.
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.
int16_lut * tau_minus_lookup
Lookup table for τ- exponential decay.
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.
static post_trace_t timing_get_initial_post_trace(void)
Get an initial post-synaptic timing trace.
int16_lut * tau_plus_lookup
Lookup table for τ+ exponential decay.
int16_lut * tau_y_lookup
Lookup table for τy exponential decay.
The type of post-spike traces.
The type of pre-spike traces.
static weight_state_t weight_two_term_apply_depression(weight_state_t state, int32_t a2_minus, int32_t a3_minus)
Apply the depression rule to the weight state.
static weight_state_t weight_two_term_apply_potentiation(weight_state_t state, int32_t a2_plus, int32_t a3_plus)
Apply the potentiation rule to the weight state.
API for dual-term weight dependence rules.