#	R A N D O M   V A R I A B L E   G E N E R A T O R S
#
#	distributions on the real line:
#	------------------------------
#	       normal (Gaussian)
#	       lognormal
#	       negative exponential
#	       gamma
#	       beta
#
#	distributions on the circle (angles 0 to 2pi)
#	---------------------------------------------
#	       circular uniform
#	       von Mises

# Translated from anonymously contributed C/C++ source.

from whrandom import random, uniform, randint, choice # Also for export!
from math import log, exp, pi, e, sqrt, acos, cos, sin

# Housekeeping function to verify that magic constants have been
# computed correctly

def verify(name, expected):
	computed = eval(name)
	if abs(computed - expected) > 1e-7:
		raise ValueError, \
  'computed value for %s deviates too much (computed %g, expected %g)' % \
  (name, computed, expected)

# -------------------- normal distribution --------------------

NV_MAGICCONST = 4*exp(-0.5)/sqrt(2.0)
verify('NV_MAGICCONST', 1.71552776992141)
def normalvariate(mu, sigma):
	# mu = mean, sigma = standard deviation

	# Uses Kinderman and Monahan method. Reference: Kinderman,
	# A.J. and Monahan, J.F., "Computer generation of random
	# variables using the ratio of uniform deviates", ACM Trans
	# Math Software, 3, (1977), pp257-260.

	while 1:
		u1 = random()
		u2 = random()
		z = NV_MAGICCONST*(u1-0.5)/u2
		zz = z*z/4.0
		if zz <= -log(u2):
			break
	return mu+z*sigma

# -------------------- lognormal distribution --------------------

def lognormvariate(mu, sigma):
	return exp(normalvariate(mu, sigma))

# -------------------- circular uniform --------------------

def cunifvariate(mean, arc):
	# mean: mean angle (in radians between 0 and pi)
	# arc:  range of distribution (in radians between 0 and pi)

	return (mean + arc * (random() - 0.5)) % pi

# -------------------- exponential distribution --------------------

def expovariate(lambd):
	# lambd: rate lambd = 1/mean
	# ('lambda' is a Python reserved word)

	u = random()
	while u <= 1e-7:
		u = random()
	return -log(u)/lambd

# -------------------- von Mises distribution --------------------

TWOPI = 2.0*pi
verify('TWOPI', 6.28318530718)

def vonmisesvariate(mu, kappa):
	# mu:    mean angle (in radians between 0 and 180 degrees)
	# kappa: concentration parameter kappa (>= 0)
	
	# if kappa = 0 generate uniform random angle
	if kappa <= 1e-6:
		return TWOPI * random()

	a = 1.0 + sqrt(1.0 + 4.0 * kappa * kappa)
	b = (a - sqrt(2.0 * a))/(2.0 * kappa)
	r = (1.0 + b * b)/(2.0 * b)

	while 1:
		u1 = random()

		z = cos(pi * u1)
		f = (1.0 + r * z)/(r + z)
		c = kappa * (r - f)

		u2 = random()

		if not (u2 >= c * (2.0 - c) and u2 > c * exp(1.0 - c)):
			break

	u3 = random()
	if u3 > 0.5:
		theta = mu + 0.5*acos(f)
	else:
		theta = mu - 0.5*acos(f)

	return theta % pi

# -------------------- gamma distribution --------------------

LOG4 = log(4.0)
verify('LOG4', 1.38629436111989)

def gammavariate(alpha, beta):
        # beta times standard gamma
	ainv = sqrt(2.0 * alpha - 1.0)
	return beta * stdgamma(alpha, ainv, alpha - LOG4, alpha + ainv)

SG_MAGICCONST = 1.0 + log(4.5)
verify('SG_MAGICCONST', 2.50407739677627)

def stdgamma(alpha, ainv, bbb, ccc):
	# ainv = sqrt(2 * alpha - 1)
	# bbb = alpha - log(4)
	# ccc = alpha + ainv

	if alpha <= 0.0:
		raise ValueError, 'stdgamma: alpha must be > 0.0'

	if alpha > 1.0:

		# Uses R.C.H. Cheng, "The generation of Gamma
		# variables with non-integral shape parameters",
		# Applied Statistics, (1977), 26, No. 1, p71-74

		while 1:
			u1 = random()
			u2 = random()
			v = log(u1/(1.0-u1))/ainv
			x = alpha*exp(v)
			z = u1*u1*u2
			r = bbb+ccc*v-x
			if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= log(z):
				return x

	elif alpha == 1.0:
		# expovariate(1)
		u = random()
		while u <= 1e-7:
			u = random()
		return -log(u)

	else:	# alpha is between 0 and 1 (exclusive)

		# Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle

		while 1:
			u = random()
			b = (e + alpha)/e
			p = b*u
			if p <= 1.0:
				x = pow(p, 1.0/alpha)
			else:
				# p > 1
				x = -log((b-p)/alpha)
			u1 = random()
			if not (((p <= 1.0) and (u1 > exp(-x))) or
				  ((p > 1)  and  (u1 > pow(x, alpha - 1.0)))):
				break
		return x


# -------------------- Gauss (faster alternative) --------------------

gauss_next = None
def gauss(mu, sigma):

	# When x and y are two variables from [0, 1), uniformly
	# distributed, then
	#
	#    cos(2*pi*x)*log(1-y)
	#    sin(2*pi*x)*log(1-y)
	#
	# are two *independent* variables with normal distribution
	# (mu = 0, sigma = 1).
	# (Lambert Meertens)

	global gauss_next

	if gauss_next != None:
		z = gauss_next
		gauss_next = None
	else:
		x2pi = random() * TWOPI
		log1_y = log(1.0 - random())
		z = cos(x2pi) * log1_y
		gauss_next = sin(x2pi) * log1_y

	return mu + z*sigma

# -------------------- beta --------------------

def betavariate(alpha, beta):

	# Discrete Event Simulation in C, pp 87-88.

	y = expovariate(alpha)
	z = expovariate(1.0/beta)
	return z/(y+z)

# -------------------- test program --------------------

def test(N = 200):
	print 'TWOPI         =', TWOPI
	print 'LOG4          =', LOG4
	print 'NV_MAGICCONST =', NV_MAGICCONST
	print 'SG_MAGICCONST =', SG_MAGICCONST
	test_generator(N, 'random()')
	test_generator(N, 'normalvariate(0.0, 1.0)')
	test_generator(N, 'lognormvariate(0.0, 1.0)')
	test_generator(N, 'cunifvariate(0.0, 1.0)')
	test_generator(N, 'expovariate(1.0)')
	test_generator(N, 'vonmisesvariate(0.0, 1.0)')
	test_generator(N, 'gammavariate(0.5, 1.0)')
	test_generator(N, 'gammavariate(0.9, 1.0)')
	test_generator(N, 'gammavariate(1.0, 1.0)')
	test_generator(N, 'gammavariate(2.0, 1.0)')
	test_generator(N, 'gammavariate(20.0, 1.0)')
	test_generator(N, 'gammavariate(200.0, 1.0)')
	test_generator(N, 'gauss(0.0, 1.0)')
	test_generator(N, 'betavariate(3.0, 3.0)')

def test_generator(n, funccall):
	import time
	print n, 'times', funccall
	code = compile(funccall, funccall, 'eval')
	sum = 0.0
	sqsum = 0.0
	smallest = 1e10
	largest = -1e10
	t0 = time.time()
	for i in range(n):
		x = eval(code)
		sum = sum + x
		sqsum = sqsum + x*x
		smallest = min(x, smallest)
		largest = max(x, largest)
	t1 = time.time()
	print round(t1-t0, 3), 'sec,', 
	avg = sum/n
	stddev = sqrt(sqsum/n - avg*avg)
	print 'avg %g, stddev %g, min %g, max %g' % \
		  (avg, stddev, smallest, largest)

if __name__ == '__main__':
	test()
