Sanctioned, purely-functional seeded PRNG.
Randomness in a model MUST come from a generator carried inside
model_state so that (a) two LPs never share a PRNG, coupling their
determinism to scheduling, and (b) rollback restores the PRNG position along
with the rest of the state snapshot — for free, via structural sharing.
This wraps Erlang's :rand in its explicit-state form (*_s), so there is no
hidden per-process seed and nothing to reset on rollback. Never call :rand
directly in a model — always thread a %TimeWarp.Rand{} through the state.
Summary
Functions
Exponentially-distributed value with the given mean, rounded to a positive
integer (virtual-time durations). Draws service times, travel durations and
inter-arrival gaps.
Seed a fresh generator deterministically from an integer.
Uniform float in [0.0, 1.0), plus the advanced generator.
Uniform integer in the inclusive range lo..hi, plus the advanced generator.
Types
@type t() :: %TimeWarp.Rand{state: :rand.state()}
Functions
@spec exponential(t(), number()) :: {pos_integer(), t()}
Exponentially-distributed value with the given mean, rounded to a positive
integer (virtual-time durations). Draws service times, travel durations and
inter-arrival gaps.
Seed a fresh generator deterministically from an integer.
Uniform float in [0.0, 1.0), plus the advanced generator.
Uniform integer in the inclusive range lo..hi, plus the advanced generator.