Getting started

Install

PureRNGs requires Julia 1.10 or later.

using Pkg
Pkg.add("PureRNGs")

Load Random for Julia's standard sampling function names.

Continue a stream

using PureRNGs, Random

rng = Philox4x32(123456)
x, rng = rand_next(rng, Float64)
values, rng = rand_next(rng, Float32, 4)
normal, rng = randn_next(rng, Float32)
exponential, rng = randexp_next(rng, Float32)
values
4-element Vector{Float32}:
 0.06056696
 0.451621
 0.79959416
 0.30984718

The _next functions return (result, next_rng). Assign the returned generator before the next draw.

Without a result type, these continuation functions default to Float64. Thus, rand_next(rng, 4) draws four values.

Keep a snapshot

An immutable generator remains a valid snapshot after a draw. Reusing it repeats the same stream:

snapshot = rng
a, rng = rand_next(snapshot, Float64, 4)
b, replay = rand_next(snapshot, Float64, 4)
@assert a == b
@assert rng == replay

rand, randn, randexp, and their fills require a mutable RNG. Use StatefulRNG for existing Julia code, or the !! adapters for code that accepts either kind of generator.

Choose a result type

Uniform draws support Bool, every signed and unsigned integer type from 8 to 128 bits, Float16, Float32, Float64, and Complex values of the float types. Integer draws cover the entire type. Uniform floating-point draws lie in [0, 1).

Normal draws support Float16, Float32, Float64, and their Complex types. Exponential draws support the three float types. The 128-bit integers run on the CPU only.

bits, rng = rand_next(rng, Bool, 8)
integers, rng = rand_next(rng, Int32, 4)
dice, rng = rand_next(rng, 1:6, 8)
dice
8-element Vector{Int64}:
 4
 3
 2
 4
 4
 4
 2
 6

For existing code that expects a mutable AbstractRNG, use Random interoperability.