Home | History | Annotate | Download | only in Lib
      1 """Random variable generators.
      2 
      3     integers
      4     --------
      5            uniform within range
      6 
      7     sequences
      8     ---------
      9            pick random element
     10            pick random sample
     11            generate random permutation
     12 
     13     distributions on the real line:
     14     ------------------------------
     15            uniform
     16            triangular
     17            normal (Gaussian)
     18            lognormal
     19            negative exponential
     20            gamma
     21            beta
     22            pareto
     23            Weibull
     24 
     25     distributions on the circle (angles 0 to 2pi)
     26     ---------------------------------------------
     27            circular uniform
     28            von Mises
     29 
     30 General notes on the underlying Mersenne Twister core generator:
     31 
     32 * The period is 2**19937-1.
     33 * It is one of the most extensively tested generators in existence.
     34 * Without a direct way to compute N steps forward, the semantics of
     35   jumpahead(n) are weakened to simply jump to another distant state and rely
     36   on the large period to avoid overlapping sequences.
     37 * The random() method is implemented in C, executes in a single Python step,
     38   and is, therefore, threadsafe.
     39 
     40 """
     41 
     42 from __future__ import division
     43 from warnings import warn as _warn
     44 from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType
     45 from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
     46 from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
     47 from os import urandom as _urandom
     48 from binascii import hexlify as _hexlify
     49 import hashlib as _hashlib
     50 
     51 __all__ = ["Random","seed","random","uniform","randint","choice","sample",
     52            "randrange","shuffle","normalvariate","lognormvariate",
     53            "expovariate","vonmisesvariate","gammavariate","triangular",
     54            "gauss","betavariate","paretovariate","weibullvariate",
     55            "getstate","setstate","jumpahead", "WichmannHill", "getrandbits",
     56            "SystemRandom"]
     57 
     58 NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
     59 TWOPI = 2.0*_pi
     60 LOG4 = _log(4.0)
     61 SG_MAGICCONST = 1.0 + _log(4.5)
     62 BPF = 53        # Number of bits in a float

     63 RECIP_BPF = 2**-BPF
     64 
     65 
     66 # Translated by Guido van Rossum from C source provided by

     67 # Adrian Baddeley.  Adapted by Raymond Hettinger for use with

     68 # the Mersenne Twister  and os.urandom() core generators.

     69 
     70 import _random
     71 
     72 class Random(_random.Random):
     73     """Random number generator base class used by bound module functions.
     74 
     75     Used to instantiate instances of Random to get generators that don't
     76     share state.  Especially useful for multi-threaded programs, creating
     77     a different instance of Random for each thread, and using the jumpahead()
     78     method to ensure that the generated sequences seen by each thread don't
     79     overlap.
     80 
     81     Class Random can also be subclassed if you want to use a different basic
     82     generator of your own devising: in that case, override the following
     83     methods: random(), seed(), getstate(), setstate() and jumpahead().
     84     Optionally, implement a getrandbits() method so that randrange() can cover
     85     arbitrarily large ranges.
     86 
     87     """
     88 
     89     VERSION = 3     # used by getstate/setstate

     90 
     91     def __init__(self, x=None):
     92         """Initialize an instance.
     93 
     94         Optional argument x controls seeding, as for Random.seed().
     95         """
     96 
     97         self.seed(x)
     98         self.gauss_next = None
     99 
    100     def seed(self, a=None):
    101         """Initialize internal state from hashable object.
    102 
    103         None or no argument seeds from current time or from an operating
    104         system specific randomness source if available.
    105 
    106         If a is not None or an int or long, hash(a) is used instead.
    107         """
    108 
    109         if a is None:
    110             try:
    111                 a = long(_hexlify(_urandom(16)), 16)
    112             except NotImplementedError:
    113                 import time
    114                 a = long(time.time() * 256) # use fractional seconds

    115 
    116         super(Random, self).seed(a)
    117         self.gauss_next = None
    118 
    119     def getstate(self):
    120         """Return internal state; can be passed to setstate() later."""
    121         return self.VERSION, super(Random, self).getstate(), self.gauss_next
    122 
    123     def setstate(self, state):
    124         """Restore internal state from object returned by getstate()."""
    125         version = state[0]
    126         if version == 3:
    127             version, internalstate, self.gauss_next = state
    128             super(Random, self).setstate(internalstate)
    129         elif version == 2:
    130             version, internalstate, self.gauss_next = state
    131             # In version 2, the state was saved as signed ints, which causes

    132             #   inconsistencies between 32/64-bit systems. The state is

    133             #   really unsigned 32-bit ints, so we convert negative ints from

    134             #   version 2 to positive longs for version 3.

    135             try:
    136                 internalstate = tuple( long(x) % (2**32) for x in internalstate )
    137             except ValueError, e:
    138                 raise TypeError, e
    139             super(Random, self).setstate(internalstate)
    140         else:
    141             raise ValueError("state with version %s passed to "
    142                              "Random.setstate() of version %s" %
    143                              (version, self.VERSION))
    144 
    145     def jumpahead(self, n):
    146         """Change the internal state to one that is likely far away
    147         from the current state.  This method will not be in Py3.x,
    148         so it is better to simply reseed.
    149         """
    150         # The super.jumpahead() method uses shuffling to change state,

    151         # so it needs a large and "interesting" n to work with.  Here,

    152         # we use hashing to create a large n for the shuffle.

    153         s = repr(n) + repr(self.getstate())
    154         n = int(_hashlib.new('sha512', s).hexdigest(), 16)
    155         super(Random, self).jumpahead(n)
    156 
    157 ## ---- Methods below this point do not need to be overridden when

    158 ## ---- subclassing for the purpose of using a different core generator.

    159 
    160 ## -------------------- pickle support  -------------------

    161 
    162     def __getstate__(self): # for pickle

    163         return self.getstate()
    164 
    165     def __setstate__(self, state):  # for pickle

    166         self.setstate(state)
    167 
    168     def __reduce__(self):
    169         return self.__class__, (), self.getstate()
    170 
    171 ## -------------------- integer methods  -------------------

    172 
    173     def randrange(self, start, stop=None, step=1, int=int, default=None,
    174                   maxwidth=1L<<BPF):
    175         """Choose a random item from range(start, stop[, step]).
    176 
    177         This fixes the problem with randint() which includes the
    178         endpoint; in Python this is usually not what you want.
    179         Do not supply the 'int', 'default', and 'maxwidth' arguments.
    180         """
    181 
    182         # This code is a bit messy to make it fast for the

    183         # common case while still doing adequate error checking.

    184         istart = int(start)
    185         if istart != start:
    186             raise ValueError, "non-integer arg 1 for randrange()"
    187         if stop is default:
    188             if istart > 0:
    189                 if istart >= maxwidth:
    190                     return self._randbelow(istart)
    191                 return int(self.random() * istart)
    192             raise ValueError, "empty range for randrange()"
    193 
    194         # stop argument supplied.

    195         istop = int(stop)
    196         if istop != stop:
    197             raise ValueError, "non-integer stop for randrange()"
    198         width = istop - istart
    199         if step == 1 and width > 0:
    200             # Note that

    201             #     int(istart + self.random()*width)

    202             # instead would be incorrect.  For example, consider istart

    203             # = -2 and istop = 0.  Then the guts would be in

    204             # -2.0 to 0.0 exclusive on both ends (ignoring that random()

    205             # might return 0.0), and because int() truncates toward 0, the

    206             # final result would be -1 or 0 (instead of -2 or -1).

    207             #     istart + int(self.random()*width)

    208             # would also be incorrect, for a subtler reason:  the RHS

    209             # can return a long, and then randrange() would also return

    210             # a long, but we're supposed to return an int (for backward

    211             # compatibility).

    212 
    213             if width >= maxwidth:
    214                 return int(istart + self._randbelow(width))
    215             return int(istart + int(self.random()*width))
    216         if step == 1:
    217             raise ValueError, "empty range for randrange() (%d,%d, %d)" % (istart, istop, width)
    218 
    219         # Non-unit step argument supplied.

    220         istep = int(step)
    221         if istep != step:
    222             raise ValueError, "non-integer step for randrange()"
    223         if istep > 0:
    224             n = (width + istep - 1) // istep
    225         elif istep < 0:
    226             n = (width + istep + 1) // istep
    227         else:
    228             raise ValueError, "zero step for randrange()"
    229 
    230         if n <= 0:
    231             raise ValueError, "empty range for randrange()"
    232 
    233         if n >= maxwidth:
    234             return istart + istep*self._randbelow(n)
    235         return istart + istep*int(self.random() * n)
    236 
    237     def randint(self, a, b):
    238         """Return random integer in range [a, b], including both end points.
    239         """
    240 
    241         return self.randrange(a, b+1)
    242 
    243     def _randbelow(self, n, _log=_log, int=int, _maxwidth=1L<<BPF,
    244                    _Method=_MethodType, _BuiltinMethod=_BuiltinMethodType):
    245         """Return a random int in the range [0,n)
    246 
    247         Handles the case where n has more bits than returned
    248         by a single call to the underlying generator.
    249         """
    250 
    251         try:
    252             getrandbits = self.getrandbits
    253         except AttributeError:
    254             pass
    255         else:
    256             # Only call self.getrandbits if the original random() builtin method

    257             # has not been overridden or if a new getrandbits() was supplied.

    258             # This assures that the two methods correspond.

    259             if type(self.random) is _BuiltinMethod or type(getrandbits) is _Method:
    260                 k = int(1.00001 + _log(n-1, 2.0))   # 2**k > n-1 > 2**(k-2)

    261                 r = getrandbits(k)
    262                 while r >= n:
    263                     r = getrandbits(k)
    264                 return r
    265         if n >= _maxwidth:
    266             _warn("Underlying random() generator does not supply \n"
    267                 "enough bits to choose from a population range this large")
    268         return int(self.random() * n)
    269 
    270 ## -------------------- sequence methods  -------------------

    271 
    272     def choice(self, seq):
    273         """Choose a random element from a non-empty sequence."""
    274         return seq[int(self.random() * len(seq))]  # raises IndexError if seq is empty

    275 
    276     def shuffle(self, x, random=None, int=int):
    277         """x, random=random.random -> shuffle list x in place; return None.
    278 
    279         Optional arg random is a 0-argument function returning a random
    280         float in [0.0, 1.0); by default, the standard random.random.
    281         """
    282 
    283         if random is None:
    284             random = self.random
    285         for i in reversed(xrange(1, len(x))):
    286             # pick an element in x[:i+1] with which to exchange x[i]

    287             j = int(random() * (i+1))
    288             x[i], x[j] = x[j], x[i]
    289 
    290     def sample(self, population, k):
    291         """Chooses k unique random elements from a population sequence.
    292 
    293         Returns a new list containing elements from the population while
    294         leaving the original population unchanged.  The resulting list is
    295         in selection order so that all sub-slices will also be valid random
    296         samples.  This allows raffle winners (the sample) to be partitioned
    297         into grand prize and second place winners (the subslices).
    298 
    299         Members of the population need not be hashable or unique.  If the
    300         population contains repeats, then each occurrence is a possible
    301         selection in the sample.
    302 
    303         To choose a sample in a range of integers, use xrange as an argument.
    304         This is especially fast and space efficient for sampling from a
    305         large population:   sample(xrange(10000000), 60)
    306         """
    307 
    308         # Sampling without replacement entails tracking either potential

    309         # selections (the pool) in a list or previous selections in a set.

    310 
    311         # When the number of selections is small compared to the

    312         # population, then tracking selections is efficient, requiring

    313         # only a small set and an occasional reselection.  For

    314         # a larger number of selections, the pool tracking method is

    315         # preferred since the list takes less space than the

    316         # set and it doesn't suffer from frequent reselections.

    317 
    318         n = len(population)
    319         if not 0 <= k <= n:
    320             raise ValueError("sample larger than population")
    321         random = self.random
    322         _int = int
    323         result = [None] * k
    324         setsize = 21        # size of a small set minus size of an empty list

    325         if k > 5:
    326             setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets

    327         if n <= setsize or hasattr(population, "keys"):
    328             # An n-length list is smaller than a k-length set, or this is a

    329             # mapping type so the other algorithm wouldn't work.

    330             pool = list(population)
    331             for i in xrange(k):         # invariant:  non-selected at [0,n-i)

    332                 j = _int(random() * (n-i))
    333                 result[i] = pool[j]
    334                 pool[j] = pool[n-i-1]   # move non-selected item into vacancy

    335         else:
    336             try:
    337                 selected = set()
    338                 selected_add = selected.add
    339                 for i in xrange(k):
    340                     j = _int(random() * n)
    341                     while j in selected:
    342                         j = _int(random() * n)
    343                     selected_add(j)
    344                     result[i] = population[j]
    345             except (TypeError, KeyError):   # handle (at least) sets

    346                 if isinstance(population, list):
    347                     raise
    348                 return self.sample(tuple(population), k)
    349         return result
    350 
    351 ## -------------------- real-valued distributions  -------------------

    352 
    353 ## -------------------- uniform distribution -------------------

    354 
    355     def uniform(self, a, b):
    356         "Get a random number in the range [a, b) or [a, b] depending on rounding."
    357         return a + (b-a) * self.random()
    358 
    359 ## -------------------- triangular --------------------

    360 
    361     def triangular(self, low=0.0, high=1.0, mode=None):
    362         """Triangular distribution.
    363 
    364         Continuous distribution bounded by given lower and upper limits,
    365         and having a given mode value in-between.
    366 
    367         http://en.wikipedia.org/wiki/Triangular_distribution
    368 
    369         """
    370         u = self.random()
    371         c = 0.5 if mode is None else (mode - low) / (high - low)
    372         if u > c:
    373             u = 1.0 - u
    374             c = 1.0 - c
    375             low, high = high, low
    376         return low + (high - low) * (u * c) ** 0.5
    377 
    378 ## -------------------- normal distribution --------------------

    379 
    380     def normalvariate(self, mu, sigma):
    381         """Normal distribution.
    382 
    383         mu is the mean, and sigma is the standard deviation.
    384 
    385         """
    386         # mu = mean, sigma = standard deviation

    387 
    388         # Uses Kinderman and Monahan method. Reference: Kinderman,

    389         # A.J. and Monahan, J.F., "Computer generation of random

    390         # variables using the ratio of uniform deviates", ACM Trans

    391         # Math Software, 3, (1977), pp257-260.

    392 
    393         random = self.random
    394         while 1:
    395             u1 = random()
    396             u2 = 1.0 - random()
    397             z = NV_MAGICCONST*(u1-0.5)/u2
    398             zz = z*z/4.0
    399             if zz <= -_log(u2):
    400                 break
    401         return mu + z*sigma
    402 
    403 ## -------------------- lognormal distribution --------------------

    404 
    405     def lognormvariate(self, mu, sigma):
    406         """Log normal distribution.
    407 
    408         If you take the natural logarithm of this distribution, you'll get a
    409         normal distribution with mean mu and standard deviation sigma.
    410         mu can have any value, and sigma must be greater than zero.
    411 
    412         """
    413         return _exp(self.normalvariate(mu, sigma))
    414 
    415 ## -------------------- exponential distribution --------------------

    416 
    417     def expovariate(self, lambd):
    418         """Exponential distribution.
    419 
    420         lambd is 1.0 divided by the desired mean.  It should be
    421         nonzero.  (The parameter would be called "lambda", but that is
    422         a reserved word in Python.)  Returned values range from 0 to
    423         positive infinity if lambd is positive, and from negative
    424         infinity to 0 if lambd is negative.
    425 
    426         """
    427         # lambd: rate lambd = 1/mean

    428         # ('lambda' is a Python reserved word)

    429 
    430         random = self.random
    431         u = random()
    432         while u <= 1e-7:
    433             u = random()
    434         return -_log(u)/lambd
    435 
    436 ## -------------------- von Mises distribution --------------------

    437 
    438     def vonmisesvariate(self, mu, kappa):
    439         """Circular data distribution.
    440 
    441         mu is the mean angle, expressed in radians between 0 and 2*pi, and
    442         kappa is the concentration parameter, which must be greater than or
    443         equal to zero.  If kappa is equal to zero, this distribution reduces
    444         to a uniform random angle over the range 0 to 2*pi.
    445 
    446         """
    447         # mu:    mean angle (in radians between 0 and 2*pi)

    448         # kappa: concentration parameter kappa (>= 0)

    449         # if kappa = 0 generate uniform random angle

    450 
    451         # Based upon an algorithm published in: Fisher, N.I.,

    452         # "Statistical Analysis of Circular Data", Cambridge

    453         # University Press, 1993.

    454 
    455         # Thanks to Magnus Kessler for a correction to the

    456         # implementation of step 4.

    457 
    458         random = self.random
    459         if kappa <= 1e-6:
    460             return TWOPI * random()
    461 
    462         a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa)
    463         b = (a - _sqrt(2.0 * a))/(2.0 * kappa)
    464         r = (1.0 + b * b)/(2.0 * b)
    465 
    466         while 1:
    467             u1 = random()
    468 
    469             z = _cos(_pi * u1)
    470             f = (1.0 + r * z)/(r + z)
    471             c = kappa * (r - f)
    472 
    473             u2 = random()
    474 
    475             if u2 < c * (2.0 - c) or u2 <= c * _exp(1.0 - c):
    476                 break
    477 
    478         u3 = random()
    479         if u3 > 0.5:
    480             theta = (mu % TWOPI) + _acos(f)
    481         else:
    482             theta = (mu % TWOPI) - _acos(f)
    483 
    484         return theta
    485 
    486 ## -------------------- gamma distribution --------------------

    487 
    488     def gammavariate(self, alpha, beta):
    489         """Gamma distribution.  Not the gamma function!
    490 
    491         Conditions on the parameters are alpha > 0 and beta > 0.
    492 
    493         The probability distribution function is:
    494 
    495                     x ** (alpha - 1) * math.exp(-x / beta)
    496           pdf(x) =  --------------------------------------
    497                       math.gamma(alpha) * beta ** alpha
    498 
    499         """
    500 
    501         # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2

    502 
    503         # Warning: a few older sources define the gamma distribution in terms

    504         # of alpha > -1.0

    505         if alpha <= 0.0 or beta <= 0.0:
    506             raise ValueError, 'gammavariate: alpha and beta must be > 0.0'
    507 
    508         random = self.random
    509         if alpha > 1.0:
    510 
    511             # Uses R.C.H. Cheng, "The generation of Gamma

    512             # variables with non-integral shape parameters",

    513             # Applied Statistics, (1977), 26, No. 1, p71-74

    514 
    515             ainv = _sqrt(2.0 * alpha - 1.0)
    516             bbb = alpha - LOG4
    517             ccc = alpha + ainv
    518 
    519             while 1:
    520                 u1 = random()
    521                 if not 1e-7 < u1 < .9999999:
    522                     continue
    523                 u2 = 1.0 - random()
    524                 v = _log(u1/(1.0-u1))/ainv
    525                 x = alpha*_exp(v)
    526                 z = u1*u1*u2
    527                 r = bbb+ccc*v-x
    528                 if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
    529                     return x * beta
    530 
    531         elif alpha == 1.0:
    532             # expovariate(1)

    533             u = random()
    534             while u <= 1e-7:
    535                 u = random()
    536             return -_log(u) * beta
    537 
    538         else:   # alpha is between 0 and 1 (exclusive)

    539 
    540             # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle

    541 
    542             while 1:
    543                 u = random()
    544                 b = (_e + alpha)/_e
    545                 p = b*u
    546                 if p <= 1.0:
    547                     x = p ** (1.0/alpha)
    548                 else:
    549                     x = -_log((b-p)/alpha)
    550                 u1 = random()
    551                 if p > 1.0:
    552                     if u1 <= x ** (alpha - 1.0):
    553                         break
    554                 elif u1 <= _exp(-x):
    555                     break
    556             return x * beta
    557 
    558 ## -------------------- Gauss (faster alternative) --------------------

    559 
    560     def gauss(self, mu, sigma):
    561         """Gaussian distribution.
    562 
    563         mu is the mean, and sigma is the standard deviation.  This is
    564         slightly faster than the normalvariate() function.
    565 
    566         Not thread-safe without a lock around calls.
    567 
    568         """
    569 
    570         # When x and y are two variables from [0, 1), uniformly

    571         # distributed, then

    572         #

    573         #    cos(2*pi*x)*sqrt(-2*log(1-y))

    574         #    sin(2*pi*x)*sqrt(-2*log(1-y))

    575         #

    576         # are two *independent* variables with normal distribution

    577         # (mu = 0, sigma = 1).

    578         # (Lambert Meertens)

    579         # (corrected version; bug discovered by Mike Miller, fixed by LM)

    580 
    581         # Multithreading note: When two threads call this function

    582         # simultaneously, it is possible that they will receive the

    583         # same return value.  The window is very small though.  To

    584         # avoid this, you have to use a lock around all calls.  (I

    585         # didn't want to slow this down in the serial case by using a

    586         # lock here.)

    587 
    588         random = self.random
    589         z = self.gauss_next
    590         self.gauss_next = None
    591         if z is None:
    592             x2pi = random() * TWOPI
    593             g2rad = _sqrt(-2.0 * _log(1.0 - random()))
    594             z = _cos(x2pi) * g2rad
    595             self.gauss_next = _sin(x2pi) * g2rad
    596 
    597         return mu + z*sigma
    598 
    599 ## -------------------- beta --------------------

    600 ## See

    601 ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html

    602 ## for Ivan Frohne's insightful analysis of why the original implementation:

    603 ##

    604 ##    def betavariate(self, alpha, beta):

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

    606 ##

    607 ##        y = self.expovariate(alpha)

    608 ##        z = self.expovariate(1.0/beta)

    609 ##        return z/(y+z)

    610 ##

    611 ## was dead wrong, and how it probably got that way.

    612 
    613     def betavariate(self, alpha, beta):
    614         """Beta distribution.
    615 
    616         Conditions on the parameters are alpha > 0 and beta > 0.
    617         Returned values range between 0 and 1.
    618 
    619         """
    620 
    621         # This version due to Janne Sinkkonen, and matches all the std

    622         # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").

    623         y = self.gammavariate(alpha, 1.)
    624         if y == 0:
    625             return 0.0
    626         else:
    627             return y / (y + self.gammavariate(beta, 1.))
    628 
    629 ## -------------------- Pareto --------------------

    630 
    631     def paretovariate(self, alpha):
    632         """Pareto distribution.  alpha is the shape parameter."""
    633         # Jain, pg. 495

    634 
    635         u = 1.0 - self.random()
    636         return 1.0 / pow(u, 1.0/alpha)
    637 
    638 ## -------------------- Weibull --------------------

    639 
    640     def weibullvariate(self, alpha, beta):
    641         """Weibull distribution.
    642 
    643         alpha is the scale parameter and beta is the shape parameter.
    644 
    645         """
    646         # Jain, pg. 499; bug fix courtesy Bill Arms

    647 
    648         u = 1.0 - self.random()
    649         return alpha * pow(-_log(u), 1.0/beta)
    650 
    651 ## -------------------- Wichmann-Hill -------------------

    652 
    653 class WichmannHill(Random):
    654 
    655     VERSION = 1     # used by getstate/setstate

    656 
    657     def seed(self, a=None):
    658         """Initialize internal state from hashable object.
    659 
    660         None or no argument seeds from current time or from an operating
    661         system specific randomness source if available.
    662 
    663         If a is not None or an int or long, hash(a) is used instead.
    664 
    665         If a is an int or long, a is used directly.  Distinct values between
    666         0 and 27814431486575L inclusive are guaranteed to yield distinct
    667         internal states (this guarantee is specific to the default
    668         Wichmann-Hill generator).
    669         """
    670 
    671         if a is None:
    672             try:
    673                 a = long(_hexlify(_urandom(16)), 16)
    674             except NotImplementedError:
    675                 import time
    676                 a = long(time.time() * 256) # use fractional seconds

    677 
    678         if not isinstance(a, (int, long)):
    679             a = hash(a)
    680 
    681         a, x = divmod(a, 30268)
    682         a, y = divmod(a, 30306)
    683         a, z = divmod(a, 30322)
    684         self._seed = int(x)+1, int(y)+1, int(z)+1
    685 
    686         self.gauss_next = None
    687 
    688     def random(self):
    689         """Get the next random number in the range [0.0, 1.0)."""
    690 
    691         # Wichman-Hill random number generator.

    692         #

    693         # Wichmann, B. A. & Hill, I. D. (1982)

    694         # Algorithm AS 183:

    695         # An efficient and portable pseudo-random number generator

    696         # Applied Statistics 31 (1982) 188-190

    697         #

    698         # see also:

    699         #        Correction to Algorithm AS 183

    700         #        Applied Statistics 33 (1984) 123

    701         #

    702         #        McLeod, A. I. (1985)

    703         #        A remark on Algorithm AS 183

    704         #        Applied Statistics 34 (1985),198-200

    705 
    706         # This part is thread-unsafe:

    707         # BEGIN CRITICAL SECTION

    708         x, y, z = self._seed
    709         x = (171 * x) % 30269
    710         y = (172 * y) % 30307
    711         z = (170 * z) % 30323
    712         self._seed = x, y, z
    713         # END CRITICAL SECTION

    714 
    715         # Note:  on a platform using IEEE-754 double arithmetic, this can

    716         # never return 0.0 (asserted by Tim; proof too long for a comment).

    717         return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
    718 
    719     def getstate(self):
    720         """Return internal state; can be passed to setstate() later."""
    721         return self.VERSION, self._seed, self.gauss_next
    722 
    723     def setstate(self, state):
    724         """Restore internal state from object returned by getstate()."""
    725         version = state[0]
    726         if version == 1:
    727             version, self._seed, self.gauss_next = state
    728         else:
    729             raise ValueError("state with version %s passed to "
    730                              "Random.setstate() of version %s" %
    731                              (version, self.VERSION))
    732 
    733     def jumpahead(self, n):
    734         """Act as if n calls to random() were made, but quickly.
    735 
    736         n is an int, greater than or equal to 0.
    737 
    738         Example use:  If you have 2 threads and know that each will
    739         consume no more than a million random numbers, create two Random
    740         objects r1 and r2, then do
    741             r2.setstate(r1.getstate())
    742             r2.jumpahead(1000000)
    743         Then r1 and r2 will use guaranteed-disjoint segments of the full
    744         period.
    745         """
    746 
    747         if not n >= 0:
    748             raise ValueError("n must be >= 0")
    749         x, y, z = self._seed
    750         x = int(x * pow(171, n, 30269)) % 30269
    751         y = int(y * pow(172, n, 30307)) % 30307
    752         z = int(z * pow(170, n, 30323)) % 30323
    753         self._seed = x, y, z
    754 
    755     def __whseed(self, x=0, y=0, z=0):
    756         """Set the Wichmann-Hill seed from (x, y, z).
    757 
    758         These must be integers in the range [0, 256).
    759         """
    760 
    761         if not type(x) == type(y) == type(z) == int:
    762             raise TypeError('seeds must be integers')
    763         if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
    764             raise ValueError('seeds must be in range(0, 256)')
    765         if 0 == x == y == z:
    766             # Initialize from current time

    767             import time
    768             t = long(time.time() * 256)
    769             t = int((t&0xffffff) ^ (t>>24))
    770             t, x = divmod(t, 256)
    771             t, y = divmod(t, 256)
    772             t, z = divmod(t, 256)
    773         # Zero is a poor seed, so substitute 1

    774         self._seed = (x or 1, y or 1, z or 1)
    775 
    776         self.gauss_next = None
    777 
    778     def whseed(self, a=None):
    779         """Seed from hashable object's hash code.
    780 
    781         None or no argument seeds from current time.  It is not guaranteed
    782         that objects with distinct hash codes lead to distinct internal
    783         states.
    784 
    785         This is obsolete, provided for compatibility with the seed routine
    786         used prior to Python 2.1.  Use the .seed() method instead.
    787         """
    788 
    789         if a is None:
    790             self.__whseed()
    791             return
    792         a = hash(a)
    793         a, x = divmod(a, 256)
    794         a, y = divmod(a, 256)
    795         a, z = divmod(a, 256)
    796         x = (x + a) % 256 or 1
    797         y = (y + a) % 256 or 1
    798         z = (z + a) % 256 or 1
    799         self.__whseed(x, y, z)
    800 
    801 ## --------------- Operating System Random Source  ------------------

    802 
    803 class SystemRandom(Random):
    804     """Alternate random number generator using sources provided
    805     by the operating system (such as /dev/urandom on Unix or
    806     CryptGenRandom on Windows).
    807 
    808      Not available on all systems (see os.urandom() for details).
    809     """
    810 
    811     def random(self):
    812         """Get the next random number in the range [0.0, 1.0)."""
    813         return (long(_hexlify(_urandom(7)), 16) >> 3) * RECIP_BPF
    814 
    815     def getrandbits(self, k):
    816         """getrandbits(k) -> x.  Generates a long int with k random bits."""
    817         if k <= 0:
    818             raise ValueError('number of bits must be greater than zero')
    819         if k != int(k):
    820             raise TypeError('number of bits should be an integer')
    821         bytes = (k + 7) // 8                    # bits / 8 and rounded up

    822         x = long(_hexlify(_urandom(bytes)), 16)
    823         return x >> (bytes * 8 - k)             # trim excess bits

    824 
    825     def _stub(self, *args, **kwds):
    826         "Stub method.  Not used for a system random number generator."
    827         return None
    828     seed = jumpahead = _stub
    829 
    830     def _notimplemented(self, *args, **kwds):
    831         "Method should not be called for a system random number generator."
    832         raise NotImplementedError('System entropy source does not have state.')
    833     getstate = setstate = _notimplemented
    834 
    835 ## -------------------- test program --------------------

    836 
    837 def _test_generator(n, func, args):
    838     import time
    839     print n, 'times', func.__name__
    840     total = 0.0
    841     sqsum = 0.0
    842     smallest = 1e10
    843     largest = -1e10
    844     t0 = time.time()
    845     for i in range(n):
    846         x = func(*args)
    847         total += x
    848         sqsum = sqsum + x*x
    849         smallest = min(x, smallest)
    850         largest = max(x, largest)
    851     t1 = time.time()
    852     print round(t1-t0, 3), 'sec,',
    853     avg = total/n
    854     stddev = _sqrt(sqsum/n - avg*avg)
    855     print 'avg %g, stddev %g, min %g, max %g' % \
    856               (avg, stddev, smallest, largest)
    857 
    858 
    859 def _test(N=2000):
    860     _test_generator(N, random, ())
    861     _test_generator(N, normalvariate, (0.0, 1.0))
    862     _test_generator(N, lognormvariate, (0.0, 1.0))
    863     _test_generator(N, vonmisesvariate, (0.0, 1.0))
    864     _test_generator(N, gammavariate, (0.01, 1.0))
    865     _test_generator(N, gammavariate, (0.1, 1.0))
    866     _test_generator(N, gammavariate, (0.1, 2.0))
    867     _test_generator(N, gammavariate, (0.5, 1.0))
    868     _test_generator(N, gammavariate, (0.9, 1.0))
    869     _test_generator(N, gammavariate, (1.0, 1.0))
    870     _test_generator(N, gammavariate, (2.0, 1.0))
    871     _test_generator(N, gammavariate, (20.0, 1.0))
    872     _test_generator(N, gammavariate, (200.0, 1.0))
    873     _test_generator(N, gauss, (0.0, 1.0))
    874     _test_generator(N, betavariate, (3.0, 3.0))
    875     _test_generator(N, triangular, (0.0, 1.0, 1.0/3.0))
    876 
    877 # Create one instance, seeded from current time, and export its methods

    878 # as module-level functions.  The functions share state across all uses

    879 #(both in the user's code and in the Python libraries), but that's fine

    880 # for most programs and is easier for the casual user than making them

    881 # instantiate their own Random() instance.

    882 
    883 _inst = Random()
    884 seed = _inst.seed
    885 random = _inst.random
    886 uniform = _inst.uniform
    887 triangular = _inst.triangular
    888 randint = _inst.randint
    889 choice = _inst.choice
    890 randrange = _inst.randrange
    891 sample = _inst.sample
    892 shuffle = _inst.shuffle
    893 normalvariate = _inst.normalvariate
    894 lognormvariate = _inst.lognormvariate
    895 expovariate = _inst.expovariate
    896 vonmisesvariate = _inst.vonmisesvariate
    897 gammavariate = _inst.gammavariate
    898 gauss = _inst.gauss
    899 betavariate = _inst.betavariate
    900 paretovariate = _inst.paretovariate
    901 weibullvariate = _inst.weibullvariate
    902 getstate = _inst.getstate
    903 setstate = _inst.setstate
    904 jumpahead = _inst.jumpahead
    905 getrandbits = _inst.getrandbits
    906 
    907 if __name__ == '__main__':
    908     _test()
    909