This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

Notebooks · lib/nprandom/pcg64

NumPy's PCG64 in 16-bit limbs

np.random.default_rng(seed) is a Generator over PCG64: a 128-bit linear congruential state, state = state * MULT + inc mod 2^128, and a 64-bit output, the high and low halves of the new state XORed and rotated right by the state's top six bits (XSL-RR). This is NumPy 1.24.4's code (numpy/random/src/pcg64/pcg64.h and pcg64.c, numpy/random/_pcg64.pyx, uint64_to_double in _common.pxd; tag v1.24.4, commit 9315a9072b2636f75c831b4eca9f42a5f67ca2fb).

The state is an array of Ints: the 128-bit state and increment as their low and high 64-bit halves, the half of the last 64-bit output that next32 keeps for the next call (NumPy's has_uint32 and uinteger), the last output, and a seeded flag. The halves are bit patterns: wrap_mul, wrap_add and umulhi compute modulo 2^64 as NumPy's uint64_t does, and ult compares as unsigned.

  • npr_pcg_new(), npr_pcg_seed(st, words): the generator, and PCG64's constructor for the eight 32-bit words SeedSequence gives (generate_state(4, np.uint64)): state = (u64[0], u64[1]), inc = (u64[2], u64[3]), then pcg_setseq_128_srandom_r.
  • npr_pcg_next64(st): one step, and its 64-bit output (an Int holding the pattern), also kept at NPR_PCG_OUT.
  • npr_pcg_next32(st): the low half of a new output, then the high half.
  • npr_pcg_double(st): (next64 >> 11) / 2^53.

Used with import nprandom.pcg64.

Look inside this program

  • Atlas

    The program’s map: every function and which calls which.

  • There’s no recorded run of this program yet.

Shift+Enter in a cell runs it and moves to the next. Running a cell runs every cell above it too, as one program.

[1]lines 31–147