Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save amarvutha/c2a3ea9d42d238551c694480019a6ce1 to your computer and use it in GitHub Desktop.
Save amarvutha/c2a3ea9d42d238551c694480019a6ce1 to your computer and use it in GitHub Desktop.
Fast Python implementation of Inverse Transform Sampling for an arbitrary probability distribution
import numpy as np
from numpy.random import random
from scipy import interpolate
import matplotlib.pyplot as plt
import cProfile
def f(x):
# does not need to be normalized
return np.exp(-x**2) * np.cos(3*x)**2 * (x-1)**4/np.cosh(1*x)
def sample(g):
x = np.linspace(-5,5,1e5)
y = g(x) # probability density function, pdf
cdf_y = np.cumsum(y) # cumulative distribution function, cdf
cdf_y = cdf_y/cdf_y.max() # takes care of normalizing cdf to 1.0
inverse_cdf = interpolate.interp1d(cdf_y,x) # this is a function
return inverse_cdf
def return_samples(N=1e6):
# let's generate some samples according to the chosen pdf, f(x)
uniform_samples = random(int(N))
required_samples = sample(f)(uniform_samples)
return required_samples
cProfile.run('return_samples()')
## plot
x = np.linspace(-3,3,1e4)
fig,ax = plt.subplots()
ax.set_xlabel('x')
ax.set_ylabel('probability density')
ax.plot(x,f(x)/np.sum(f(x)*(x[1]-x[0])) )
ax.hist(return_samples(1e6),bins='auto',normed=True,range=(x.min(),x.max()))
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment