diff options
Diffstat (limited to 'lib/utils')
| -rw-r--r-- | lib/utils/geometry.py | 2 | ||||
| -rw-r--r-- | lib/utils/prng.py | 44 |
2 files changed, 45 insertions, 1 deletions
diff --git a/lib/utils/geometry.py b/lib/utils/geometry.py index 98f40709..0ca13d8f 100644 --- a/lib/utils/geometry.py +++ b/lib/utils/geometry.py @@ -148,7 +148,7 @@ def cut_path(points, length): class Point: - def __init__(self, x, y): + def __init__(self, x: float, y: float): self.x = x self.y = y diff --git a/lib/utils/prng.py b/lib/utils/prng.py new file mode 100644 index 00000000..518049cb --- /dev/null +++ b/lib/utils/prng.py @@ -0,0 +1,44 @@ +from hashlib import blake2s +from math import ceil +from itertools import count, chain +import numpy as np + + +def joinArgs(*args): + # Stringifies parameters into a slash-separated string for use in hash keys. + # Idempotent and associative. + return "/".join([str(x) for x in args]) + + +MAX_UNIFORM_INT = 2 ** 32 - 1 + + +def uniformInts(*args): + # Single pseudo-random drawing determined by the joined parameters. + # Returns 4 uniformly random uint64. + s = joinArgs(*args) + h = blake2s(s.encode()).hexdigest() + nums = [] + for i in range(0, 64, 8): + nums.append(int(h[i:i+8], 16)) + return np.array(nums) + + +def uniformFloats(*args): + # returns an array of 8 floats in the range [0,1] + return uniformInts(*args) / MAX_UNIFORM_INT + + +def nUniformFloats(n: int, *args): + # returns a fixed number (which may exceed 8) of floats in the range [0,1] + seed = joinArgs(*args) + nBlocks = ceil(n/8) + blocks = [uniformFloats(seed, x) for x in range(nBlocks)] + return np.concatenate(blocks)[0:n] + + +def iterUniformFloats(*args): + # returns an infinite sequence of floats in the range [0,1] + seed = joinArgs(*args) + blocks = map(lambda x: list(uniformFloats(seed, x)), count(0)) + return chain.from_iterable(blocks) |
