#%%
import random
from math import log
import matplotlib.pyplot as plt
import numpy as np

class PoissonProcess():
  def __init__(self, **kwargs):
    self.lam = kwargs.get("lam", 5) # rate
    self.size = kwargs.get("size", 100)

  def generate(self):
    _time = 0
    events = []
    for i in range(self.size):
      p = random.random()

      _interval = - log(1-p) / self.lam
      _time = _time + _interval

      events.append(_time)
    return events

#1 (events)
poi = PoissonProcess(lam = 5).generate()
print(poi)

#matplotlib: x=index, y=poi[index]
plt.eventplot(poi)


#2 (points)
poi = np.random.poisson(lam=5,size=100)
print(f"avergae is {np.average(poi)}")

#poi = [i-j for i,j in zip(poi[:-1],poi[1:])]

poi2 = [np.sum(poi[1:i]) for i in range(len(poi))]
# or poin2=np.cumsum(poi)
print(poi2)
#poi = np.diff(poi) # alternative numpy solution for inter-interval durations
#plt.plot(poi2)

plt.show()
#%%

import numpy as np
from scipy.special import factorial

def events_prob(events_per_unit_time, total_time, num_of_events):
  # poisson dist
  lam = events_per_unit_time * total_time
  return np.exp(-lam) * np.power(lam, num_of_events) * factorial(num_of_events)


rate = 5
ks = np.arange(20)
ps = events_prob(5,20,ks)
print(np.argmax(ps), np.max(ps))

#%%


# %%
# Using numpy exp to generate random interarrivals

import numpy as np

duration = 20
rate = 5
size = 2 * rate * duration

inter_arrivals = np.random.exponential(scale = 1/rate, size=size)
arrivals = np.cumsum(inter_arrivals)

spikes = arrivals[np.where(arrivals<duration)]
