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