RandomParkMiller.st
author Claus Gittinger <cg@exept.de>
Wed, 15 Feb 2017 21:45:55 +0100
changeset 4324 c3d7f79e34b0
parent 3420 f9d2226dbde2
child 4592 1f7298074f35
permissions -rw-r--r--
#DOCUMENTATION by cg class: RandomKISS comment/format in: #documentation
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
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     3
Object subclass:#RandomParkMiller
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     4
	instanceVariableNames:'seed'
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     5
	classVariableNames:'PMa PMm PMmu1 PMq PMr'
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     6
	poolDictionaries:''
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     7
	category:'Magnitude-Numbers'
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     8
!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     9
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    10
!RandomParkMiller class methodsFor:'documentation'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    11
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    12
documentation
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    13
"
3354
fafc1522a85b comment/format in: #documentation
Claus Gittinger <cg@exept.de>
parents: 3349
diff changeset
    14
    Warning: this generator should not be used for cryptographic work.
fafc1522a85b comment/format in: #documentation
Claus Gittinger <cg@exept.de>
parents: 3349
diff changeset
    15
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    16
    NO WARRANTY
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    17
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    18
    Another pseudo-random number generator
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    19
2427
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    20
    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
    21
    when a high quality random is required (for example, for cryptographic work). 
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    22
    Applications should use either the OS-random generator or a LaggedFibonacci generator.
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    23
    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
    24
    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
    25
    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
    26
    22 bits is undefined. 
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    27
    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
    28
    and bit 22 of the mantissa is always 1.
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
    29
998
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    30
    Please read:
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    31
        Standard reference by Park and Miller in 
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    32
            'Random Number Generators: Good Ones Are Hard to Find',
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    33
        Comm. ACM, 31:1192-1201, 1988.
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    34
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    35
    [see also:]
3395
520eb553e9e6 documentation link
Claus Gittinger <cg@exept.de>
parents: 3388
diff changeset
    36
        http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf
3401
2e1f3c5748a5 documentation link
Claus Gittinger <cg@exept.de>
parents: 3395
diff changeset
    37
        RandomGenerator - the default; uses the machine's /dev/random if available
998
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    38
        Random  - fast, but generates less quality random numbers
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    39
        RandomTT800 - another random generator
3395
520eb553e9e6 documentation link
Claus Gittinger <cg@exept.de>
parents: 3388
diff changeset
    40
        RandomMT19937 - a better random generator
520eb553e9e6 documentation link
Claus Gittinger <cg@exept.de>
parents: 3388
diff changeset
    41
        RandomKISS - fast and better random generator
998
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    42
"
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    43
!
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    44
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    45
testing
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    46
"
5f66a2dd6b7d documentation
Claus Gittinger <cg@exept.de>
parents: 977
diff changeset
    47
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    48
    |r|
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    49
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    50
    r := self new.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    51
    (1 to:10) collect:[:i | r next]
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    52
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    53
    -> should be
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    54
        #(
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    55
            0.1492432697 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    56
            0.3316330217 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    57
            0.7561964480 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    58
            0.3937015400 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    59
            0.9417831814 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    60
            0.5499291939 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    61
            0.6599625962 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    62
            0.9913545591 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    63
            0.6960744326 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    64
            0.9229878997
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    65
        #)
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    66
"
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
!RandomParkMiller class methodsFor:'initialization'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    70
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    71
initialize
2073
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
    72
    PMa := 16807.         " magic constant "
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
    73
    PMm := 2147483647.    " magic constant "
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
    74
    PMq := 127773.        " quotient (m quo: a) = 44488 "
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
    75
    PMr := 2836.          " remainder (m \\ a). = 2836 "
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
    76
    PMmu1 := 4.65661E-10  
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    77
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    78
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    79
!RandomParkMiller class methodsFor:'instance creation'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    80
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    81
new
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    82
    self initialize.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    83
    ^ super new initialize
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    84
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    85
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    86
!RandomParkMiller methodsFor:'accessing-reading'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    87
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    88
next
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    89
    " 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
    90
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    91
    seed := self nextInteger.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    92
    ^ seed * PMmu1
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    93
!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    94
3338
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    95
nextBoolean
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    96
    " This method generates a boolean "
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    97
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
    98
    ^ self next > 0.5
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
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   101
nextInteger
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   102
    " This method generates random instances of Integer in the interval 0 to 16r7FFFFFFF. "
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   103
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   104
    seed := self peekInteger.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   105
    ^ seed
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   106
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   107
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   108
!RandomParkMiller methodsFor:'initialization'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   109
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   110
initialize
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   111
    " Set a reasonable Park-Miller starting seed "
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   112
3388
379593c9d8ae better seeding
Claus Gittinger <cg@exept.de>
parents: 3354
diff changeset
   113
    seed := (Random randomSeed bitAnd:16rFFFFFFFF) "/ 2345678901
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   114
!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   115
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   116
seed:anInteger 
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   117
    seed := anInteger
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   118
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   119
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   120
!RandomParkMiller methodsFor:'private'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   121
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   122
peek
2073
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
   123
    " 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
   124
      It answers the same value for all successive message sends. "
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   125
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   126
    ^ self peekInteger * PMmu1
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   127
!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   128
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   129
peekInteger
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   130
    " 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
   131
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   132
    |lo hi aLoRHi answer|
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   133
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   134
    hi := seed quo:PMq.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   135
    lo := seed rem:PMq.
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   136
    aLoRHi := (PMa * lo) - (PMr * hi).
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   137
    (aLoRHi > 0) ifTrue:[ ^ aLoRHi ].
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   138
    ^ aLoRHi + PMm
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   139
! !
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   140
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   141
!RandomParkMiller class methodsFor:'documentation'!
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   142
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   143
version
3420
f9d2226dbde2 comments
Claus Gittinger <cg@exept.de>
parents: 3401
diff changeset
   144
    ^ '$Header: /cvs/stx/stx/libbasic2/RandomParkMiller.st,v 1.11 2014-10-02 16:23:25 cg Exp $'
2427
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
   145
!
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
   146
ea26fd4ce3f2 changed: #documentation
Claus Gittinger <cg@exept.de>
parents: 2073
diff changeset
   147
version_CVS
3420
f9d2226dbde2 comments
Claus Gittinger <cg@exept.de>
parents: 3401
diff changeset
   148
    ^ '$Header: /cvs/stx/stx/libbasic2/RandomParkMiller.st,v 1.11 2014-10-02 16:23:25 cg Exp $'
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   149
! !
2073
7cb0248742e3 comments
Claus Gittinger <cg@exept.de>
parents: 998
diff changeset
   150
3338
4c5ab3702414 class: RandomParkMiller
Claus Gittinger <cg@exept.de>
parents: 2427
diff changeset
   151
977
a7e2a422bfdb initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   152
RandomParkMiller initialize!