Home | History | Annotate | Download | only in python2.7
      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         # we use 1-random() instead of random() to preclude the
    431         # possibility of taking the log of zero.
    432         return -_log(1.0 - self.random())/lambd
    433 
    434 ## -------------------- von Mises distribution --------------------
    435 
    436     def vonmisesvariate(self, mu, kappa):
    437         """Circular data distribution.
    438 
    439         mu is the mean angle, expressed in radians between 0 and 2*pi, and
    440         kappa is the concentration parameter, which must be greater than or
    441         equal to zero.  If kappa is equal to zero, this distribution reduces
    442         to a uniform random angle over the range 0 to 2*pi.
    443 
    444         """
    445         # mu:    mean angle (in radians between 0 and 2*pi)
    446         # kappa: concentration parameter kappa (>= 0)
    447         # if kappa = 0 generate uniform random angle
    448 
    449         # Based upon an algorithm published in: Fisher, N.I.,
    450         # "Statistical Analysis of Circular Data", Cambridge
    451         # University Press, 1993.
    452 
    453         # Thanks to Magnus Kessler for a correction to the
    454         # implementation of step 4.
    455 
    456         random = self.random
    457         if kappa <= 1e-6:
    458             return TWOPI * random()
    459 
    460         s = 0.5 / kappa
    461         r = s + _sqrt(1.0 + s * s)
    462 
    463         while 1:
    464             u1 = random()
    465             z = _cos(_pi * u1)
    466 
    467             d = z / (r + z)
    468             u2 = random()
    469             if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d):
    470                 break
    471 
    472         q = 1.0 / r
    473         f = (q + z) / (1.0 + q * z)
    474         u3 = random()
    475         if u3 > 0.5:
    476             theta = (mu + _acos(f)) % TWOPI
    477         else:
    478             theta = (mu - _acos(f)) % TWOPI
    479 
    480         return theta
    481 
    482 ## -------------------- gamma distribution --------------------
    483 
    484     def gammavariate(self, alpha, beta):
    485         """Gamma distribution.  Not the gamma function!
    486 
    487         Conditions on the parameters are alpha > 0 and beta > 0.
    488 
    489         The probability distribution function is:
    490 
    491                     x ** (alpha - 1) * math.exp(-x / beta)
    492           pdf(x) =  --------------------------------------
    493                       math.gamma(alpha) * beta ** alpha
    494 
    495         """
    496 
    497         # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
    498 
    499         # Warning: a few older sources define the gamma distribution in terms
    500         # of alpha > -1.0
    501         if alpha <= 0.0 or beta <= 0.0:
    502             raise ValueError, 'gammavariate: alpha and beta must be > 0.0'
    503 
    504         random = self.random
    505         if alpha > 1.0:
    506 
    507             # Uses R.C.H. Cheng, "The generation of Gamma
    508             # variables with non-integral shape parameters",
    509             # Applied Statistics, (1977), 26, No. 1, p71-74
    510 
    511             ainv = _sqrt(2.0 * alpha - 1.0)
    512             bbb = alpha - LOG4
    513             ccc = alpha + ainv
    514 
    515             while 1:
    516                 u1 = random()
    517                 if not 1e-7 < u1 < .9999999:
    518                     continue
    519                 u2 = 1.0 - random()
    520                 v = _log(u1/(1.0-u1))/ainv
    521                 x = alpha*_exp(v)
    522                 z = u1*u1*u2
    523                 r = bbb+ccc*v-x
    524                 if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
    525                     return x * beta
    526 
    527         elif alpha == 1.0:
    528             # expovariate(1)
    529             u = random()
    530             while u <= 1e-7:
    531                 u = random()
    532             return -_log(u) * beta
    533 
    534         else:   # alpha is between 0 and 1 (exclusive)
    535 
    536             # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
    537 
    538             while 1:
    539                 u = random()
    540                 b = (_e + alpha)/_e
    541                 p = b*u
    542                 if p <= 1.0:
    543                     x = p ** (1.0/alpha)
    544                 else:
    545                     x = -_log((b-p)/alpha)
    546                 u1 = random()
    547                 if p > 1.0:
    548                     if u1 <= x ** (alpha - 1.0):
    549                         break
    550                 elif u1 <= _exp(-x):
    551                     break
    552             return x * beta
    553 
    554 ## -------------------- Gauss (faster alternative) --------------------
    555 
    556     def gauss(self, mu, sigma):
    557         """Gaussian distribution.
    558 
    559         mu is the mean, and sigma is the standard deviation.  This is
    560         slightly faster than the normalvariate() function.
    561 
    562         Not thread-safe without a lock around calls.
    563 
    564         """
    565 
    566         # When x and y are two variables from [0, 1), uniformly
    567         # distributed, then
    568         #
    569         #    cos(2*pi*x)*sqrt(-2*log(1-y))
    570         #    sin(2*pi*x)*sqrt(-2*log(1-y))
    571         #
    572         # are two *independent* variables with normal distribution
    573         # (mu = 0, sigma = 1).
    574         # (Lambert Meertens)
    575         # (corrected version; bug discovered by Mike Miller, fixed by LM)
    576 
    577         # Multithreading note: When two threads call this function
    578         # simultaneously, it is possible that they will receive the
    579         # same return value.  The window is very small though.  To
    580         # avoid this, you have to use a lock around all calls.  (I
    581         # didn't want to slow this down in the serial case by using a
    582         # lock here.)
    583 
    584         random = self.random
    585         z = self.gauss_next
    586         self.gauss_next = None
    587         if z is None:
    588             x2pi = random() * TWOPI
    589             g2rad = _sqrt(-2.0 * _log(1.0 - random()))
    590             z = _cos(x2pi) * g2rad
    591             self.gauss_next = _sin(x2pi) * g2rad
    592 
    593         return mu + z*sigma
    594 
    595 ## -------------------- beta --------------------
    596 ## See
    597 ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html
    598 ## for Ivan Frohne's insightful analysis of why the original implementation:
    599 ##
    600 ##    def betavariate(self, alpha, beta):
    601 ##        # Discrete Event Simulation in C, pp 87-88.
    602 ##
    603 ##        y = self.expovariate(alpha)
    604 ##        z = self.expovariate(1.0/beta)
    605 ##        return z/(y+z)
    606 ##
    607 ## was dead wrong, and how it probably got that way.
    608 
    609     def betavariate(self, alpha, beta):
    610         """Beta distribution.
    611 
    612         Conditions on the parameters are alpha > 0 and beta > 0.
    613         Returned values range between 0 and 1.
    614 
    615         """
    616 
    617         # This version due to Janne Sinkkonen, and matches all the std
    618         # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
    619         y = self.gammavariate(alpha, 1.)
    620         if y == 0:
    621             return 0.0
    622         else:
    623             return y / (y + self.gammavariate(beta, 1.))
    624 
    625 ## -------------------- Pareto --------------------
    626 
    627     def paretovariate(self, alpha):
    628         """Pareto distribution.  alpha is the shape parameter."""
    629         # Jain, pg. 495
    630 
    631         u = 1.0 - self.random()
    632         return 1.0 / pow(u, 1.0/alpha)
    633 
    634 ## -------------------- Weibull --------------------
    635 
    636     def weibullvariate(self, alpha, beta):
    637         """Weibull distribution.
    638 
    639         alpha is the scale parameter and beta is the shape parameter.
    640 
    641         """
    642         # Jain, pg. 499; bug fix courtesy Bill Arms
    643 
    644         u = 1.0 - self.random()
    645         return alpha * pow(-_log(u), 1.0/beta)
    646 
    647 ## -------------------- Wichmann-Hill -------------------
    648 
    649 class WichmannHill(Random):
    650 
    651     VERSION = 1     # used by getstate/setstate
    652 
    653     def seed(self, a=None):
    654         """Initialize internal state from hashable object.
    655 
    656         None or no argument seeds from current time or from an operating
    657         system specific randomness source if available.
    658 
    659         If a is not None or an int or long, hash(a) is used instead.
    660 
    661         If a is an int or long, a is used directly.  Distinct values between
    662         0 and 27814431486575L inclusive are guaranteed to yield distinct
    663         internal states (this guarantee is specific to the default
    664         Wichmann-Hill generator).
    665         """
    666 
    667         if a is None:
    668             try:
    669                 a = long(_hexlify(_urandom(16)), 16)
    670             except NotImplementedError:
    671                 import time
    672                 a = long(time.time() * 256) # use fractional seconds
    673 
    674         if not isinstance(a, (int, long)):
    675             a = hash(a)
    676 
    677         a, x = divmod(a, 30268)
    678         a, y = divmod(a, 30306)
    679         a, z = divmod(a, 30322)
    680         self._seed = int(x)+1, int(y)+1, int(z)+1
    681 
    682         self.gauss_next = None
    683 
    684     def random(self):
    685         """Get the next random number in the range [0.0, 1.0)."""
    686 
    687         # Wichman-Hill random number generator.
    688         #
    689         # Wichmann, B. A. & Hill, I. D. (1982)
    690         # Algorithm AS 183:
    691         # An efficient and portable pseudo-random number generator
    692         # Applied Statistics 31 (1982) 188-190
    693         #
    694         # see also:
    695         #        Correction to Algorithm AS 183
    696         #        Applied Statistics 33 (1984) 123
    697         #
    698         #        McLeod, A. I. (1985)
    699         #        A remark on Algorithm AS 183
    700         #        Applied Statistics 34 (1985),198-200
    701 
    702         # This part is thread-unsafe:
    703         # BEGIN CRITICAL SECTION
    704         x, y, z = self._seed
    705         x = (171 * x) % 30269
    706         y = (172 * y) % 30307
    707         z = (170 * z) % 30323
    708         self._seed = x, y, z
    709         # END CRITICAL SECTION
    710 
    711         # Note:  on a platform using IEEE-754 double arithmetic, this can
    712         # never return 0.0 (asserted by Tim; proof too long for a comment).
    713         return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
    714 
    715     def getstate(self):
    716         """Return internal state; can be passed to setstate() later."""
    717         return self.VERSION, self._seed, self.gauss_next
    718 
    719     def setstate(self, state):
    720         """Restore internal state from object returned by getstate()."""
    721         version = state[0]
    722         if version == 1:
    723             version, self._seed, self.gauss_next = state
    724         else:
    725             raise ValueError("state with version %s passed to "
    726                              "Random.setstate() of version %s" %
    727                              (version, self.VERSION))
    728 
    729     def jumpahead(self, n):
    730         """Act as if n calls to random() were made, but quickly.
    731 
    732         n is an int, greater than or equal to 0.
    733 
    734         Example use:  If you have 2 threads and know that each will
    735         consume no more than a million random numbers, create two Random
    736         objects r1 and r2, then do
    737             r2.setstate(r1.getstate())
    738             r2.jumpahead(1000000)
    739         Then r1 and r2 will use guaranteed-disjoint segments of the full
    740         period.
    741         """
    742 
    743         if not n >= 0:
    744             raise ValueError("n must be >= 0")
    745         x, y, z = self._seed
    746         x = int(x * pow(171, n, 30269)) % 30269
    747         y = int(y * pow(172, n, 30307)) % 30307
    748         z = int(z * pow(170, n, 30323)) % 30323
    749         self._seed = x, y, z
    750 
    751     def __whseed(self, x=0, y=0, z=0):
    752         """Set the Wichmann-Hill seed from (x, y, z).
    753 
    754         These must be integers in the range [0, 256).
    755         """
    756 
    757         if not type(x) == type(y) == type(z) == int:
    758             raise TypeError('seeds must be integers')
    759         if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
    760             raise ValueError('seeds must be in range(0, 256)')
    761         if 0 == x == y == z:
    762             # Initialize from current time
    763             import time
    764             t = long(time.time() * 256)
    765             t = int((t&0xffffff) ^ (t>>24))
    766             t, x = divmod(t, 256)
    767             t, y = divmod(t, 256)
    768             t, z = divmod(t, 256)
    769         # Zero is a poor seed, so substitute 1
    770         self._seed = (x or 1, y or 1, z or 1)
    771 
    772         self.gauss_next = None
    773 
    774     def whseed(self, a=None):
    775         """Seed from hashable object's hash code.
    776 
    777         None or no argument seeds from current time.  It is not guaranteed
    778         that objects with distinct hash codes lead to distinct internal
    779         states.
    780 
    781         This is obsolete, provided for compatibility with the seed routine
    782         used prior to Python 2.1.  Use the .seed() method instead.
    783         """
    784 
    785         if a is None:
    786             self.__whseed()
    787             return
    788         a = hash(a)
    789         a, x = divmod(a, 256)
    790         a, y = divmod(a, 256)
    791         a, z = divmod(a, 256)
    792         x = (x + a) % 256 or 1
    793         y = (y + a) % 256 or 1
    794         z = (z + a) % 256 or 1
    795         self.__whseed(x, y, z)
    796 
    797 ## --------------- Operating System Random Source  ------------------
    798 
    799 class SystemRandom(Random):
    800     """Alternate random number generator using sources provided
    801     by the operating system (such as /dev/urandom on Unix or
    802     CryptGenRandom on Windows).
    803 
    804      Not available on all systems (see os.urandom() for details).
    805     """
    806 
    807     def random(self):
    808         """Get the next random number in the range [0.0, 1.0)."""
    809         return (long(_hexlify(_urandom(7)), 16) >> 3) * RECIP_BPF
    810 
    811     def getrandbits(self, k):
    812         """getrandbits(k) -> x.  Generates a long int with k random bits."""
    813         if k <= 0:
    814             raise ValueError('number of bits must be greater than zero')
    815         if k != int(k):
    816             raise TypeError('number of bits should be an integer')
    817         bytes = (k + 7) // 8                    # bits / 8 and rounded up
    818         x = long(_hexlify(_urandom(bytes)), 16)
    819         return x >> (bytes * 8 - k)             # trim excess bits
    820 
    821     def _stub(self, *args, **kwds):
    822         "Stub method.  Not used for a system random number generator."
    823         return None
    824     seed = jumpahead = _stub
    825 
    826     def _notimplemented(self, *args, **kwds):
    827         "Method should not be called for a system random number generator."
    828         raise NotImplementedError('System entropy source does not have state.')
    829     getstate = setstate = _notimplemented
    830 
    831 ## -------------------- test program --------------------
    832 
    833 def _test_generator(n, func, args):
    834     import time
    835     print n, 'times', func.__name__
    836     total = 0.0
    837     sqsum = 0.0
    838     smallest = 1e10
    839     largest = -1e10
    840     t0 = time.time()
    841     for i in range(n):
    842         x = func(*args)
    843         total += x
    844         sqsum = sqsum + x*x
    845         smallest = min(x, smallest)
    846         largest = max(x, largest)
    847     t1 = time.time()
    848     print round(t1-t0, 3), 'sec,',
    849     avg = total/n
    850     stddev = _sqrt(sqsum/n - avg*avg)
    851     print 'avg %g, stddev %g, min %g, max %g' % \
    852               (avg, stddev, smallest, largest)
    853 
    854 
    855 def _test(N=2000):
    856     _test_generator(N, random, ())
    857     _test_generator(N, normalvariate, (0.0, 1.0))
    858     _test_generator(N, lognormvariate, (0.0, 1.0))
    859     _test_generator(N, vonmisesvariate, (0.0, 1.0))
    860     _test_generator(N, gammavariate, (0.01, 1.0))
    861     _test_generator(N, gammavariate, (0.1, 1.0))
    862     _test_generator(N, gammavariate, (0.1, 2.0))
    863     _test_generator(N, gammavariate, (0.5, 1.0))
    864     _test_generator(N, gammavariate, (0.9, 1.0))
    865     _test_generator(N, gammavariate, (1.0, 1.0))
    866     _test_generator(N, gammavariate, (2.0, 1.0))
    867     _test_generator(N, gammavariate, (20.0, 1.0))
    868     _test_generator(N, gammavariate, (200.0, 1.0))
    869     _test_generator(N, gauss, (0.0, 1.0))
    870     _test_generator(N, betavariate, (3.0, 3.0))
    871     _test_generator(N, triangular, (0.0, 1.0, 1.0/3.0))
    872 
    873 # Create one instance, seeded from current time, and export its methods
    874 # as module-level functions.  The functions share state across all uses
    875 #(both in the user's code and in the Python libraries), but that's fine
    876 # for most programs and is easier for the casual user than making them
    877 # instantiate their own Random() instance.
    878 
    879 _inst = Random()
    880 seed = _inst.seed
    881 random = _inst.random
    882 uniform = _inst.uniform
    883 triangular = _inst.triangular
    884 randint = _inst.randint
    885 choice = _inst.choice
    886 randrange = _inst.randrange
    887 sample = _inst.sample
    888 shuffle = _inst.shuffle
    889 normalvariate = _inst.normalvariate
    890 lognormvariate = _inst.lognormvariate
    891 expovariate = _inst.expovariate
    892 vonmisesvariate = _inst.vonmisesvariate
    893 gammavariate = _inst.gammavariate
    894 gauss = _inst.gauss
    895 betavariate = _inst.betavariate
    896 paretovariate = _inst.paretovariate
    897 weibullvariate = _inst.weibullvariate
    898 getstate = _inst.getstate
    899 setstate = _inst.setstate
    900 jumpahead = _inst.jumpahead
    901 getrandbits = _inst.getrandbits
    902 
    903 if __name__ == '__main__':
    904     _test()
    905