import ranlib import Numeric import LinearAlgebra import sys import math from types import * # Extended RandomArray to provide more distributions: # normal, beta, chi square, F, multivariate normal, # exponential, binomial, multinomial # Lee Barford, Dec. 1999. class ArgumentError(Exception): pass def seed(x=0,y=0): """seed(x, y), set the seed using the integers x, y; Set a random one from clock if y == 0 """ if type (x) != IntType or type (y) != IntType : raise ArgumentError, "seed requires integer arguments." if y == 0: import time t = time.time() ndigits = int(math.log10(t)) base = 10**(ndigits/2) x = int(t/base) y = 1 + int(t%base) ranlib.set_seeds(x,y) seed() def get_seed(): "Return the current seed pair" return ranlib.get_seeds() def _build_random_array(fun, args, shape=[]): # Build an array by applying function fun to # the arguments in args, creating an array with # the specified shape. # Allows an integer shape n as a shorthand for (n,). if isinstance(shape, IntType): shape = [shape] if len(shape) != 0: n = Numeric.multiply.reduce(shape) s = apply(fun, args + (n,)) s.shape = shape return s else: n = 1 s = apply(fun, args + (n,)) return s[0] def random(shape=[]): "random(n) or random([n, m, ...]) returns array of random numbers" return _build_random_array(ranlib.sample, (), shape) def uniform(minimum, maximum, shape=[]): """uniform(minimum, maximum, shape=[]) returns array of given shape of random reals in given range""" return minimum + (maximum-minimum)*random(shape) def randint(minimum, maximum=None, shape=[]): """randint(min, max, shape=[]) = random integers >=min, < max If max not given, random integers >= 0, = 0.6: raise SystemExit, "uniform returned out of desired range" print "randint(1, 10, shape=[50])" print randint(1, 10, shape=[50]) print "permutation(10)", permutation(10) print "randint(3,9)", randint(3,9) print "random_integers(10, shape=[20])" print random_integers(10, shape=[20]) s = 3.0 x = normal(2.0, s, [10, 1000]) if len(x.shape) != 2 or x.shape[0] != 10 or x.shape[1] != 1000: raise SystemExit, "standard_normal returned wrong shape" x.shape = (10000,) mean_var_test(x, "normally distributed numbers with mean 2 and variance %f"%(s**2,), 2, s**2, 0) x = exponential(3, 10000) mean_var_test(x, "random numbers exponentially distributed with mean %f"%(s,), s, s**2, 2) x = multivariate_normal(Numeric.array([10,20]), Numeric.array(([1,2],[2,4]))) print "\nA multivariate normal", x if x.shape != (2,): raise SystemExit, "multivariate_normal returned wrong shape" x = multivariate_normal(Numeric.array([10,20]), Numeric.array([[1,2],[2,4]]), [4,3]) print "A 4x3x2 array containing multivariate normals" print x if x.shape != (4,3,2): raise SystemExit, "multivariate_normal returned wrong shape" x = multivariate_normal(Numeric.array([-100,0,100]), Numeric.array([[3,2,1],[2,2,1],[1,1,1]]), 10000) x_mean = Numeric.sum(x)/10000. print "Average of 10000 multivariate normals with mean [-100,0,100]" print x_mean x_minus_mean = x - x_mean print "Estimated covariance of 10000 multivariate normals with covariance [[3,2,1],[2,2,1],[1,1,1]]" print Numeric.matrixmultiply(Numeric.transpose(x_minus_mean),x_minus_mean)/9999. x = beta(5.0, 10.0, 10000) mean_var_test(x, "beta(5.,10.) random numbers", 0.333, 0.014) x = gamma(.01, 2., 10000) mean_var_test(x, "gamma(.01,2.) random numbers", 2*100, 2*100*100) x = chi_square(11., 10000) mean_var_test(x, "chi squared random numbers with 11 degrees of freedom", 11, 22, 2*Numeric.sqrt(2./11.)) x = F(5., 10., 10000) mean_var_test(x, "F random numbers with 5 and 10 degrees of freedom", 1.25, 1.35) x = poisson(50., 10000) mean_var_test(x, "poisson random numbers with mean 50", 50, 50, 0.14) print "\nEach element is the result of 16 binomial trials with probability 0.5:" print binomial(16, 0.5, 16) print "\nEach element is the result of 16 negative binomial trials with probability 0.5:" print negative_binomial(16, 0.5, [16,]) print "\nEach row is the result of 16 multinomial trials with probabilities [0.1, 0.5, 0.1 0.3]:" x = multinomial(16, [0.1, 0.5, 0.1], 8) print x print "Mean = ", Numeric.sum(x)/8. if __name__ == '__main__': test()