# 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:

• UniformDistribution(a, b) -- a uniform distribution of numbers in the interval [a, b)
• NormalDistribution(mu, sigma) -- a normal distribution with mean mu and standard deviation sigma
• ExponentialDistribution(l) -- an exponential distribution of positive numbers with decay constant l.
• LogNormalDistribution(mean, std) -- a log normal distribution with given mean and standard deviation.

## 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]))
```