As your function is bounded both in x
and p(x)
, I recommend that you use Monte Carlo rejection sampling. The basic principle is that you draw two uniform random numbers, one representing a candidate x
in the x
space bounds [0,b]
and another representing y
. If y
is lower or equal to the normalized p(x)
, then the sampled x
is returned, if not it continues to the next iteration
import numpy as np
def rejection_sampler(p,xbounds,pmax):
while True:
x = np.random.rand(1)*(xbounds[1]-xbounds[0])+xbounds[0]
y = np.random.rand(1)*pmax
if y<=p(x):
return x
Here, p
should be a callable to your normalized piecewise probability density, xbounds
can be a list or tuple containing the lower and upper bounds, and pmax
the maximum of the probability density in the x interval.