2

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.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
user3014593
  • 231
  • 1
  • 2
  • 5
  • Do you ask for the inverse of the gamma function to be displayed or do you want a programed inverse gamma function? I would think the second one. – User Nov 20 '13 at 20:11

1 Answers1

1

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.

User
  • 14,131
  • 2
  • 40
  • 59