RandomParkMiller.st
author Claus Gittinger <cg@exept.de>
Tue, 25 Jun 2019 14:28:51 +0200
changeset 5050 44fa8672d102
parent 4592 1f7298074f35
child 5252 6248614509e9
permissions -rw-r--r--
#DOCUMENTATION by cg class: SharedQueue comment/format in: #next #nextWithTimeout:
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     1
"{ Package: 'stx:libbasic2' }"
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     2
4592
1f7298074f35 #OTHER by cg
Claus Gittinger <cg@exept.de>
parents: 3420
diff changeset
     3
"{ NameSpace: Smalltalk }"
1f7298074f35 #OTHER by cg
Claus Gittinger <cg@exept.de>
parents: 3420
diff changeset
     4
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     5
Object subclass:#RandomParkMiller
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     6
	instanceVariableNames:'seed'
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     7
	classVariableNames:'PMa PMm PMmu1 PMq PMr'
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     8
	poolDictionaries:''
4592
1f7298074f35 #OTHER by cg
Claus Gittinger <cg@exept.de>
parents: 3420
diff changeset
     9
	category:'Magnitude-Numbers-Random'
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    10
!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    11
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    12
!RandomParkMiller class methodsFor:'documentation'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    13
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    14
documentation
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    15
"
3354
fafc1522a85b comment/format in: #documentation
Claus Gittinger <cg@exept.de>
parents: 3349
diff changeset
    16
    Warning: this generator should not be used for cryptographic work.
fafc1522a85b comment/format in: #documentation
Claus Gittinger <cg@exept.de>
parents: 3349
diff changeset
    17
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    18
    NO WARRANTY
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    19
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    20
    Another pseudo-random number generator
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    21
2427
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    22
    The ParkMiller random generator (although better than the old Random), is not recommended 
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    23
    when a high quality random is required (for example, for cryptographic work). 
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    24
    Applications should use either the OS-random generator or a LaggedFibonacci generator.
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    25
    This is because the random values provided by the Park-Miller generator are double precision 
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    26
    floating point numbers which have up to 53 significant bits. Since only the first 31 bits 
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    27
    of their mantissa are known to have good random properties, the behavior of the remaining 
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    28
    22 bits is undefined. 
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    29
    In particular, bit aliasing occurs during the calculation of the next random value, 
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    30
    and bit 22 of the mantissa is always 1.
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    31
998
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    32
    Please read:
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    33
        Standard reference by Park and Miller in 
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    34
            'Random Number Generators: Good Ones Are Hard to Find',
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    35
        Comm. ACM, 31:1192-1201, 1988.
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    36
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    37
    [see also:]
3395
520eb553e9e6 documentation link
Claus Gittinger <cg@exept.de>
parents: 3388
diff changeset
    38
        http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf
3401
2e1f3c5748a5 documentation link
Claus Gittinger <cg@exept.de>
parents: 3395
diff changeset
    39
        RandomGenerator - the default; uses the machine's /dev/random if available
998
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    40
        Random  - fast, but generates less quality random numbers
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    41
        RandomTT800 - another random generator
3395
520eb553e9e6 documentation link
Claus Gittinger <cg@exept.de>
parents: 3388
diff changeset
    42
        RandomMT19937 - a better random generator
520eb553e9e6 documentation link
Claus Gittinger <cg@exept.de>
parents: 3388
diff changeset
    43
        RandomKISS - fast and better random generator
998
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    44
"
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    45
!
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    46
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    47
testing
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    48
"
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    49
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    50
    |r|
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    51
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    52
    r := self new.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    53
    (1 to:10) collect:[:i | r next]
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    54
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    55
    -> should be
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    56
        #(
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    57
            0.1492432697 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    58
            0.3316330217 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    59
            0.7561964480 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    60
            0.3937015400 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    61
            0.9417831814 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    62
            0.5499291939 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    63
            0.6599625962 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    64
            0.9913545591 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    65
            0.6960744326 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    66
            0.9229878997
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    67
        #)
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    68
"
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    69
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    70
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    71
!RandomParkMiller class methodsFor:'initialization'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    72
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    73
initialize
2073
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
    74
    PMa := 16807.         " magic constant "
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
    75
    PMm := 2147483647.    " magic constant "
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
    76
    PMq := 127773.        " quotient (m quo: a) = 44488 "
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
    77
    PMr := 2836.          " remainder (m \\ a). = 2836 "
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
    78
    PMmu1 := 4.65661E-10  
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    79
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    80
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    81
!RandomParkMiller class methodsFor:'instance creation'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    82
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    83
new
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    84
    self initialize.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    85
    ^ super new initialize
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    86
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    87
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    88
!RandomParkMiller methodsFor:'accessing-reading'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    89
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    90
next
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    91
    " This method generates random instances of Float in the interval 0.0 to 1.0 "
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    92
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    93
    seed := self nextInteger.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    94
    ^ seed * PMmu1
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    95
!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    96
3338
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    97
nextBoolean
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    98
    " This method generates a boolean "
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    99
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
   100
    ^ self next > 0.5
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
   101
!
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
   102
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   103
nextInteger
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   104
    " This method generates random instances of Integer in the interval 0 to 16r7FFFFFFF. "
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   105
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   106
    seed := self peekInteger.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   107
    ^ seed
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   108
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   109
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   110
!RandomParkMiller methodsFor:'initialization'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   111
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   112
initialize
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   113
    " Set a reasonable Park-Miller starting seed "
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   114
3388
379593c9d8ae better seeding
Claus Gittinger <cg@exept.de>
parents: 3354
diff changeset
   115
    seed := (Random randomSeed bitAnd:16rFFFFFFFF) "/ 2345678901
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   116
!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   117
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   118
seed:anInteger 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   119
    seed := anInteger
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   120
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   121
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   122
!RandomParkMiller methodsFor:'private'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   123
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   124
peek
2073
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
   125
    " This method answers the next random number that will be generated as a Float in the range [0..1). 
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
   126
      It answers the same value for all successive message sends. "
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   127
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   128
    ^ self peekInteger * PMmu1
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   129
!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   130
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   131
peekInteger
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   132
    " This method generates random instances of Integer in the interval 0 to 16r7FFFFFFF. This method does NOT update the seed; repeated sends answer the same value. The algorithm is described in detail in 'Random Number Generators: Good Ones Are Hard to Find' by Stephen K. Park and Keith W. Miller, (Comm. Asso. Comp. Mach., 31(10):1192--1201, 1988). "
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   133
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   134
    |lo hi aLoRHi answer|
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   135
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   136
    hi := seed quo:PMq.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   137
    lo := seed rem:PMq.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   138
    aLoRHi := (PMa * lo) - (PMr * hi).
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   139
    (aLoRHi > 0) ifTrue:[ ^ aLoRHi ].
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   140
    ^ aLoRHi + PMm
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   141
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   142
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   143
!RandomParkMiller class methodsFor:'documentation'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   144
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   145
version
4592
1f7298074f35 #OTHER by cg
Claus Gittinger <cg@exept.de>
parents: 3420
diff changeset
   146
    ^ '$Header$'
2427
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
   147
!
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
   148
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
   149
version_CVS
4592
1f7298074f35 #OTHER by cg
Claus Gittinger <cg@exept.de>
parents: 3420
diff changeset
   150
    ^ '$Header$'
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   151
! !
2073
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
   152
3338
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
   153
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   154
RandomParkMiller initialize!