v2 / vlib / rand / wyrand / wyrand_test.v
317 lines · 292 sloc · 7.05 KB · 9f3f1291e8936cc90c7c1abe66a672ac1173d601
Raw
1import math
2import rand
3import rand.seed
4import rand.wyrand
5
6const range_limit = 40
7const value_count = 1000
8const seeds = [[u32(42), 0], [u32(256), 0]]
9
10const sample_size = 1000
11const stats_epsilon = 0.05
12const inv_sqrt_12 = 1.0 / math.sqrt(12)
13
14fn gen_randoms(seed_data []u32, bound int) []u64 {
15 bound_u64 := u64(bound)
16 mut randoms := []u64{len: (20)}
17 mut rnd := &rand.PRNG(&wyrand.WyRandRNG{})
18 rnd.seed(seed_data)
19 for i in 0 .. 20 {
20 randoms[i] = rnd.u64n(bound_u64) or { panic("Couldn't obtain u64") }
21 }
22 return randoms
23}
24
25fn test_wyrand_reproducibility() {
26 seed_data := seed.time_seed_array(2)
27 randoms1 := gen_randoms(seed_data, 1000)
28 randoms2 := gen_randoms(seed_data, 1000)
29 assert randoms1.len == randoms2.len
30 len := randoms1.len
31 for i in 0 .. len {
32 assert randoms1[i] == randoms2[i]
33 }
34}
35
36fn test_wyrand_variability() {
37 // If this test fails and if it is certainly not the implementation
38 // at fault, try changing the seed values. Repeated values are
39 // improbable but not impossible.
40 for seed in seeds {
41 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
42 rng.seed(seed)
43 mut values := []u64{cap: value_count}
44 for i in 0 .. value_count {
45 value := rng.u64()
46 assert value !in values
47 assert values.len == i
48 values << value
49 }
50 }
51}
52
53fn check_uniformity_u64(mut rng rand.PRNG, range u64) {
54 range_f64 := f64(range)
55 expected_mean := range_f64 / 2.0
56 mut variance := 0.0
57 for _ in 0 .. sample_size {
58 diff := f64(rng.u64n(range) or { panic("Couldn't obtain u64") }) - expected_mean
59 variance += diff * diff
60 }
61 variance /= sample_size - 1
62 sigma := math.sqrt(variance)
63 expected_sigma := range_f64 * inv_sqrt_12
64 error := (sigma - expected_sigma) / expected_sigma
65 assert math.abs(error) < stats_epsilon
66}
67
68fn test_wyrand_uniformity_u64() {
69 ranges := [14019545, 80240, 130]
70 for seed in seeds {
71 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
72 rng.seed(seed)
73 for range in ranges {
74 check_uniformity_u64(mut rng, u64(range))
75 }
76 }
77}
78
79fn check_uniformity_f64(mut rng rand.PRNG) {
80 expected_mean := 0.5
81 mut variance := 0.0
82 for _ in 0 .. sample_size {
83 diff := rng.f64() - expected_mean
84 variance += diff * diff
85 }
86 variance /= sample_size - 1
87 sigma := math.sqrt(variance)
88 expected_sigma := inv_sqrt_12
89 error := (sigma - expected_sigma) / expected_sigma
90 assert math.abs(error) < stats_epsilon
91}
92
93fn test_wyrand_uniformity_f64() {
94 // The f64 version
95 for seed in seeds {
96 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
97 rng.seed(seed)
98 check_uniformity_f64(mut rng)
99 }
100}
101
102fn test_wyrand_u32n() {
103 max := u32(16384)
104 for seed in seeds {
105 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
106 rng.seed(seed)
107 for _ in 0 .. range_limit {
108 value := rng.u32n(max) or { panic("Couldn't obtain u32") }
109 assert value >= 0
110 assert value < max
111 }
112 }
113}
114
115fn test_wyrand_u64n() {
116 max := u64(379091181005)
117 for seed in seeds {
118 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
119 rng.seed(seed)
120 for _ in 0 .. range_limit {
121 value := rng.u64n(max) or { panic("Couldn't obtain u64") }
122 assert value >= 0
123 assert value < max
124 }
125 }
126}
127
128fn test_wyrand_u32_in_range() {
129 max := u32(484468466)
130 min := u32(316846)
131 for seed in seeds {
132 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
133 rng.seed(seed)
134 for _ in 0 .. range_limit {
135 value := rng.u32_in_range(min, max) or { panic("Couldn't obtain u32 in range") }
136 assert value >= min
137 assert value < max
138 }
139 }
140}
141
142fn test_wyrand_u64_in_range() {
143 max := u64(216468454685163)
144 min := u64(6848646868)
145 for seed in seeds {
146 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
147 rng.seed(seed)
148 for _ in 0 .. range_limit {
149 value := rng.u64_in_range(min, max) or { panic("Couldn't obtain u64 in range") }
150 assert value >= min
151 assert value < max
152 }
153 }
154}
155
156fn test_wyrand_int31() {
157 max_u31 := int(0x7FFFFFFF)
158 sign_mask := int(u32(0x80000000))
159 for seed in seeds {
160 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
161 rng.seed(seed)
162 for _ in 0 .. range_limit {
163 value := rng.int31()
164 assert value >= 0
165 assert value <= max_u31
166 // This statement ensures that the sign bit is zero
167 assert (value & sign_mask) == 0
168 }
169 }
170}
171
172fn test_wyrand_int63() {
173 max_u63 := i64(0x7FFFFFFFFFFFFFFF)
174 sign_mask := i64(u64(0x8000000000000000))
175 for seed in seeds {
176 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
177 rng.seed(seed)
178 for _ in 0 .. range_limit {
179 value := rng.int63()
180 assert value >= 0
181 assert value <= max_u63
182 assert (value & sign_mask) == 0
183 }
184 }
185}
186
187fn test_wyrand_intn() {
188 max := 2525642
189 for seed in seeds {
190 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
191 rng.seed(seed)
192 for _ in 0 .. range_limit {
193 value := rng.intn(max) or { panic("Couldn't obtain int") }
194 assert value >= 0
195 assert value < max
196 }
197 }
198}
199
200fn test_wyrand_i64n() {
201 max := i64(3246727724653636)
202 for seed in seeds {
203 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
204 rng.seed(seed)
205 for _ in 0 .. range_limit {
206 value := rng.i64n(max) or { panic("Couldn't obtain i64") }
207 assert value >= 0
208 assert value < max
209 }
210 }
211}
212
213fn test_wyrand_int_in_range() {
214 min := -4252
215 max := 1034
216 for seed in seeds {
217 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
218 rng.seed(seed)
219 for _ in 0 .. range_limit {
220 value := rng.int_in_range(min, max) or { panic("Couldn't obtain int in range") }
221 assert value >= min
222 assert value < max
223 }
224 }
225}
226
227fn test_wyrand_i64_in_range() {
228 min := i64(-24095)
229 max := i64(324058)
230 for seed in seeds {
231 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
232 rng.seed(seed)
233 for _ in 0 .. range_limit {
234 value := rng.i64_in_range(min, max) or { panic("Couldn't obtain i64 in range") }
235 assert value >= min
236 assert value < max
237 }
238 }
239}
240
241fn test_wyrand_f32() {
242 for seed in seeds {
243 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
244 rng.seed(seed)
245 for _ in 0 .. range_limit {
246 value := rng.f32()
247 assert value >= 0.0
248 assert value < 1.0
249 }
250 }
251}
252
253fn test_wyrand_f64() {
254 for seed in seeds {
255 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
256 rng.seed(seed)
257 for _ in 0 .. range_limit {
258 value := rng.f64()
259 assert value >= 0.0
260 assert value < 1.0
261 }
262 }
263}
264
265fn test_wyrand_f32n() {
266 max := f32(357.0)
267 for seed in seeds {
268 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
269 rng.seed(seed)
270 for _ in 0 .. range_limit {
271 value := rng.f32n(max) or { panic("Couldn't obtain f32") }
272 assert value >= 0.0
273 assert value < max
274 }
275 }
276}
277
278fn test_wyrand_f64n() {
279 max := 1.52e6
280 for seed in seeds {
281 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
282 rng.seed(seed)
283 for _ in 0 .. range_limit {
284 value := rng.f64n(max) or { panic("Couldn't obtain f64") }
285 assert value >= 0.0
286 assert value < max
287 }
288 }
289}
290
291fn test_wyrand_f32_in_range() {
292 min := f32(-24.0)
293 max := f32(125.0)
294 for seed in seeds {
295 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
296 rng.seed(seed)
297 for _ in 0 .. range_limit {
298 value := rng.f32_in_range(min, max) or { panic("Couldn't obtain f32 in range") }
299 assert value >= min
300 assert value < max
301 }
302 }
303}
304
305fn test_wyrand_f64_in_range() {
306 min := -548.7
307 max := 5015.2
308 for seed in seeds {
309 mut rng := &rand.PRNG(&wyrand.WyRandRNG{})
310 rng.seed(seed)
311 for _ in 0 .. range_limit {
312 value := rng.f64_in_range(min, max) or { panic("Couldn't obtain f64 in range") }
313 assert value >= min
314 assert value < max
315 }
316 }
317}
318