RandomParkMiller.st
author Claus Gittinger <cg@exept.de>
Sat, 02 May 2020 21:40:13 +0200
changeset 5476 7355a4b11cb6
parent 5252 6248614509e9
permissions -rw-r--r--
#FEATURE by cg class: Socket class added: #newTCPclientToHost:port:domain:domainOrder:withTimeout: changed: #newTCPclientToHost:port:domain:withTimeout:
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
3338
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    90
nextBoolean
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    91
    " This method generates a boolean "
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    92
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    93
    ^ self next > 0.5
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    94
!
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    95
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    96
nextInteger
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    97
    " This method generates random instances of Integer in the interval 0 to 16r7FFFFFFF. "
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    98
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    99
    seed := self peekInteger.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   100
    ^ seed
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   101
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   102
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   103
!RandomParkMiller methodsFor:'initialization'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   104
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   105
initialize
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   106
    " Set a reasonable Park-Miller starting seed "
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   107
3388
379593c9d8ae better seeding
Claus Gittinger <cg@exept.de>
parents: 3354
diff changeset
   108
    seed := (Random randomSeed bitAnd:16rFFFFFFFF) "/ 2345678901
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   109
!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   110
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   111
seed:anInteger 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   112
    seed := anInteger
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   113
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   114
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   115
!RandomParkMiller methodsFor:'private'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   116
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   117
peek
2073
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
   118
    " 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
   119
      It answers the same value for all successive message sends. "
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   120
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   121
    ^ self peekInteger * PMmu1
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   122
!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   123
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   124
peekInteger
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   125
    " 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
   126
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   127
    |lo hi aLoRHi answer|
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   128
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   129
    hi := seed quo:PMq.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   130
    lo := seed rem:PMq.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   131
    aLoRHi := (PMa * lo) - (PMr * hi).
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   132
    (aLoRHi > 0) ifTrue:[ ^ aLoRHi ].
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   133
    ^ aLoRHi + PMm
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   134
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   135
5252
6248614509e9 #DOCUMENTATION by cg
Claus Gittinger <cg@exept.de>
parents: 4592
diff changeset
   136
!RandomParkMiller methodsFor:'reading'!
6248614509e9 #DOCUMENTATION by cg
Claus Gittinger <cg@exept.de>
parents: 4592
diff changeset
   137
6248614509e9 #DOCUMENTATION by cg
Claus Gittinger <cg@exept.de>
parents: 4592
diff changeset
   138
next
6248614509e9 #DOCUMENTATION by cg
Claus Gittinger <cg@exept.de>
parents: 4592
diff changeset
   139
    " This method generates random instances of Float in the interval 0.0 to 1.0 "
6248614509e9 #DOCUMENTATION by cg
Claus Gittinger <cg@exept.de>
parents: 4592
diff changeset
   140
6248614509e9 #DOCUMENTATION by cg
Claus Gittinger <cg@exept.de>
parents: 4592
diff changeset
   141
    seed := self nextInteger.
6248614509e9 #DOCUMENTATION by cg
Claus Gittinger <cg@exept.de>
parents: 4592
diff changeset
   142
    ^ seed * PMmu1
6248614509e9 #DOCUMENTATION by cg
Claus Gittinger <cg@exept.de>
parents: 4592
diff changeset
   143
! !
6248614509e9 #DOCUMENTATION by cg
Claus Gittinger <cg@exept.de>
parents: 4592
diff changeset
   144
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   145
!RandomParkMiller class methodsFor:'documentation'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   146
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   147
version
4592
1f7298074f35 #OTHER by cg
Claus Gittinger <cg@exept.de>
parents: 3420
diff changeset
   148
    ^ '$Header$'
2427
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
   149
!
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
   150
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
   151
version_CVS
4592
1f7298074f35 #OTHER by cg
Claus Gittinger <cg@exept.de>
parents: 3420
diff changeset
   152
    ^ '$Header$'
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   153
! !
2073
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
   154
3338
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
   155
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   156
RandomParkMiller initialize!