This question already has an answer here:
I have a piecewise quartic distribution with a probability density function:
p(x)= c(x/a)^2 if 0≤x<a;
c((b+a-x)^2/b)^2 if a≤x≤b;
0 otherwise
Suppose c, a, b are known, I am trying to draw 100 random samples from the distribution. How can I do it with numpy/scipy?
One standard way is to find an explicit formula,
G = F^-1
for the inverse of the cumulative distribution function. That is doable here (although it will naturally be piecewise defined) and then useG(U)
whereU
is uniform on [0,1] to generate your samples.In this case, I think that I worked out the details, but you will need to check the Calculus/Algebra.
First of all, to streamline things it helps to introduce a couple of new parameters. Let
and
Then your
p(x)
is given byI integrated
f
to find the cumulative distribution and then inverted and got the following:Assuming this is right, then simply:
In this case it was possible to work out an explicit formula. When you can't work out such a formula for the inverse, consider using the Monte Carlo methods described by @lucianopaz
As your function is bounded both in
x
andp(x)
, I recommend that you use Monte Carlo rejection sampling. The basic principle is that you draw two uniform random numbers, one representing a candidatex
in thex
space bounds[0,b]
and another representingy
. Ify
is lower or equal to the normalizedp(x)
, then the sampledx
is returned, if not it continues to the next iterationHere,
p
should be a callable to your normalized piecewise probability density,xbounds
can be a list or tuple containing the lower and upper bounds, andpmax
the maximum of the probability density in the x interval.