Search code examples
pythonarraysalgorithmnumpypoisson

Enforce minimum spacing between non-zero elements in array


I'm trying to generate an array of zeroes and ones where the spacing between ones is Poisson-distributed.

I believe this code does the trick:

import numpy as np

dt = 0.05
n_t = 500 / dt  # desired length of array
r = 100
spike_train = (np.random.rand(n_t) < r * dt).astype(int)

However, I'd also like to enforce a minimum spacing between ones -- such as a minimum of two zeroes between any two ones.

What's an efficient way to do this?


Solution

  • Here is a reasonably efficient way. It works by (1) first ignoring the minimum wait. (2) computing inter-event-times (3) adding the minimum wait,(4) going back to absolute times discarding events that have been shifted out the right end. It can create 10**7 samples in less than a second.

    import numpy as np
    
    def train(T, dt, rate, min_wait):
        p = dt*rate
        # correct for minimum wait
        if p:
            p = 1 / (1 / p - min_wait) 
        if p > 0.1:
            print("warning: probability too high for approximation to be good")
        n = int(np.ceil(T/dt))
        raw_times, = np.where(np.random.random(n) < p)
        raw_times[1:] += min_wait - raw_times[:-1]
        good_times = raw_times.cumsum()
        cut = good_times.searchsorted(n)
        result = np.zeros(n, int)
        result[good_times[:cut]] = 1
        return result