Random Number Generators

Revision History

May 27, 1998. (Rob Managan) Ported to Mac. Added a log normal distribution. Added the density function to the method list for distributions. It seems there was no way to call the density functions that were in the code.

April, 1998. (Konrad Hinsen) The module RNG is an enhanced version of the URNG module by Paul Dubois. The URNG module provided any number of independent random number generators with a uniform distribution. The RNG module extends the random number generators to non-uniform distributions. Currently implemented are exponential and normal distributions, but adding others is not difficult. Contributions of code for other distributions are welcome!

Usage

Module RNG defines the function

CreateGenerator(s)

creates a new random number generator with a uniform [0, 1) distribution that is independent of other ones created earlier or later. Its first argument, an integer, determines the initial state:

  • s < 0 ==> Use the default initial seed value.
  • s = 0 ==> Set a random value for the seed from the system clock.
  • s > 0 ==> Set seed directly (32 bits only).
  • Other distributions are obtained by supplying a second argument which must be a distribution. Currently RNG defines the following distribution types:

    Examples

    The test routine Demo/RNGdemo.py illustrates some common usage of both RNG and Numeric.

    #import sys
    #sys.path.append("../pyds")
    #sys.path.append("../Lib")
    #sys.path.append("../../Numerical/Lib")
    #sys.path.append("../../Numerical/pyds")
    from Numeric import *
    import RNG
    def test_normal (mean, std, n=10000):
        dist = RNG.NormalDistribution(mean, std)
        rng = RNG.CreateGenerator(0, dist)
        values = rng.sample(n)
        m = sum(values)/n
        s = sqrt(sum((values-m)**2)/n)
        return (m, s)
    def test_lognormal (mean, std, n=10000):
        dist = RNG.LogNormalDistribution(mean, std)
        rng = RNG.CreateGenerator(0, dist)
        values = rng.sample(n)
        m = sum(values)/n
        s = sqrt(sum((values-m)**2)/n)
        return (m, s)
    def test_uniform (n=10000):
        dist = RNG.UniformDistribution(0., 1.)
        rng = RNG.CreateGenerator(0, dist)
        values = rng.sample(n)
        m = sum(values)/n
        return m
    if __name__ == "__main__":
        while(1):
           n = input("Enter sample size, 0 to quit: ")
           if (n <= 1): raise SystemExit
           print "Should be close to 1/2:", test_uniform(n)
           print "Should be close to 10.0, 1.0:", test_normal(10.0, 1.0,n)
           print "Should be close to 10.0, 1.0:", test_lognormal(10.0, 1.0,n)

    The test routine RNGtest2.py combines RNG with Konrad Hinsen's Statistics package to do a test of the log normal distribution..

    import Numeric
    import RNG
    dist = RNG.LogNormalDistribution(10.,5.)
    rng = RNG.CreateGenerator(0,dist)
    values = rng.sample(50000)
    print "generated values"
    import Statistics
    upper=40.
    lower=1.
    numbins=100
    hist = Statistics.histogram(values,numbins,(lower,upper))
    print "generated histogram"
    print hist
    for i in range(numbins):
      print i, hist[i,0], hist[i,1], 50000*((upper-lower)/numbins)*dist.density(hist[i,0]), hist[i,1]/(50000*((upper-lower)/numbins)*dist.density(hist[i,0]))