On Aug 6, 3:02 pm, Alex <[EMAIL PROTECTED]> wrote: > I wonder if it is possible in python to produce random numbers > according to a user defined distribution? > Unfortunately the random module does not contain the distribution I > need :-(
Sure there's a way but it won't be very efficient. Starting with an arbitrary probability density function over some range, you can run it through a quadrature routine to create a cumulative density function over that range. Use random.random() to create a uniform variate x. Then use a bisecting search to find x in the cumulative density function over the given range. from __future__ import division from random import random def integrate(f, lo, hi, steps=1000): dx = (hi - lo) / steps lo += dx / 2 return sum(f(i*dx + lo) * dx for i in range(steps)) def make_cdf(f, lo, hi, steps=1000): total_area = integrate(f, lo, hi, steps) def cdf(x): assert lo <= x <= hi return integrate(f, lo, x, steps) / total_area return cdf def bisect(target, f, lo, hi, n=20): 'Find x between lo and hi where f(x)=target' for i in range(n): mid = (hi + lo) / 2.0 if target < f(mid): hi = mid else: lo = mid return (hi + lo) / 2.0 def make_user_distribution(f, lo, hi, steps=1000, n=20): cdf = make_cdf(f, lo, hi, steps) return lambda: bisect(random(), cdf, lo, hi, n) if __name__ == '__main__': def linear(x): return 3 * x - 6 lo, hi = 2, 10 r = make_user_distribution(linear, lo, hi) for i in range(20): print r() -- Raymond -- http://mail.python.org/mailman/listinfo/python-list