def random_standard_normal_f(bitgen): while 1: r = next_uint32(bitgen) idx = r & 0xff sign = (r >> 8) & 0x1 rabs = (r >> 9) & 0x0007fffff x = float32(float32(rabs) * wi_float[idx]) if (sign & 0x1): x = -x if (rabs < ki_float[idx]): return x if (idx == 0): while 1: xx = float32(-ziggurat_nor_inv_r_f * np_log1pf(-next_float(bitgen))) yy = float32(-np_log1pf(-next_float(bitgen))) if (float32(yy + yy) > float32(xx * xx)): if ((rabs >> 8) & 0x1): return -float32(ziggurat_nor_r_f + xx) else: return float32(ziggurat_nor_r_f + xx) else: if (((fi_float[idx - 1] - fi_float[idx]) * next_float(bitgen) + fi_float[idx]) < float32(np.exp(-float32(0.5) * x * x))): return x
def random_bounded_uint64_fill(bitgen, low, rng, size, dtype): """ Returns a new array of given size with 64 bit integers bounded by given interval. """ out = np.empty(size, dtype=dtype) if rng == 0: for i in np.ndindex(size): out[i] = low elif rng <= 0xFFFFFFFF: if (rng == 0xFFFFFFFF): for i in np.ndindex(size): out[i] = low + next_uint32(bitgen) else: for i in np.ndindex(size): out[i] = low + buffered_bounded_lemire_uint32(bitgen, rng) elif (rng == 0xFFFFFFFFFFFFFFFF): for i in np.ndindex(size): out[i] = low + next_uint64(bitgen) else: for i in np.ndindex(size): out[i] = low + bounded_lemire_uint64(bitgen, rng) return out
def buffered_uint16(bitgen, bcnt, buf): if not bcnt: buf = next_uint32(bitgen) bcnt = 1 else: buf >>= 16 bcnt -= 1 return uint16(buf), bcnt, buf
def buffered_uint8(bitgen, bcnt, buf): if not bcnt: buf = next_uint32(bitgen) bcnt = 3 else: buf >>= 8 bcnt -= 1 return uint8(buf), bcnt, buf
def buffered_bounded_bool(bitgen, off, rng, bcnt, buf): if (rng == 0): return off, bcnt, buf if not bcnt: buf = next_uint32(bitgen) bcnt = 31 else: buf >>= 1 bcnt -= 1 return ((buf & 1) != 0), bcnt, buf
def buffered_bounded_lemire_uint32(bitgen, rng): """ Generates a random unsigned 32 bit integer bounded within a given interval using Lemire's rejection. """ rng_excl = uint32(rng) + uint32(1) assert (rng != 0xFFFFFFFF) # Generate a scaled random number. m = uint64(next_uint32(bitgen)) * uint64(rng_excl) # Rejection sampling to remove any bias leftover = m & 0xFFFFFFFF if (leftover < rng_excl): # `rng_excl` is a simple upper bound for `threshold`. threshold = (UINT32_MAX - rng) % rng_excl while (leftover < threshold): m = uint64(next_uint32(bitgen)) * uint64(rng_excl) leftover = m & 0xFFFFFFFF return (m >> 32)
def random_standard_exponential_f(bitgen): while 1: ri = next_uint32(bitgen) ri >>= 1 idx = ri & 0xFF ri >>= 8 x = float32(float32(ri) * we_float[idx]) if (ri < ke_float[idx]): return x else: if (idx == 0): return float32(ziggurat_exp_r_f - float32(np_log1pf(-next_float(bitgen)))) elif ((fe_float[idx - 1] - fe_float[idx]) * next_float(bitgen) + fe_float[idx] < float32(np.exp(float32(-x)))): return x
def random_bounded_uint32_fill(bitgen, low, rng, size, dtype): """ Returns a new array of given size with 32 bit integers bounded by given interval. """ out = np.empty(size, dtype=dtype) if rng == 0: for i in np.ndindex(size): out[i] = low elif rng == 0xFFFFFFFF: # Lemire32 doesn't support rng = 0xFFFFFFFF. for i in np.ndindex(size): out[i] = low + next_uint32(bitgen) else: for i in np.ndindex(size): out[i] = low + buffered_bounded_lemire_uint32(bitgen, rng) return out