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