Обеспечить минимальный интервал между ненулевыми элементами в массиве - PullRequest
0 голосов
/ 11 декабря 2018

Я пытаюсь сгенерировать массив нулей и единиц, где интервал между ними распределен по Пуассону.

Я считаю, что этот код помогает:

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)

Однако,Я также хотел бы установить минимальный интервал между ними - например, минимум два нуля между любыми двумя.

Какой эффективный способ сделать это?

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Вот достаточно эффективный способ.Это работает, (1) сначала игнорируя минимальное ожидание.(2) вычисление времени между событиями (3) добавление минимального ожидания, (4) возврат к абсолютному времени, отбрасывание событий, которые были смещены из правого конца.Он может создать 10 ** 7 сэмплов менее чем за секунду.

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
0 голосов
/ 11 декабря 2018

Я думал в этой (не очень элегантной) логике, чтобы сохранить распределение:

def assure_2zeros(l):

    for idx in range(len(l)):
        # detect the problem when the ones are adjacent
        if l[idx] == 1 and l[idx+1] == 1:
            # check forward for a zero that could be realocated to split the ones
            for i in range(idx+2, len(l)-1):
                # check to not create other problems
                if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
                    del l[i]
                    l.insert(idx+1, 0)
                    break
            # if doesnt found any zero forward, check backward
            else:
                for i in range(idx-1, 0, -1):
                    if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
                        del l[i]
                        l.insert(idx+1, 0)
                        break

        # detects the problem when there are one zero between the ones
        if l[idx] == 1 and l[idx+2] == 1:
            for i in range(idx+3, len(l)-1):
                if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
                    del l[i]
                    l.insert(idx+1, 0)
                    break
            else:
                for i in range(idx-1, 0, -1):
                    if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
                        del l[i]
                        l.insert(idx+1, 0)
                        break

    return l

Обратите внимание, что когда есть два смежных, первый, если будет вставлять ноль между ними, тогда он будет вводитьво втором if и второй ноль будут вставлены.Однако, это терпит неудачу, когда есть два или один ноль в самом конце или начале списка.В операторах if можно добавить больше условий, но для вашего случая достаточно нулей, и я думаю, что это может сработать.

...