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