# Goal: approximate true Poisson as limit of Binomial distributions
# simulate binomial distribution
def binom(n,p):
"""Sample from Binomial(n,p) distribution. Number of heads
when flip n coins (each with prob p of landing heads)."""
run_sum = 0 # running total of number of heads so far
for i in range(n):
if random()<p: # random() generates uniform r.v. in (0,1)
# get here with probability p
run_sum += 1 # increase count of heads so far
return run_sum
import matplotlib.pyplot as plt
plt.hist([binom(1,1/2) for i in range(1000)])
import matplotlib.pyplot as plt
plt.hist([binom(3,1/4) for i in range(1000)])
import matplotlib.pyplot as plt
plt.hist([binom(100,1/4) for i in range(10000)], bins=range(10,45), align="left", rwidth=0.5)
# if we take binom(n,p), for some fixed p, as n gets large converges to
# normal distribution (Central Limit Theorem)
# Get Poisson(lam) distribution by taking limit of binom(n,lam/n),
# as n-> infinity
lam=3.0 # lambda, intensity of Poisson distribution
n=100
plt.hist([binom(n,lam/n) for i in range(10000)], bins=range(0,15), align="left", rwidth=0.5)
lam=3.0 # lambda, intensity of Poisson distribution
n=1000
plt.hist([binom(n,lam/n) for i in range(10000)], bins=range(0,15), align="left", rwidth=0.5)
# Observation: the above two distributions (n=100,1000) are very close
# Suggest that as n-> infinity, the disributions binom(n,lam/n)
# converge to some limiting distribution.
# This limit is the Poisson distribution.
# Try out different values of lam
lam=1.0 # lambda, intensity of Poisson distribution
n=1000
plt.hist([binom(n,lam/n) for i in range(10000)], bins=range(0,15), align="left", rwidth=0.5)
lam=8.0 # lambda, intensity of Poisson distribution
n=1000
plt.hist([binom(n,lam/n) for i in range(10000)], bins=range(0,30), align="left", rwidth=0.5)
# Poisson(lam) tends to a normal distribution (with proper scaling)
# as lam->infinity
# Poisson can also be characterized by its Probability Mass Function (pmf)
# (analogue of Probability Density Functions, but for discrete distribution)
# PMF is a function f, such that f(k) gives prob that distribution takes
# the value k.
# For instance, {0,1}-discrete r.v. (i.e. randint(0,1))
# PMF is f(0)=1/2, f(1)=1/2, f(k) =0 for any other k.
#PMF for Poisson(lam):
# f(k) = lam^k * exp(-lam)/k!
# e.g. for Poisson(1), f(k)= exp(-1)/k!
# (By convention 0!=1. Note f is not even defined for k not
# non-negative integer)
f(k)=lam^k * exp(-lam)/factorial(k)
lam = 1
f(k)=lam^k * exp(-lam)/factorial(k)
list_plot([f(k) for k in range(0,10)])
N(f(0)) # prob that Poisson(1) takes value 0
N(f(1))
N(f(6))
N(f(7))
N(f(30)) # non-zero, but very small
lam = 3
f(k)=lam^k * exp(-lam)/factorial(k)
list_plot([f(k) for k in range(0,10)])
# degrees of vertices in random graphs
# (for n vertices, n edges, with n large)
# will be close to Poisson distributed