I was trying to learn using SciPy and I want to create a custom distribution with the pdf defined as :
f(x) = k * x ^ (k-1) if 0 < x < 1 else 0
Based on the documentation on the scipy website I've defined the custom distribution as:
k = 7
class custom_distro(stats.rv_continuous):
def _pdf(self, x):
return k*math.pow(x,k-1) if (0<=x<=1) else 0
Now the custom_distro.pdf()
and custom_distro.cdf()
functions are working fine, but using the function .rvs()
gives the error:
The function value at x=nan is NaN; solver cannot continue.
I've tried to search for what the issue is but I cannot find any helpful suggestion.
I'd also request that if you have some good resources for the library please do suggest.
This is surprising, because
custom_distro
is a subclass ofrv_continuous
, but each SciPy (continuous) distributions is an instance of a subclasses ofrv_continuous
. For examplenorm_gen
is a subclass ofrv_continuous
, andscipy.stats.norm
is an instance ofnorm_gen
. (It's weird, I know.)Another part of the problem may have been that your distribution has finite support (your
_pdf
returned 0 whenx
was outside the interval[0, 1]
), but it is better to define the support of the distribution using the appropriate feature of the infrastructure. The infrastructure will take care of ensuring that thepdf
method returns 0 when the argument is outside the support, etc.Here is code for which the
rvs
method works.There is some additional information about adding new distributions at Adding a New Statistics Distribution. Looking at PRs in which distributions were added will also be helpful, e.g. gh-12694.
Creating custom distributions is rather advanced. The process is poorly documented, and there are many issues with the infrastructure, so I would not recommend starting with this. Consider following one of the other tutorials.