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