/
stdrandom.py
120 lines (98 loc) · 3.14 KB
/
stdrandom.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
"""
stdrandom.py
The stdrandom module defines functions related to pseudo-random
numbers.
"""
#-----------------------------------------------------------------------
import random
import math
#-----------------------------------------------------------------------
def uniformInt(lo, hi):
"""
Return an integer uniformly in ['lo', 'hi'), where 'lo' and 'hi'
are integers.
"""
# Or instead call random.randrange(lo, hi) directly.
return random.randrange(lo, hi)
#-----------------------------------------------------------------------
def uniformFloat(lo, hi):
"""
Return a float uniformly in ['lo', 'hi'), where 'lo' and 'hi'
are floats.
"""
# Or instead call random.uniform(lo, hi) directly.
return random.uniform(lo, hi)
#-----------------------------------------------------------------------
def bernoulli(p):
"""
Return True with probability 'p'.
"""
# Or instead call scipy.stats.bernoulli().
return random.random() < p
#-----------------------------------------------------------------------
def gaussian(mean=0.0, stddev=1.0):
"""
Return a float according to a standard Gaussian distribution
with the given mean ('mean') and standard deviation ('stddev').
"""
# Or instead call random.gauss(mu, sigma).
# Use the polar form of the Box-Muller transform.
x = uniformFloat(-1.0, 1.0)
y = uniformFloat(-1.0, 1.0)
r = x*x + y*y
while (r >= 1) or (r == 0):
x = uniformFloat(-1.0, 1.0)
y = uniformFloat(-1.0, 1.0)
r = x*x + y*y
g = x * math.sqrt(-2 * math.log(r) / r)
# Remark: x * math.sqrt(-2 * math.log(r) / r)
# is an independent random gaussian
return mean + stddev * g
#-----------------------------------------------------------------------
def discrete(a):
"""
Return a float from a discrete distribution: i with probability
a[i]. Precondition: the elements of array 'a' sum to 1.
"""
r = uniformFloat(0.0, 1.0)
sum = 0.0
for i in range(len(a)):
sum += a[i]
if sum > r:
return i
return len(a) -1
#-----------------------------------------------------------------------
def shuffle(a):
"""
Shuffle array 'a'.
"""
# Or instead call random.shuffle(a) directly.
random.shuffle(a)
#-----------------------------------------------------------------------
def exp(lambd):
"""
Return a float from an exponential distribution with rate 'lambd'.
"""
# Or instead call random.expovariate(lambd)
return -math.log(1 - random.random()) / lambd
#-----------------------------------------------------------------------
def main(argv):
"""
For testing:
"""
import stdio
N = int(argv[1])
t = [.5, .3, .1, .1]
for i in range(N):
stdio.writef(' %2d ' , uniformInt(-100, 100))
stdio.writef('%8.5f ', uniformFloat(10.0, 99.0))
if bernoulli(.5):
stdio.write('False ')
else:
stdio.write('True ')
stdio.writef('%7.5f ', gaussian(9.0, .2))
stdio.writef('%2d ' , discrete(t))
stdio.writeln()
if __name__ == '__main__':
import sys
main(sys.argv)