Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function getDW(t_pre, t_post) {
if(t_pre <= t_post) {
return a_plus*Math.exp((t_pre - t_post)/tau_plus);
} else {
return -a_minus*Math.exp(-(t_pre - t_post)/tau_minus);
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
class STDPWeights {
constructor(numPre, numPost, tau_plus = 0.02, tau_minus = 0.02, a_plus = 0.01, a_minus = 0.011, g_min = 0, g_max = 1) {
this.numPre = numPre;
this.numPost = numPost;

this.tau_plus = tau_plus;
this.tau_minus = tau_minus;
this.x = times(numPre, 0); // An array with numPre zeros
this.y = times(numPost, 0); // An array with numPost zeros

this.a_plus = a_plus;
this.a_minus = a_minus;

this.g_min = g_min;
this.g_max = g_max;
this.w = times2d(numPre, numPost, 0); // A 2-D array; numPre x numPost zeros (normally would be random)
}
updateWeights(preOutputs, postOutputs) {
const preSpikeIndices = getIndicesGreaterThan0(preOutputs); // Indices of pre-synaptic spiking neurons
const postSpikeIndices = getIndicesGreaterThan0(postOutputs); // Indices of poast-synaptic spiking neurons
// Increment x for spiking pre-synaptic neurons
preSpikeIndices.forEach((ps_idx) => {
this.x[ps_idx] += this.a_plus;
});

// Increment y for spiking poast-synaptic neurons
postSpikeIndices.forEach((ps_idx) => {
this.y[ps_idx] -= this.a_minus;
});
const alpha_g = this.g_max - this.g_min; // Scaling factor for weight updates

// Loop over the *index* of every pre-synaptic neuron that spiked
preSpikeIndices.forEach((ps_idx) => {
// And for every post-synaptic neuron connected to this pre-synaptic neuron, update
// the connection weight by the `y` value for that post-synaptic neuron
for(let i = 0; i<this.numPost; i++) {
this.w[ps_idx][i] += alpha_g * this.y[i];
// Make sure it is between this.g_min and this.g_max
if(this.w[ps_idx][i] < this.g_min) { this.w[ps_idx][i] = this.g_min; } // if less than g_min, set to g_min
if(this.w[ps_idx][i] > this.g_max) { this.w[ps_idx][i] = this.g_max; } // if greater than g_max, set to g_max
}
});



// Loop over the *index* of every post-synaptic neuron that spiked
postSpikeIndices.forEach((ps_idx) => {
// And for every pre-synaptic neuron connected to this post-synaptic neuron, update
// the connection weight by the `x` value for that pre-synaptic neuron
for(let i = 0; i<this.numPre; i++) {
this.w[i][ps_idx] += alpha_g * this.x[i];
// Make sure it is between this.g_min and this.g_max
if(this.w[i][ps_idx] < this.g_min) { this.w[i][ps_idx] = this.g_min; } // if less than g_min, set to g_min
if(this.w[i][ps_idx] > this.g_max) { this.w[i][ps_idx] = this.g_max; } // if greater than g_max, set to g_max
}
});
}
step(t_step) {
// Loop through each value of this.x and decay
for(let i = 0; i<this.x.length; i++) {
this.x[i] = this.x[i] * (1 - t_step/this.tau_plus);
}
// Loop through each value of this.y and decay
for(let i = 0; i<this.y.length; i++) {
this.y[i] = this.y[i] * (1 - t_step/this.tau_minus);
}
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
getDWView(
// Pre-synaptic spikes
[
"x x x x x x",
" x x xxx x ",
],
// Post-synaptic spikes
[
" xx x x ",
" x x x ",
])
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function times(n, funcVal) {
const result = [];
const func = (typeof funcVal === 'function') ? funcVal : (() => funcVal);

for(let i = 0; i<n; i++) {
result.push(func(i));
}
return result;
}
Insert cell
function times2d(n1, n2, funcVal) {
const result = [];
const func = (typeof funcVal === 'function') ? funcVal : (() => funcVal);

for(let i = 0; i<n1; i++) {
const row = [];
for(let j = 0; j<n2; j++) {
row.push(func(i, j));
}
result.push(row);
}
return result;
}
Insert cell
function getIndicesGreaterThan0(arr) {
return arr.map((_, index) => index).filter((index) => arr[index] > 0);
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more