| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f7ec7a8 commit 28de64f
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,25 +28,14 @@ for cryptographic purposes. | |||
| 28 | 28 | ||
| 29 | 29 | The functions supplied by this module are actually bound methods of a hidden | |
| 30 | 30 | instance of the :class:`random.Random` class. You can instantiate your own | |
| 31 | - instances of :class:`Random` to get generators that don't share state. This is | ||
| 32 | - especially useful for multi-threaded programs, creating a different instance of | ||
| 33 | - :class:`Random` for each thread, and using the :meth:`jumpahead` method to make | ||
| 34 | - it likely that the generated sequences seen by each thread don't overlap. | ||
| 31 | + instances of :class:`Random` to get generators that don't share state. | ||
| 35 | 32 | ||
| 36 | 33 | Class :class:`Random` can also be subclassed if you want to use a different | |
| 37 | 34 | basic generator of your own devising: in that case, override the :meth:`random`, | |
| 38 | - :meth:`seed`, :meth:`getstate`, :meth:`setstate` and :meth:`jumpahead` methods. | ||
| 35 | + :meth:`seed`, :meth:`getstate`, and :meth:`setstate`. | ||
| 39 | 36 | Optionally, a new generator can supply a :meth:`getrandombits` method --- this | |
| 40 | 37 | allows :meth:`randrange` to produce selections over an arbitrarily large range. | |
| 41 | 38 | ||
| 42 | - As an example of subclassing, the :mod:`random` module provides the | ||
| 43 | - :class:`WichmannHill` class that implements an alternative generator in pure | ||
| 44 | - Python. The class provides a backward compatible way to reproduce results from | ||
| 45 | - earlier versions of Python, which used the Wichmann-Hill algorithm as the core | ||
| 46 | - generator. Note that this Wichmann-Hill generator can no longer be recommended: | ||
| 47 | - its period is too short by contemporary standards, and the sequence generated is | ||
| 48 | - known to fail some stringent randomness tests. See the references below for a | ||
| 49 | - recent variant that repairs these flaws. | ||
| 50 | 39 | ||
| 51 | 40 | Bookkeeping functions: | |
| 52 | 41 | ||
@@ -79,17 +68,6 @@ Bookkeeping functions: | |||
| 79 | 68 | the time :func:`setstate` was called. | |
| 80 | 69 | ||
| 81 | 70 | ||
| 82 | - .. function:: jumpahead(n) | ||
| 83 | - | ||
| 84 | - Change the internal state to one different from and likely far away from the | ||
| 85 | - current state. *n* is a non-negative integer which is used to scramble the | ||
| 86 | - current state vector. This is most useful in multi-threaded programs, in | ||
| 87 | - conjuction with multiple instances of the :class:`Random` class: | ||
| 88 | - :meth:`setstate` or :meth:`seed` can be used to force all instances into the | ||
| 89 | - same internal state, and then :meth:`jumpahead` can be used to force the | ||
| 90 | - instances' states far apart. | ||
| 91 | - | ||
| 92 | - | ||
| 93 | 71 | .. function:: getrandbits(k) | |
| 94 | 72 | ||
| 95 | 73 | Returns a python integer with *k* random bits. This method is supplied with | |
@@ -224,24 +202,6 @@ be found in any statistics text. | |||
| 224 | 202 | ||
| 225 | 203 | Alternative Generators: | |
| 226 | 204 | ||
| 227 | - .. class:: WichmannHill([seed]) | ||
| 228 | - | ||
| 229 | - Class that implements the Wichmann-Hill algorithm as the core generator. Has all | ||
| 230 | - of the same methods as :class:`Random` plus the :meth:`whseed` method described | ||
| 231 | - below. Because this class is implemented in pure Python, it is not threadsafe | ||
| 232 | - and may require locks between calls. The period of the generator is | ||
| 233 | - 6,953,607,871,644 which is small enough to require care that two independent | ||
| 234 | - random sequences do not overlap. | ||
| 235 | - | ||
| 236 | - | ||
| 237 | - .. function:: whseed([x]) | ||
| 238 | - | ||
| 239 | - This is obsolete, supplied for bit-level compatibility with versions of Python | ||
| 240 | - prior to 2.1. See :func:`seed` for details. :func:`whseed` does not guarantee | ||
| 241 | - that distinct integer arguments yield distinct internal states, and can yield no | ||
| 242 | - more than about 2\*\*24 distinct internal states in all. | ||
| 243 | - | ||
| 244 | - | ||
| 245 | 205 | .. class:: SystemRandom([seed]) | |
| 246 | 206 | ||
| 247 | 207 | Class that uses the :func:`os.urandom` function for generating random numbers | |
@@ -281,6 +241,4 @@ Examples of basic usage:: | |||
| 281 | 241 | equidistributed uniform pseudorandom number generator", ACM Transactions on | |
| 282 | 242 | Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998. | |
| 283 | 243 | ||
| 284 | - Wichmann, B. A. & Hill, I. D., "Algorithm AS 183: An efficient and portable | ||
| 285 | - pseudo-random number generator", Applied Statistics 31 (1982) 188-190. | ||
| 286 | 244 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,9 +30,6 @@ | |||
| 30 | 30 | ||
| 31 | 31 | * The period is 2**19937-1. | |
| 32 | 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 | 33 | * The random() method is implemented in C, executes in a single Python step, | |
| 37 | 34 | and is, therefore, threadsafe. | |
| 38 | 35 | ||
@@ -49,7 +46,7 @@ | |||
| 49 | 46 | "randrange","shuffle","normalvariate","lognormvariate", | |
| 50 | 47 | "expovariate","vonmisesvariate","gammavariate", | |
| 51 | 48 | "gauss","betavariate","paretovariate","weibullvariate", | |
| 52 | - "getstate","setstate","jumpahead", "WichmannHill", "getrandbits", | ||
| 49 | + "getstate","setstate", "getrandbits", | ||
| 53 | 50 | "SystemRandom"] | |
| 54 | 51 | ||
| 55 | 52 | NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0) | |
@@ -70,14 +67,11 @@ class Random(_random.Random): | |||
| 70 | 67 | """Random number generator base class used by bound module functions. | |
| 71 | 68 | ||
| 72 | 69 | 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. | ||
| 70 | + share state. | ||
| 77 | 71 | ||
| 78 | 72 | Class Random can also be subclassed if you want to use a different basic | |
| 79 | 73 | generator of your own devising: in that case, override the following | |
| 80 | - methods: random(), seed(), getstate(), setstate() and jumpahead(). | ||
| 74 | + methods: random(), seed(), getstate(), and setstate(). | ||
| 81 | 75 | Optionally, implement a getrandombits() method so that randrange() | |
| 82 | 76 | can cover arbitrarily large ranges. | |
| 83 | 77 | ||
@@ -615,156 +609,6 @@ def weibullvariate(self, alpha, beta): | |||
| 615 | 609 | u = 1.0 - self.random() | |
| 616 | 610 | return alpha * pow(-_log(u), 1.0/beta) | |
| 617 | 611 | ||
| 618 | - ## -------------------- Wichmann-Hill ------------------- | ||
| 619 | - | ||
| 620 | - class WichmannHill(Random): | ||
| 621 | - | ||
| 622 | - VERSION = 1 # used by getstate/setstate | ||
| 623 | - | ||
| 624 | - def seed(self, a=None): | ||
| 625 | - """Initialize internal state from hashable object. | ||
| 626 | - | ||
| 627 | - None or no argument seeds from current time or from an operating | ||
| 628 | - system specific randomness source if available. | ||
| 629 | - | ||
| 630 | - If a is not None or an int or long, hash(a) is used instead. | ||
| 631 | - | ||
| 632 | - If a is an int or long, a is used directly. Distinct values between | ||
| 633 | - 0 and 27814431486575L inclusive are guaranteed to yield distinct | ||
| 634 | - internal states (this guarantee is specific to the default | ||
| 635 | - Wichmann-Hill generator). | ||
| 636 | - """ | ||
| 637 | - | ||
| 638 | - if a is None: | ||
| 639 | - try: | ||
| 640 | - a = int(_hexlify(_urandom(16)), 16) | ||
| 641 | - except NotImplementedError: | ||
| 642 | - import time | ||
| 643 | - a = int(time.time() * 256) # use fractional seconds | ||
| 644 | - | ||
| 645 | - if not isinstance(a, int): | ||
| 646 | - a = hash(a) | ||
| 647 | - | ||
| 648 | - a, x = divmod(a, 30268) | ||
| 649 | - a, y = divmod(a, 30306) | ||
| 650 | - a, z = divmod(a, 30322) | ||
| 651 | - self._seed = int(x)+1, int(y)+1, int(z)+1 | ||
| 652 | - | ||
| 653 | - self.gauss_next = None | ||
| 654 | - | ||
| 655 | - def random(self): | ||
| 656 | - """Get the next random number in the range [0.0, 1.0).""" | ||
| 657 | - | ||
| 658 | - # Wichman-Hill random number generator. | ||
| 659 | - # | ||
| 660 | - # Wichmann, B. A. & Hill, I. D. (1982) | ||
| 661 | - # Algorithm AS 183: | ||
| 662 | - # An efficient and portable pseudo-random number generator | ||
| 663 | - # Applied Statistics 31 (1982) 188-190 | ||
| 664 | - # | ||
| 665 | - # see also: | ||
| 666 | - # Correction to Algorithm AS 183 | ||
| 667 | - # Applied Statistics 33 (1984) 123 | ||
| 668 | - # | ||
| 669 | - # McLeod, A. I. (1985) | ||
| 670 | - # A remark on Algorithm AS 183 | ||
| 671 | - # Applied Statistics 34 (1985),198-200 | ||
| 672 | - | ||
| 673 | - # This part is thread-unsafe: | ||
| 674 | - # BEGIN CRITICAL SECTION | ||
| 675 | - x, y, z = self._seed | ||
| 676 | - x = (171 * x) % 30269 | ||
| 677 | - y = (172 * y) % 30307 | ||
| 678 | - z = (170 * z) % 30323 | ||
| 679 | - self._seed = x, y, z | ||
| 680 | - # END CRITICAL SECTION | ||
| 681 | - | ||
| 682 | - # Note: on a platform using IEEE-754 double arithmetic, this can | ||
| 683 | - # never return 0.0 (asserted by Tim; proof too long for a comment). | ||
| 684 | - return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0 | ||
| 685 | - | ||
| 686 | - def getstate(self): | ||
| 687 | - """Return internal state; can be passed to setstate() later.""" | ||
| 688 | - return self.VERSION, self._seed, self.gauss_next | ||
| 689 | - | ||
| 690 | - def setstate(self, state): | ||
| 691 | - """Restore internal state from object returned by getstate().""" | ||
| 692 | - version = state[0] | ||
| 693 | - if version == 1: | ||
| 694 | - version, self._seed, self.gauss_next = state | ||
| 695 | - else: | ||
| 696 | - raise ValueError("state with version %s passed to " | ||
| 697 | - "Random.setstate() of version %s" % | ||
| 698 | - (version, self.VERSION)) | ||
| 699 | - | ||
| 700 | - def jumpahead(self, n): | ||
| 701 | - """Act as if n calls to random() were made, but quickly. | ||
| 702 | - | ||
| 703 | - n is an int, greater than or equal to 0. | ||
| 704 | - | ||
| 705 | - Example use: If you have 2 threads and know that each will | ||
| 706 | - consume no more than a million random numbers, create two Random | ||
| 707 | - objects r1 and r2, then do | ||
| 708 | - r2.setstate(r1.getstate()) | ||
| 709 | - r2.jumpahead(1000000) | ||
| 710 | - Then r1 and r2 will use guaranteed-disjoint segments of the full | ||
| 711 | - period. | ||
| 712 | - """ | ||
| 713 | - | ||
| 714 | - if not n >= 0: | ||
| 715 | - raise ValueError("n must be >= 0") | ||
| 716 | - x, y, z = self._seed | ||
| 717 | - x = int(x * pow(171, n, 30269)) % 30269 | ||
| 718 | - y = int(y * pow(172, n, 30307)) % 30307 | ||
| 719 | - z = int(z * pow(170, n, 30323)) % 30323 | ||
| 720 | - self._seed = x, y, z | ||
| 721 | - | ||
| 722 | - def __whseed(self, x=0, y=0, z=0): | ||
| 723 | - """Set the Wichmann-Hill seed from (x, y, z). | ||
| 724 | - | ||
| 725 | - These must be integers in the range [0, 256). | ||
| 726 | - """ | ||
| 727 | - | ||
| 728 | - if not type(x) == type(y) == type(z) == int: | ||
| 729 | - raise TypeError('seeds must be integers') | ||
| 730 | - if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256): | ||
| 731 | - raise ValueError('seeds must be in range(0, 256)') | ||
| 732 | - if 0 == x == y == z: | ||
| 733 | - # Initialize from current time | ||
| 734 | - import time | ||
| 735 | - t = int(time.time() * 256) | ||
| 736 | - t = int((t&0xffffff) ^ (t>>24)) | ||
| 737 | - t, x = divmod(t, 256) | ||
| 738 | - t, y = divmod(t, 256) | ||
| 739 | - t, z = divmod(t, 256) | ||
| 740 | - # Zero is a poor seed, so substitute 1 | ||
| 741 | - self._seed = (x or 1, y or 1, z or 1) | ||
| 742 | - | ||
| 743 | - self.gauss_next = None | ||
| 744 | - | ||
| 745 | - def whseed(self, a=None): | ||
| 746 | - """Seed from hashable object's hash code. | ||
| 747 | - | ||
| 748 | - None or no argument seeds from current time. It is not guaranteed | ||
| 749 | - that objects with distinct hash codes lead to distinct internal | ||
| 750 | - states. | ||
| 751 | - | ||
| 752 | - This is obsolete, provided for compatibility with the seed routine | ||
| 753 | - used prior to Python 2.1. Use the .seed() method instead. | ||
| 754 | - """ | ||
| 755 | - | ||
| 756 | - if a is None: | ||
| 757 | - self.__whseed() | ||
| 758 | - return | ||
| 759 | - a = hash(a) | ||
| 760 | - a, x = divmod(a, 256) | ||
| 761 | - a, y = divmod(a, 256) | ||
| 762 | - a, z = divmod(a, 256) | ||
| 763 | - x = (x + a) % 256 or 1 | ||
| 764 | - y = (y + a) % 256 or 1 | ||
| 765 | - z = (z + a) % 256 or 1 | ||
| 766 | - self.__whseed(x, y, z) | ||
| 767 | - | ||
| 768 | 612 | ## --------------- Operating System Random Source ------------------ | |
| 769 | 613 | ||
| 770 | 614 | class SystemRandom(Random): | |
@@ -789,10 +633,9 @@ def getrandbits(self, k): | |||
| 789 | 633 | x = int(_hexlify(_urandom(bytes)), 16) | |
| 790 | 634 | return x >> (bytes * 8 - k) # trim excess bits | |
| 791 | 635 | ||
| 792 | - def _stub(self, *args, **kwds): | ||
| 636 | + def seed(self, *args, **kwds): | ||
| 793 | 637 | "Stub method. Not used for a system random number generator." | |
| 794 | 638 | return None | |
| 795 | - seed = jumpahead = _stub | ||
| 796 | 639 | ||
| 797 | 640 | def _notimplemented(self, *args, **kwds): | |
| 798 | 641 | "Method should not be called for a system random number generator." | |
@@ -866,7 +709,6 @@ def _test(N=2000): | |||
| 866 | 709 | weibullvariate = _inst.weibullvariate | |
| 867 | 710 | getstate = _inst.getstate | |
| 868 | 711 | setstate = _inst.setstate | |
| 869 | - jumpahead = _inst.jumpahead | ||
| 870 | 712 | getrandbits = _inst.getrandbits | |
| 871 | 713 | ||
| 872 | 714 | if __name__ == '__main__': | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -444,7 +444,7 @@ | |||
| 444 | 444 | >>> roots = sets[:] | |
| 445 | 445 | ||
| 446 | 446 | >>> import random | |
| 447 | - >>> gen = random.WichmannHill(42) | ||
| 447 | + >>> gen = random.Random(42) | ||
| 448 | 448 | >>> while 1: | |
| 449 | 449 | ... for s in sets: | |
| 450 | 450 | ... print(" %s->%s" % (s, s.find()), end='') | |
@@ -458,29 +458,29 @@ | |||
| 458 | 458 | ... else: | |
| 459 | 459 | ... break | |
| 460 | 460 | A->A B->B C->C D->D E->E F->F G->G H->H I->I J->J K->K L->L M->M | |
| 461 | - merged D into G | ||
| 462 | - A->A B->B C->C D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M | ||
| 463 | - merged C into F | ||
| 464 | - A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M | ||
| 461 | + merged I into A | ||
| 462 | + A->A B->B C->C D->D E->E F->F G->G H->H I->A J->J K->K L->L M->M | ||
| 463 | + merged D into C | ||
| 464 | + A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->K L->L M->M | ||
| 465 | + merged K into H | ||
| 466 | + A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->H L->L M->M | ||
| 465 | 467 | merged L into A | |
| 466 | - A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->A M->M | ||
| 467 | - merged H into E | ||
| 468 | - A->A B->B C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M | ||
| 469 | - merged B into E | ||
| 470 | - A->A B->E C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M | ||
| 468 | + A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->H L->A M->M | ||
| 469 | + merged E into A | ||
| 470 | + A->A B->B C->C D->C E->A F->F G->G H->H I->A J->J K->H L->A M->M | ||
| 471 | + merged B into G | ||
| 472 | + A->A B->G C->C D->C E->A F->F G->G H->H I->A J->J K->H L->A M->M | ||
| 473 | + merged A into F | ||
| 474 | + A->F B->G C->C D->C E->F F->F G->G H->H I->F J->J K->H L->F M->M | ||
| 475 | + merged H into G | ||
| 476 | + A->F B->G C->C D->C E->F F->F G->G H->G I->F J->J K->G L->F M->M | ||
| 477 | + merged F into J | ||
| 478 | + A->J B->G C->C D->C E->J F->J G->G H->G I->J J->J K->G L->J M->M | ||
| 479 | + merged M into C | ||
| 480 | + A->J B->G C->C D->C E->J F->J G->G H->G I->J J->J K->G L->J M->C | ||
| 471 | 481 | merged J into G | |
| 472 | - A->A B->E C->F D->G E->E F->F G->G H->E I->I J->G K->K L->A M->M | ||
| 473 | - merged E into G | ||
| 474 | - A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->M | ||
| 475 | - merged M into G | ||
| 476 | - A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->G | ||
| 477 | - merged I into K | ||
| 478 | - A->A B->G C->F D->G E->G F->F G->G H->G I->K J->G K->K L->A M->G | ||
| 479 | - merged K into A | ||
| 480 | - A->A B->G C->F D->G E->G F->F G->G H->G I->A J->G K->A L->A M->G | ||
| 481 | - merged F into A | ||
| 482 | - A->A B->G C->A D->G E->G F->A G->G H->G I->A J->G K->A L->A M->G | ||
| 483 | - merged A into G | ||
| 482 | + A->G B->G C->C D->C E->G F->G G->G H->G I->G J->G K->G L->G M->C | ||
| 483 | + merged C into G | ||
| 484 | 484 | A->G B->G C->G D->G E->G F->G G->G H->G I->G J->G K->G L->G M->G | |
| 485 | 485 | ||
| 486 | 486 | """ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments