diff options
author | Mario Mulansky <mario.mulansky@gmx.net> | 2015-01-28 16:53:48 +0100 |
---|---|---|
committer | Mario Mulansky <mario.mulansky@gmx.net> | 2015-01-28 16:53:48 +0100 |
commit | deb1fb51359085ff5d171e5ffa8cd4c142a4e174 (patch) | |
tree | 571208ee90a5079beb8d70f7b6874012f8796fa1 /pyspike | |
parent | 27121e76e92a244c484b970f61da990eff19dc1d (diff) |
added smoothing functionality to spike sync
Diffstat (limited to 'pyspike')
-rw-r--r-- | pyspike/function.py | 69 |
1 files changed, 62 insertions, 7 deletions
diff --git a/pyspike/function.py b/pyspike/function.py index e0dadf6..047c88a 100644 --- a/pyspike/function.py +++ b/pyspike/function.py @@ -397,10 +397,13 @@ class DiscreteFunction(object): np.allclose(self.y, other.y, atol=eps, rtol=0.0) and \ np.allclose(self.mp, other.mp, atol=eps, rtol=0.0) - def get_plottable_data(self, k=0): - """ Returns two arrays containing x- and y-coordinates for immeditate - plotting of the interval sequence. + def get_plottable_data(self, averaging_window_size=0): + """ Returns two arrays containing x- and y-coordinates for plotting + the interval sequence. The optional parameter `averaging_window_size` + determines the size of an averaging window to smoothen the profile. If + this value is 0, no averaging is performed. + :param averaging_window_size: size of the averaging window, default=0. :returns: (x_plot, y_plot) containing plottable data :rtype: pair of np.array @@ -410,10 +413,62 @@ class DiscreteFunction(object): plt.plot(x, y, '-o', label="Discrete function") """ - if k > 0: - raise NotImplementedError() - - return 1.0*self.x, 1.0*self.y/self.mp + if averaging_window_size > 0: + # for the averaged profile we have to take the multiplicity into + # account. values with higher multiplicity should be consider as if + # they appeared several times. Hence we can not know how many + # entries we have to consider to the left and right. Rather, we + # will iterate until some wanted multiplicity is reached. + + # the first value in self.mp contains the number of averaged + # profiles without any possible extra multiplicities + # (by implementation) + expected_mp = (averaging_window_size+1) * int(self.mp[0]) + y_plot = np.zeros_like(self.y) + # compute the values in a loop, could be done in cython if required + for i in xrange(len(y_plot)): + + if self.mp[i] >= expected_mp: + # the current value contains already all the wanted + # multiplicity + y_plot[i] = self.y[i]/self.mp[i] + continue + + # first look to the right + y = self.y[i] + mp_r = self.mp[i] + j = i+1 + while j < len(y_plot): + if mp_r+self.mp[j] < expected_mp: + # if we still dont reach the required multiplicity + # we take the whole value + y += self.y[j] + mp_r += self.mp[j] + else: + # otherwise, just some fraction + y += self.y[j] * (expected_mp - mp_r)/self.mp[j] + mp_r += (expected_mp - mp_r) + break + j += 1 + + # same story to the left + mp_l = self.mp[i] + j = i-1 + while j >= 0: + if mp_l+self.mp[j] < expected_mp: + y += self.y[j] + mp_l += self.mp[j] + else: + y += self.y[j] * (expected_mp - mp_l)/self.mp[j] + mp_l += (expected_mp - mp_l) + break + j -= 1 + y_plot[i] = y/(mp_l+mp_r-self.mp[i]) + return 1.0*self.x, y_plot + + else: # k = 0 + + return 1.0*self.x, 1.0*self.y/self.mp def integral(self, interval=None): """ Returns the integral over the given interval. For the discrete |