Public
Edited
Feb 21, 2023
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
class Vanilla_LIF {
constructor(tau_rc=0.02, tau_ref=0.2, v0=0, thresh=1) {
this.rc = tau_rc;
this.ref = tau_ref;
this.v = v0;
this.thresh = thresh;
this.output = 0;
this.refractory_time = 0;
}

step(J, dt) {
this.refractory_time -= dt;
let delta_t = dt - this.refractory_time; // How much time passed where we can actually accept input?
if (delta_t < 0 ) { delta_t = 0; } // Make sure it's not negative
if (delta_t > dt) { delta_t = dt; } // Make sure it's not greater than our time step

this.v = J + (this.v - J) * Math.exp(-delta_t/this.rc)

if(this.v > this.thresh) { // Fired
this.output = 1;

this.refractory_time = this.ref;
this.v = 0;
} else {
this.output = 0;
}
return this.output;
}
}
Insert cell
Insert cell
Insert cell
Insert cell
class TensorFlowLIF {
constructor(n = 1, tau_rc=0.02, tau_ref=0.2, thresh=1) {
this.n = n;
this.rc = tf.scalar(tau_rc);
this.ref = tf.scalar(tau_ref);
this.thresh = tf.scalar(thresh);

this.v = tf.variable(tf.zeros([this.n]));
this.output = tf.variable(tf.zeros([this.n]));
this.refractory_time = tf.variable(tf.zeros([this.n]));
}

step(J, dt_num) {
tf.tidy(() => {
const dt = tf.broadcastTo(dt_num, [this.n]);
const refractoryTimesAfterDt = this.refractory_time.sub(dt);
const delta_t = dt.sub(refractoryTimesAfterDt).clipByValue(0, dt_num);
const v_next = tf.add(J, (this.v.sub(J)).mul(tf.exp(delta_t.div(this.rc).neg())));
const spikeMask = tf.greater(v_next, this.thresh);
const nonSpikeMask = tf.lessEqual(v_next, this.thresh);
this.v.assign(v_next.mul(nonSpikeMask)); // zero out non-spiking indices
this.output.assign(spikeMask.mul(1)); // Assign output spikes
this.refractory_time.assign(nonSpikeMask.mul(this.ref));
});
return this.output;
}

dispose() {
tf.dispose([this.rc, this.ref, this.thresh, this.v, this.output, this.refractory_time]);
this.v.dispose();
this.output.dispose();
this.refractory_time.dispose();
}
}
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

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