python-2.5.2/win32/Lib/random.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     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            normal (Gaussian)
       
    17            lognormal
       
    18            negative exponential
       
    19            gamma
       
    20            beta
       
    21            pareto
       
    22            Weibull
       
    23 
       
    24     distributions on the circle (angles 0 to 2pi)
       
    25     ---------------------------------------------
       
    26            circular uniform
       
    27            von Mises
       
    28 
       
    29 General notes on the underlying Mersenne Twister core generator:
       
    30 
       
    31 * The period is 2**19937-1.
       
    32 * It is one of the most extensively tested generators in existence.
       
    33 * Without a direct way to compute N steps forward, the semantics of
       
    34   jumpahead(n) are weakened to simply jump to another distant state and rely
       
    35   on the large period to avoid overlapping sequences.
       
    36 * The random() method is implemented in C, executes in a single Python step,
       
    37   and is, therefore, threadsafe.
       
    38 
       
    39 """
       
    40 
       
    41 from warnings import warn as _warn
       
    42 from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType
       
    43 from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
       
    44 from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
       
    45 from os import urandom as _urandom
       
    46 from binascii import hexlify as _hexlify
       
    47 
       
    48 __all__ = ["Random","seed","random","uniform","randint","choice","sample",
       
    49            "randrange","shuffle","normalvariate","lognormvariate",
       
    50            "expovariate","vonmisesvariate","gammavariate",
       
    51            "gauss","betavariate","paretovariate","weibullvariate",
       
    52            "getstate","setstate","jumpahead", "WichmannHill", "getrandbits",
       
    53            "SystemRandom"]
       
    54 
       
    55 NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
       
    56 TWOPI = 2.0*_pi
       
    57 LOG4 = _log(4.0)
       
    58 SG_MAGICCONST = 1.0 + _log(4.5)
       
    59 BPF = 53        # Number of bits in a float
       
    60 RECIP_BPF = 2**-BPF
       
    61 
       
    62 
       
    63 # Translated by Guido van Rossum from C source provided by
       
    64 # Adrian Baddeley.  Adapted by Raymond Hettinger for use with
       
    65 # the Mersenne Twister  and os.urandom() core generators.
       
    66 
       
    67 import _random
       
    68 
       
    69 class Random(_random.Random):
       
    70     """Random number generator base class used by bound module functions.
       
    71 
       
    72     Used to instantiate instances of Random to get generators that don't
       
    73     share state.  Especially useful for multi-threaded programs, creating
       
    74     a different instance of Random for each thread, and using the jumpahead()
       
    75     method to ensure that the generated sequences seen by each thread don't
       
    76     overlap.
       
    77 
       
    78     Class Random can also be subclassed if you want to use a different basic
       
    79     generator of your own devising: in that case, override the following
       
    80     methods:  random(), seed(), getstate(), setstate() and jumpahead().
       
    81     Optionally, implement a getrandombits() method so that randrange()
       
    82     can cover arbitrarily large ranges.
       
    83 
       
    84     """
       
    85 
       
    86     VERSION = 2     # used by getstate/setstate
       
    87 
       
    88     def __init__(self, x=None):
       
    89         """Initialize an instance.
       
    90 
       
    91         Optional argument x controls seeding, as for Random.seed().
       
    92         """
       
    93 
       
    94         self.seed(x)
       
    95         self.gauss_next = None
       
    96 
       
    97     def seed(self, a=None):
       
    98         """Initialize internal state from hashable object.
       
    99 
       
   100         None or no argument seeds from current time or from an operating
       
   101         system specific randomness source if available.
       
   102 
       
   103         If a is not None or an int or long, hash(a) is used instead.
       
   104         """
       
   105 
       
   106         if a is None:
       
   107             try:
       
   108                 a = long(_hexlify(_urandom(16)), 16)
       
   109             except NotImplementedError:
       
   110                 import time
       
   111                 a = long(time.time() * 256) # use fractional seconds
       
   112 
       
   113         super(Random, self).seed(a)
       
   114         self.gauss_next = None
       
   115 
       
   116     def getstate(self):
       
   117         """Return internal state; can be passed to setstate() later."""
       
   118         return self.VERSION, super(Random, self).getstate(), self.gauss_next
       
   119 
       
   120     def setstate(self, state):
       
   121         """Restore internal state from object returned by getstate()."""
       
   122         version = state[0]
       
   123         if version == 2:
       
   124             version, internalstate, self.gauss_next = state
       
   125             super(Random, self).setstate(internalstate)
       
   126         else:
       
   127             raise ValueError("state with version %s passed to "
       
   128                              "Random.setstate() of version %s" %
       
   129                              (version, self.VERSION))
       
   130 
       
   131 ## ---- Methods below this point do not need to be overridden when
       
   132 ## ---- subclassing for the purpose of using a different core generator.
       
   133 
       
   134 ## -------------------- pickle support  -------------------
       
   135 
       
   136     def __getstate__(self): # for pickle
       
   137         return self.getstate()
       
   138 
       
   139     def __setstate__(self, state):  # for pickle
       
   140         self.setstate(state)
       
   141 
       
   142     def __reduce__(self):
       
   143         return self.__class__, (), self.getstate()
       
   144 
       
   145 ## -------------------- integer methods  -------------------
       
   146 
       
   147     def randrange(self, start, stop=None, step=1, int=int, default=None,
       
   148                   maxwidth=1L<<BPF):
       
   149         """Choose a random item from range(start, stop[, step]).
       
   150 
       
   151         This fixes the problem with randint() which includes the
       
   152         endpoint; in Python this is usually not what you want.
       
   153         Do not supply the 'int', 'default', and 'maxwidth' arguments.
       
   154         """
       
   155 
       
   156         # This code is a bit messy to make it fast for the
       
   157         # common case while still doing adequate error checking.
       
   158         istart = int(start)
       
   159         if istart != start:
       
   160             raise ValueError, "non-integer arg 1 for randrange()"
       
   161         if stop is default:
       
   162             if istart > 0:
       
   163                 if istart >= maxwidth:
       
   164                     return self._randbelow(istart)
       
   165                 return int(self.random() * istart)
       
   166             raise ValueError, "empty range for randrange()"
       
   167 
       
   168         # stop argument supplied.
       
   169         istop = int(stop)
       
   170         if istop != stop:
       
   171             raise ValueError, "non-integer stop for randrange()"
       
   172         width = istop - istart
       
   173         if step == 1 and width > 0:
       
   174             # Note that
       
   175             #     int(istart + self.random()*width)
       
   176             # instead would be incorrect.  For example, consider istart
       
   177             # = -2 and istop = 0.  Then the guts would be in
       
   178             # -2.0 to 0.0 exclusive on both ends (ignoring that random()
       
   179             # might return 0.0), and because int() truncates toward 0, the
       
   180             # final result would be -1 or 0 (instead of -2 or -1).
       
   181             #     istart + int(self.random()*width)
       
   182             # would also be incorrect, for a subtler reason:  the RHS
       
   183             # can return a long, and then randrange() would also return
       
   184             # a long, but we're supposed to return an int (for backward
       
   185             # compatibility).
       
   186 
       
   187             if width >= maxwidth:
       
   188                 return int(istart + self._randbelow(width))
       
   189             return int(istart + int(self.random()*width))
       
   190         if step == 1:
       
   191             raise ValueError, "empty range for randrange() (%d,%d, %d)" % (istart, istop, width)
       
   192 
       
   193         # Non-unit step argument supplied.
       
   194         istep = int(step)
       
   195         if istep != step:
       
   196             raise ValueError, "non-integer step for randrange()"
       
   197         if istep > 0:
       
   198             n = (width + istep - 1) // istep
       
   199         elif istep < 0:
       
   200             n = (width + istep + 1) // istep
       
   201         else:
       
   202             raise ValueError, "zero step for randrange()"
       
   203 
       
   204         if n <= 0:
       
   205             raise ValueError, "empty range for randrange()"
       
   206 
       
   207         if n >= maxwidth:
       
   208             return istart + istep*self._randbelow(n)
       
   209         return istart + istep*int(self.random() * n)
       
   210 
       
   211     def randint(self, a, b):
       
   212         """Return random integer in range [a, b], including both end points.
       
   213         """
       
   214 
       
   215         return self.randrange(a, b+1)
       
   216 
       
   217     def _randbelow(self, n, _log=_log, int=int, _maxwidth=1L<<BPF,
       
   218                    _Method=_MethodType, _BuiltinMethod=_BuiltinMethodType):
       
   219         """Return a random int in the range [0,n)
       
   220 
       
   221         Handles the case where n has more bits than returned
       
   222         by a single call to the underlying generator.
       
   223         """
       
   224 
       
   225         try:
       
   226             getrandbits = self.getrandbits
       
   227         except AttributeError:
       
   228             pass
       
   229         else:
       
   230             # Only call self.getrandbits if the original random() builtin method
       
   231             # has not been overridden or if a new getrandbits() was supplied.
       
   232             # This assures that the two methods correspond.
       
   233             if type(self.random) is _BuiltinMethod or type(getrandbits) is _Method:
       
   234                 k = int(1.00001 + _log(n-1, 2.0))   # 2**k > n-1 > 2**(k-2)
       
   235                 r = getrandbits(k)
       
   236                 while r >= n:
       
   237                     r = getrandbits(k)
       
   238                 return r
       
   239         if n >= _maxwidth:
       
   240             _warn("Underlying random() generator does not supply \n"
       
   241                 "enough bits to choose from a population range this large")
       
   242         return int(self.random() * n)
       
   243 
       
   244 ## -------------------- sequence methods  -------------------
       
   245 
       
   246     def choice(self, seq):
       
   247         """Choose a random element from a non-empty sequence."""
       
   248         return seq[int(self.random() * len(seq))]  # raises IndexError if seq is empty
       
   249 
       
   250     def shuffle(self, x, random=None, int=int):
       
   251         """x, random=random.random -> shuffle list x in place; return None.
       
   252 
       
   253         Optional arg random is a 0-argument function returning a random
       
   254         float in [0.0, 1.0); by default, the standard random.random.
       
   255         """
       
   256 
       
   257         if random is None:
       
   258             random = self.random
       
   259         for i in reversed(xrange(1, len(x))):
       
   260             # pick an element in x[:i+1] with which to exchange x[i]
       
   261             j = int(random() * (i+1))
       
   262             x[i], x[j] = x[j], x[i]
       
   263 
       
   264     def sample(self, population, k):
       
   265         """Chooses k unique random elements from a population sequence.
       
   266 
       
   267         Returns a new list containing elements from the population while
       
   268         leaving the original population unchanged.  The resulting list is
       
   269         in selection order so that all sub-slices will also be valid random
       
   270         samples.  This allows raffle winners (the sample) to be partitioned
       
   271         into grand prize and second place winners (the subslices).
       
   272 
       
   273         Members of the population need not be hashable or unique.  If the
       
   274         population contains repeats, then each occurrence is a possible
       
   275         selection in the sample.
       
   276 
       
   277         To choose a sample in a range of integers, use xrange as an argument.
       
   278         This is especially fast and space efficient for sampling from a
       
   279         large population:   sample(xrange(10000000), 60)
       
   280         """
       
   281 
       
   282         # XXX Although the documentation says `population` is "a sequence",
       
   283         # XXX attempts are made to cater to any iterable with a __len__
       
   284         # XXX method.  This has had mixed success.  Examples from both
       
   285         # XXX sides:  sets work fine, and should become officially supported;
       
   286         # XXX dicts are much harder, and have failed in various subtle
       
   287         # XXX ways across attempts.  Support for mapping types should probably
       
   288         # XXX be dropped (and users should pass mapping.keys() or .values()
       
   289         # XXX explicitly).
       
   290 
       
   291         # Sampling without replacement entails tracking either potential
       
   292         # selections (the pool) in a list or previous selections in a set.
       
   293 
       
   294         # When the number of selections is small compared to the
       
   295         # population, then tracking selections is efficient, requiring
       
   296         # only a small set and an occasional reselection.  For
       
   297         # a larger number of selections, the pool tracking method is
       
   298         # preferred since the list takes less space than the
       
   299         # set and it doesn't suffer from frequent reselections.
       
   300 
       
   301         n = len(population)
       
   302         if not 0 <= k <= n:
       
   303             raise ValueError, "sample larger than population"
       
   304         random = self.random
       
   305         _int = int
       
   306         result = [None] * k
       
   307         setsize = 21        # size of a small set minus size of an empty list
       
   308         if k > 5:
       
   309             setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
       
   310         if n <= setsize or hasattr(population, "keys"):
       
   311             # An n-length list is smaller than a k-length set, or this is a
       
   312             # mapping type so the other algorithm wouldn't work.
       
   313             pool = list(population)
       
   314             for i in xrange(k):         # invariant:  non-selected at [0,n-i)
       
   315                 j = _int(random() * (n-i))
       
   316                 result[i] = pool[j]
       
   317                 pool[j] = pool[n-i-1]   # move non-selected item into vacancy
       
   318         else:
       
   319             try:
       
   320                 selected = set()
       
   321                 selected_add = selected.add
       
   322                 for i in xrange(k):
       
   323                     j = _int(random() * n)
       
   324                     while j in selected:
       
   325                         j = _int(random() * n)
       
   326                     selected_add(j)
       
   327                     result[i] = population[j]
       
   328             except (TypeError, KeyError):   # handle (at least) sets
       
   329                 if isinstance(population, list):
       
   330                     raise
       
   331                 return self.sample(tuple(population), k)
       
   332         return result
       
   333 
       
   334 ## -------------------- real-valued distributions  -------------------
       
   335 
       
   336 ## -------------------- uniform distribution -------------------
       
   337 
       
   338     def uniform(self, a, b):
       
   339         """Get a random number in the range [a, b)."""
       
   340         return a + (b-a) * self.random()
       
   341 
       
   342 ## -------------------- normal distribution --------------------
       
   343 
       
   344     def normalvariate(self, mu, sigma):
       
   345         """Normal distribution.
       
   346 
       
   347         mu is the mean, and sigma is the standard deviation.
       
   348 
       
   349         """
       
   350         # mu = mean, sigma = standard deviation
       
   351 
       
   352         # Uses Kinderman and Monahan method. Reference: Kinderman,
       
   353         # A.J. and Monahan, J.F., "Computer generation of random
       
   354         # variables using the ratio of uniform deviates", ACM Trans
       
   355         # Math Software, 3, (1977), pp257-260.
       
   356 
       
   357         random = self.random
       
   358         while 1:
       
   359             u1 = random()
       
   360             u2 = 1.0 - random()
       
   361             z = NV_MAGICCONST*(u1-0.5)/u2
       
   362             zz = z*z/4.0
       
   363             if zz <= -_log(u2):
       
   364                 break
       
   365         return mu + z*sigma
       
   366 
       
   367 ## -------------------- lognormal distribution --------------------
       
   368 
       
   369     def lognormvariate(self, mu, sigma):
       
   370         """Log normal distribution.
       
   371 
       
   372         If you take the natural logarithm of this distribution, you'll get a
       
   373         normal distribution with mean mu and standard deviation sigma.
       
   374         mu can have any value, and sigma must be greater than zero.
       
   375 
       
   376         """
       
   377         return _exp(self.normalvariate(mu, sigma))
       
   378 
       
   379 ## -------------------- exponential distribution --------------------
       
   380 
       
   381     def expovariate(self, lambd):
       
   382         """Exponential distribution.
       
   383 
       
   384         lambd is 1.0 divided by the desired mean.  (The parameter would be
       
   385         called "lambda", but that is a reserved word in Python.)  Returned
       
   386         values range from 0 to positive infinity.
       
   387 
       
   388         """
       
   389         # lambd: rate lambd = 1/mean
       
   390         # ('lambda' is a Python reserved word)
       
   391 
       
   392         random = self.random
       
   393         u = random()
       
   394         while u <= 1e-7:
       
   395             u = random()
       
   396         return -_log(u)/lambd
       
   397 
       
   398 ## -------------------- von Mises distribution --------------------
       
   399 
       
   400     def vonmisesvariate(self, mu, kappa):
       
   401         """Circular data distribution.
       
   402 
       
   403         mu is the mean angle, expressed in radians between 0 and 2*pi, and
       
   404         kappa is the concentration parameter, which must be greater than or
       
   405         equal to zero.  If kappa is equal to zero, this distribution reduces
       
   406         to a uniform random angle over the range 0 to 2*pi.
       
   407 
       
   408         """
       
   409         # mu:    mean angle (in radians between 0 and 2*pi)
       
   410         # kappa: concentration parameter kappa (>= 0)
       
   411         # if kappa = 0 generate uniform random angle
       
   412 
       
   413         # Based upon an algorithm published in: Fisher, N.I.,
       
   414         # "Statistical Analysis of Circular Data", Cambridge
       
   415         # University Press, 1993.
       
   416 
       
   417         # Thanks to Magnus Kessler for a correction to the
       
   418         # implementation of step 4.
       
   419 
       
   420         random = self.random
       
   421         if kappa <= 1e-6:
       
   422             return TWOPI * random()
       
   423 
       
   424         a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa)
       
   425         b = (a - _sqrt(2.0 * a))/(2.0 * kappa)
       
   426         r = (1.0 + b * b)/(2.0 * b)
       
   427 
       
   428         while 1:
       
   429             u1 = random()
       
   430 
       
   431             z = _cos(_pi * u1)
       
   432             f = (1.0 + r * z)/(r + z)
       
   433             c = kappa * (r - f)
       
   434 
       
   435             u2 = random()
       
   436 
       
   437             if u2 < c * (2.0 - c) or u2 <= c * _exp(1.0 - c):
       
   438                 break
       
   439 
       
   440         u3 = random()
       
   441         if u3 > 0.5:
       
   442             theta = (mu % TWOPI) + _acos(f)
       
   443         else:
       
   444             theta = (mu % TWOPI) - _acos(f)
       
   445 
       
   446         return theta
       
   447 
       
   448 ## -------------------- gamma distribution --------------------
       
   449 
       
   450     def gammavariate(self, alpha, beta):
       
   451         """Gamma distribution.  Not the gamma function!
       
   452 
       
   453         Conditions on the parameters are alpha > 0 and beta > 0.
       
   454 
       
   455         """
       
   456 
       
   457         # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
       
   458 
       
   459         # Warning: a few older sources define the gamma distribution in terms
       
   460         # of alpha > -1.0
       
   461         if alpha <= 0.0 or beta <= 0.0:
       
   462             raise ValueError, 'gammavariate: alpha and beta must be > 0.0'
       
   463 
       
   464         random = self.random
       
   465         if alpha > 1.0:
       
   466 
       
   467             # Uses R.C.H. Cheng, "The generation of Gamma
       
   468             # variables with non-integral shape parameters",
       
   469             # Applied Statistics, (1977), 26, No. 1, p71-74
       
   470 
       
   471             ainv = _sqrt(2.0 * alpha - 1.0)
       
   472             bbb = alpha - LOG4
       
   473             ccc = alpha + ainv
       
   474 
       
   475             while 1:
       
   476                 u1 = random()
       
   477                 if not 1e-7 < u1 < .9999999:
       
   478                     continue
       
   479                 u2 = 1.0 - random()
       
   480                 v = _log(u1/(1.0-u1))/ainv
       
   481                 x = alpha*_exp(v)
       
   482                 z = u1*u1*u2
       
   483                 r = bbb+ccc*v-x
       
   484                 if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
       
   485                     return x * beta
       
   486 
       
   487         elif alpha == 1.0:
       
   488             # expovariate(1)
       
   489             u = random()
       
   490             while u <= 1e-7:
       
   491                 u = random()
       
   492             return -_log(u) * beta
       
   493 
       
   494         else:   # alpha is between 0 and 1 (exclusive)
       
   495 
       
   496             # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
       
   497 
       
   498             while 1:
       
   499                 u = random()
       
   500                 b = (_e + alpha)/_e
       
   501                 p = b*u
       
   502                 if p <= 1.0:
       
   503                     x = p ** (1.0/alpha)
       
   504                 else:
       
   505                     x = -_log((b-p)/alpha)
       
   506                 u1 = random()
       
   507                 if p > 1.0:
       
   508                     if u1 <= x ** (alpha - 1.0):
       
   509                         break
       
   510                 elif u1 <= _exp(-x):
       
   511                     break
       
   512             return x * beta
       
   513 
       
   514 ## -------------------- Gauss (faster alternative) --------------------
       
   515 
       
   516     def gauss(self, mu, sigma):
       
   517         """Gaussian distribution.
       
   518 
       
   519         mu is the mean, and sigma is the standard deviation.  This is
       
   520         slightly faster than the normalvariate() function.
       
   521 
       
   522         Not thread-safe without a lock around calls.
       
   523 
       
   524         """
       
   525 
       
   526         # When x and y are two variables from [0, 1), uniformly
       
   527         # distributed, then
       
   528         #
       
   529         #    cos(2*pi*x)*sqrt(-2*log(1-y))
       
   530         #    sin(2*pi*x)*sqrt(-2*log(1-y))
       
   531         #
       
   532         # are two *independent* variables with normal distribution
       
   533         # (mu = 0, sigma = 1).
       
   534         # (Lambert Meertens)
       
   535         # (corrected version; bug discovered by Mike Miller, fixed by LM)
       
   536 
       
   537         # Multithreading note: When two threads call this function
       
   538         # simultaneously, it is possible that they will receive the
       
   539         # same return value.  The window is very small though.  To
       
   540         # avoid this, you have to use a lock around all calls.  (I
       
   541         # didn't want to slow this down in the serial case by using a
       
   542         # lock here.)
       
   543 
       
   544         random = self.random
       
   545         z = self.gauss_next
       
   546         self.gauss_next = None
       
   547         if z is None:
       
   548             x2pi = random() * TWOPI
       
   549             g2rad = _sqrt(-2.0 * _log(1.0 - random()))
       
   550             z = _cos(x2pi) * g2rad
       
   551             self.gauss_next = _sin(x2pi) * g2rad
       
   552 
       
   553         return mu + z*sigma
       
   554 
       
   555 ## -------------------- beta --------------------
       
   556 ## See
       
   557 ## http://sourceforge.net/bugs/?func=detailbug&bug_id=130030&group_id=5470
       
   558 ## for Ivan Frohne's insightful analysis of why the original implementation:
       
   559 ##
       
   560 ##    def betavariate(self, alpha, beta):
       
   561 ##        # Discrete Event Simulation in C, pp 87-88.
       
   562 ##
       
   563 ##        y = self.expovariate(alpha)
       
   564 ##        z = self.expovariate(1.0/beta)
       
   565 ##        return z/(y+z)
       
   566 ##
       
   567 ## was dead wrong, and how it probably got that way.
       
   568 
       
   569     def betavariate(self, alpha, beta):
       
   570         """Beta distribution.
       
   571 
       
   572         Conditions on the parameters are alpha > 0 and beta > 0.
       
   573         Returned values range between 0 and 1.
       
   574 
       
   575         """
       
   576 
       
   577         # This version due to Janne Sinkkonen, and matches all the std
       
   578         # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
       
   579         y = self.gammavariate(alpha, 1.)
       
   580         if y == 0:
       
   581             return 0.0
       
   582         else:
       
   583             return y / (y + self.gammavariate(beta, 1.))
       
   584 
       
   585 ## -------------------- Pareto --------------------
       
   586 
       
   587     def paretovariate(self, alpha):
       
   588         """Pareto distribution.  alpha is the shape parameter."""
       
   589         # Jain, pg. 495
       
   590 
       
   591         u = 1.0 - self.random()
       
   592         return 1.0 / pow(u, 1.0/alpha)
       
   593 
       
   594 ## -------------------- Weibull --------------------
       
   595 
       
   596     def weibullvariate(self, alpha, beta):
       
   597         """Weibull distribution.
       
   598 
       
   599         alpha is the scale parameter and beta is the shape parameter.
       
   600 
       
   601         """
       
   602         # Jain, pg. 499; bug fix courtesy Bill Arms
       
   603 
       
   604         u = 1.0 - self.random()
       
   605         return alpha * pow(-_log(u), 1.0/beta)
       
   606 
       
   607 ## -------------------- Wichmann-Hill -------------------
       
   608 
       
   609 class WichmannHill(Random):
       
   610 
       
   611     VERSION = 1     # used by getstate/setstate
       
   612 
       
   613     def seed(self, a=None):
       
   614         """Initialize internal state from hashable object.
       
   615 
       
   616         None or no argument seeds from current time or from an operating
       
   617         system specific randomness source if available.
       
   618 
       
   619         If a is not None or an int or long, hash(a) is used instead.
       
   620 
       
   621         If a is an int or long, a is used directly.  Distinct values between
       
   622         0 and 27814431486575L inclusive are guaranteed to yield distinct
       
   623         internal states (this guarantee is specific to the default
       
   624         Wichmann-Hill generator).
       
   625         """
       
   626 
       
   627         if a is None:
       
   628             try:
       
   629                 a = long(_hexlify(_urandom(16)), 16)
       
   630             except NotImplementedError:
       
   631                 import time
       
   632                 a = long(time.time() * 256) # use fractional seconds
       
   633 
       
   634         if not isinstance(a, (int, long)):
       
   635             a = hash(a)
       
   636 
       
   637         a, x = divmod(a, 30268)
       
   638         a, y = divmod(a, 30306)
       
   639         a, z = divmod(a, 30322)
       
   640         self._seed = int(x)+1, int(y)+1, int(z)+1
       
   641 
       
   642         self.gauss_next = None
       
   643 
       
   644     def random(self):
       
   645         """Get the next random number in the range [0.0, 1.0)."""
       
   646 
       
   647         # Wichman-Hill random number generator.
       
   648         #
       
   649         # Wichmann, B. A. & Hill, I. D. (1982)
       
   650         # Algorithm AS 183:
       
   651         # An efficient and portable pseudo-random number generator
       
   652         # Applied Statistics 31 (1982) 188-190
       
   653         #
       
   654         # see also:
       
   655         #        Correction to Algorithm AS 183
       
   656         #        Applied Statistics 33 (1984) 123
       
   657         #
       
   658         #        McLeod, A. I. (1985)
       
   659         #        A remark on Algorithm AS 183
       
   660         #        Applied Statistics 34 (1985),198-200
       
   661 
       
   662         # This part is thread-unsafe:
       
   663         # BEGIN CRITICAL SECTION
       
   664         x, y, z = self._seed
       
   665         x = (171 * x) % 30269
       
   666         y = (172 * y) % 30307
       
   667         z = (170 * z) % 30323
       
   668         self._seed = x, y, z
       
   669         # END CRITICAL SECTION
       
   670 
       
   671         # Note:  on a platform using IEEE-754 double arithmetic, this can
       
   672         # never return 0.0 (asserted by Tim; proof too long for a comment).
       
   673         return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
       
   674 
       
   675     def getstate(self):
       
   676         """Return internal state; can be passed to setstate() later."""
       
   677         return self.VERSION, self._seed, self.gauss_next
       
   678 
       
   679     def setstate(self, state):
       
   680         """Restore internal state from object returned by getstate()."""
       
   681         version = state[0]
       
   682         if version == 1:
       
   683             version, self._seed, self.gauss_next = state
       
   684         else:
       
   685             raise ValueError("state with version %s passed to "
       
   686                              "Random.setstate() of version %s" %
       
   687                              (version, self.VERSION))
       
   688 
       
   689     def jumpahead(self, n):
       
   690         """Act as if n calls to random() were made, but quickly.
       
   691 
       
   692         n is an int, greater than or equal to 0.
       
   693 
       
   694         Example use:  If you have 2 threads and know that each will
       
   695         consume no more than a million random numbers, create two Random
       
   696         objects r1 and r2, then do
       
   697             r2.setstate(r1.getstate())
       
   698             r2.jumpahead(1000000)
       
   699         Then r1 and r2 will use guaranteed-disjoint segments of the full
       
   700         period.
       
   701         """
       
   702 
       
   703         if not n >= 0:
       
   704             raise ValueError("n must be >= 0")
       
   705         x, y, z = self._seed
       
   706         x = int(x * pow(171, n, 30269)) % 30269
       
   707         y = int(y * pow(172, n, 30307)) % 30307
       
   708         z = int(z * pow(170, n, 30323)) % 30323
       
   709         self._seed = x, y, z
       
   710 
       
   711     def __whseed(self, x=0, y=0, z=0):
       
   712         """Set the Wichmann-Hill seed from (x, y, z).
       
   713 
       
   714         These must be integers in the range [0, 256).
       
   715         """
       
   716 
       
   717         if not type(x) == type(y) == type(z) == int:
       
   718             raise TypeError('seeds must be integers')
       
   719         if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
       
   720             raise ValueError('seeds must be in range(0, 256)')
       
   721         if 0 == x == y == z:
       
   722             # Initialize from current time
       
   723             import time
       
   724             t = long(time.time() * 256)
       
   725             t = int((t&0xffffff) ^ (t>>24))
       
   726             t, x = divmod(t, 256)
       
   727             t, y = divmod(t, 256)
       
   728             t, z = divmod(t, 256)
       
   729         # Zero is a poor seed, so substitute 1
       
   730         self._seed = (x or 1, y or 1, z or 1)
       
   731 
       
   732         self.gauss_next = None
       
   733 
       
   734     def whseed(self, a=None):
       
   735         """Seed from hashable object's hash code.
       
   736 
       
   737         None or no argument seeds from current time.  It is not guaranteed
       
   738         that objects with distinct hash codes lead to distinct internal
       
   739         states.
       
   740 
       
   741         This is obsolete, provided for compatibility with the seed routine
       
   742         used prior to Python 2.1.  Use the .seed() method instead.
       
   743         """
       
   744 
       
   745         if a is None:
       
   746             self.__whseed()
       
   747             return
       
   748         a = hash(a)
       
   749         a, x = divmod(a, 256)
       
   750         a, y = divmod(a, 256)
       
   751         a, z = divmod(a, 256)
       
   752         x = (x + a) % 256 or 1
       
   753         y = (y + a) % 256 or 1
       
   754         z = (z + a) % 256 or 1
       
   755         self.__whseed(x, y, z)
       
   756 
       
   757 ## --------------- Operating System Random Source  ------------------
       
   758 
       
   759 class SystemRandom(Random):
       
   760     """Alternate random number generator using sources provided
       
   761     by the operating system (such as /dev/urandom on Unix or
       
   762     CryptGenRandom on Windows).
       
   763 
       
   764      Not available on all systems (see os.urandom() for details).
       
   765     """
       
   766 
       
   767     def random(self):
       
   768         """Get the next random number in the range [0.0, 1.0)."""
       
   769         return (long(_hexlify(_urandom(7)), 16) >> 3) * RECIP_BPF
       
   770 
       
   771     def getrandbits(self, k):
       
   772         """getrandbits(k) -> x.  Generates a long int with k random bits."""
       
   773         if k <= 0:
       
   774             raise ValueError('number of bits must be greater than zero')
       
   775         if k != int(k):
       
   776             raise TypeError('number of bits should be an integer')
       
   777         bytes = (k + 7) // 8                    # bits / 8 and rounded up
       
   778         x = long(_hexlify(_urandom(bytes)), 16)
       
   779         return x >> (bytes * 8 - k)             # trim excess bits
       
   780 
       
   781     def _stub(self, *args, **kwds):
       
   782         "Stub method.  Not used for a system random number generator."
       
   783         return None
       
   784     seed = jumpahead = _stub
       
   785 
       
   786     def _notimplemented(self, *args, **kwds):
       
   787         "Method should not be called for a system random number generator."
       
   788         raise NotImplementedError('System entropy source does not have state.')
       
   789     getstate = setstate = _notimplemented
       
   790 
       
   791 ## -------------------- test program --------------------
       
   792 
       
   793 def _test_generator(n, func, args):
       
   794     import time
       
   795     print n, 'times', func.__name__
       
   796     total = 0.0
       
   797     sqsum = 0.0
       
   798     smallest = 1e10
       
   799     largest = -1e10
       
   800     t0 = time.time()
       
   801     for i in range(n):
       
   802         x = func(*args)
       
   803         total += x
       
   804         sqsum = sqsum + x*x
       
   805         smallest = min(x, smallest)
       
   806         largest = max(x, largest)
       
   807     t1 = time.time()
       
   808     print round(t1-t0, 3), 'sec,',
       
   809     avg = total/n
       
   810     stddev = _sqrt(sqsum/n - avg*avg)
       
   811     print 'avg %g, stddev %g, min %g, max %g' % \
       
   812               (avg, stddev, smallest, largest)
       
   813 
       
   814 
       
   815 def _test(N=2000):
       
   816     _test_generator(N, random, ())
       
   817     _test_generator(N, normalvariate, (0.0, 1.0))
       
   818     _test_generator(N, lognormvariate, (0.0, 1.0))
       
   819     _test_generator(N, vonmisesvariate, (0.0, 1.0))
       
   820     _test_generator(N, gammavariate, (0.01, 1.0))
       
   821     _test_generator(N, gammavariate, (0.1, 1.0))
       
   822     _test_generator(N, gammavariate, (0.1, 2.0))
       
   823     _test_generator(N, gammavariate, (0.5, 1.0))
       
   824     _test_generator(N, gammavariate, (0.9, 1.0))
       
   825     _test_generator(N, gammavariate, (1.0, 1.0))
       
   826     _test_generator(N, gammavariate, (2.0, 1.0))
       
   827     _test_generator(N, gammavariate, (20.0, 1.0))
       
   828     _test_generator(N, gammavariate, (200.0, 1.0))
       
   829     _test_generator(N, gauss, (0.0, 1.0))
       
   830     _test_generator(N, betavariate, (3.0, 3.0))
       
   831 
       
   832 # Create one instance, seeded from current time, and export its methods
       
   833 # as module-level functions.  The functions share state across all uses
       
   834 #(both in the user's code and in the Python libraries), but that's fine
       
   835 # for most programs and is easier for the casual user than making them
       
   836 # instantiate their own Random() instance.
       
   837 
       
   838 _inst = Random()
       
   839 seed = _inst.seed
       
   840 random = _inst.random
       
   841 uniform = _inst.uniform
       
   842 randint = _inst.randint
       
   843 choice = _inst.choice
       
   844 randrange = _inst.randrange
       
   845 sample = _inst.sample
       
   846 shuffle = _inst.shuffle
       
   847 normalvariate = _inst.normalvariate
       
   848 lognormvariate = _inst.lognormvariate
       
   849 expovariate = _inst.expovariate
       
   850 vonmisesvariate = _inst.vonmisesvariate
       
   851 gammavariate = _inst.gammavariate
       
   852 gauss = _inst.gauss
       
   853 betavariate = _inst.betavariate
       
   854 paretovariate = _inst.paretovariate
       
   855 weibullvariate = _inst.weibullvariate
       
   856 getstate = _inst.getstate
       
   857 setstate = _inst.setstate
       
   858 jumpahead = _inst.jumpahead
       
   859 getrandbits = _inst.getrandbits
       
   860 
       
   861 if __name__ == '__main__':
       
   862     _test()