简体   繁体   中英

Cumulative distribution function with Gamma Function in Python

I am dealing with the Schechter Luminosity function that looks like this:

phi(L)dL = norm. Factor * (L/Lstar)^(a) * exp (L/Lstar) d(L/Lstar)

Say, L/Lstar is l.

The analytic solution to its cumulative distribution function of is given by the gamma function: N = norm factor* Gamma(a+1, l).

This is the incomplete gamma function because the limits of integration are L to infinity.

Now, I am trying to plot the cdf in Python. I used:

import scipy.special as ss
si= [ss.gammainc(a+1, l[i]) for i in a]  #cdf  

(where l[I] is the array I made from random numbers)

The resulting graph totals at 1, and looks like a cdf. But now I want to randomize it. So, instead of cdf = 1, I set cdf = random number (generated uniformly by Python.) Now if I want to plot a histogram with number of counts vs. L, with the random sampling, I need to invert the gamma function.

My question is: How do I invert the Gamma function in Python?

This is what I have now:

u= [random.uniform(0,1) for i in a]

l= [ss.gammaincinv(a+1, u[i]) for i in a]

plt.plot(l, u, '.')

plt.show()

plt.hist(l, bins=50,rwidth= 1.5,histtype='step', lw= 0.7, normed= True, range=(-0.5, 1))

plt.show()

The compiler doesn't complain, but the histogram is the wrong shape. I think the randomly sampled histogram of the cdf should recover the shape of the PDF.

What am I doing wrong? Apparently, scipy's version of incomplete gamma function is 'regularized', which means it is divided by the complete gamma function. So if I multiply gammainc(a+1, u[I])* gamma(a+1) it still doesn't work.

The axes are log scaled.

Any suggestions?

Bottom line: I need to make a histogram of the cdf of Schechter luminosity function by random sampling.

First try:

A function is a mapping from the Domain to the Range. So you can write it like this:

def function(x):
    # ...

Domain = list(range(0, 1000)) # [0,1000)
mapping = {}
inverse_mapping = {}
for x in Domain:
    y = function(x)
    mapping[x] = y
    inverse_mapping[y] = x

def inverse_function(y):
    return inverse_mapping[y] # not a continuous function. needs improvement

If something like this in on your mind then let me know. We can improve it for monotonous functions like cdf.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM