Skip to content

Missed time step(s) for noisy / AC current injection in Brian implementation #445

Description

@appukuttan-shailesh

It was seen that current injection (NoisyCurrentSource and ACSource) failed to invoke the method '_compute()' for a few time intervals. During these intervals (1 or 2 dts) the current injected continued to be that evaluated for the previous time step.

Splitting the if statement in this line: https://github.com/NeuralEnsemble/PyNN/blob/master/pyNN/brian/standardmodels/electrodes.py#L74
and adding a print statement inbetween the two conditions, helps identify this problem. Something like this (continuing from the fix for issue #437):

def _update_current(self):
    if self.running:
        print "s.s.t = ",  simulator.state.t, "\tself.i = ", self.i, "\tself.time[i]*1e3 = ", self.times[self.i]*1e3, "\tdiff = ", (simulator.state.t - (self.times[self.i] * 1e3))
        if simulator.state.t  >= self.times[self.i] * 1e3:
            for cell, idx in zip(self.cell_list, self.indices):
                if not self._is_playable:
                    cell.parent.brian_group.i_inj[idx] = self.amplitudes[self.i] * ampere
                else:
                    cell.parent.brian_group.i_inj[idx] = self._compute(self.times[self.i]) * ampere
            self.i += 1
            if self.i >= len(self.times):
                self.running = False
                if self._is_playable:
                    for cell, idx in zip(self.cell_list, self.indices):
                        cell.parent.brian_group.i_inj[idx] = 0
        else:
            print "_compute() not invoked"

Snippets from some sample outputs for this code are given below:

Note: s.s.t = simulator.state.t

  1. start=50.0, stop=125.0, inj_dt = 0.1, setup(timestep = 0.1), run(200.0)
s.s.t =  49.9 	self.i =  0 	self.time[i]*1e3 =  50.0 	diff =  -0.1
_compute() not invoked
s.s.t =  50.0 	self.i =  0 	self.time[i]*1e3 =  50.0 	diff =  0.0
s.s.t =  50.1 	self.i =  1 	self.time[i]*1e3 =  50.1 	diff =  -7.1054273576e-15
_compute() not invoked
s.s.t =  50.2 	self.i =  1 	self.time[i]*1e3 =  50.1 	diff =  0.1
s.s.t =  50.3 	self.i =  2 	self.time[i]*1e3 =  50.2 	diff =  0.1
  1. start=40.0, stop=125.0, inj_dt = 0.1, setup(timestep = 0.1), run(200.0)
s.s.t =  39.9 	self.i =  0 	self.time[i]*1e3 =  40.0 	diff =  -0.1
_compute() not invoked
s.s.t =  40.0 	self.i =  0 	self.time[i]*1e3 =  40.0 	diff =  0.0
s.s.t =  40.1 	self.i =  1 	self.time[i]*1e3 =  40.1 	diff =  0.0
s.s.t =  40.2 	self.i =  2 	self.time[i]*1e3 =  40.2 	diff =  -1.42108547152e-14
_compute() not invoked
s.s.t =  40.3 	self.i =  2 	self.time[i]*1e3 =  40.2 	diff =  0.1
  1. start=50.0, stop=125.0, inj_dt = 0.01, setup(timestep = 0.01), run(200.0)
s.s.t =  49.99 	self.i =  0 	self.time[i]*1e3 =  50.0 	diff =  -0.00999999999999
_compute() not invoked
s.s.t =  50.0 	self.i =  0 	self.time[i]*1e3 =  50.0 	diff =  0.0
s.s.t =  50.01 	self.i =  1 	self.time[i]*1e3 =  50.01 	diff =  0.0
s.s.t =  50.02 	self.i =  2 	self.time[i]*1e3 =  50.02 	diff =  -7.1054273576e-15
_compute() not invoked
s.s.t =  50.03 	self.i =  2 	self.time[i]*1e3 =  50.02 	diff =  0.00999999999999
  1. start=2.0, stop=4.0, inj_dt = 0.01, setup(timestep = 0.01), run(5.0)
s.s.t =  2.1 	self.i =  10 	self.time[i]*1e3 =  2.1 	diff =  0.0
s.s.t =  2.11 	self.i =  11 	self.time[i]*1e3 =  2.11 	diff =  0.0
s.s.t =  2.12 	self.i =  12 	self.time[i]*1e3 =  2.12 	diff =  -4.4408920985e-16
_compute() not invoked
s.s.t =  2.13 	self.i =  12 	self.time[i]*1e3 =  2.12 	diff =  0.01
s.s.t =  2.14 	self.i =  13 	self.time[i]*1e3 =  2.13 	diff =  0.01
s.s.t =  2.15 	self.i =  14 	self.time[i]*1e3 =  2.14 	diff =  0.01

It can be seen that the issue is due to comparison of floating point numbers, and can be overcome using the concept of EPSILON. This would allows us to set an upper bound on the error due to rounding in floating point arithmetic. Will test the same and update here.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions