Created
August 30, 2021 09:25
-
-
Save demotomohiro/9516fe686da376bbce8a4470e52752ab to your computer and use it in GitHub Desktop.
## Visualize how Pseudo-random number generators created with jump function and with random seed use PRNG state space.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Visualize how Pseudo-random number generators created | |
## with jump function and with random seed use PRNG state space. | |
## Install pixie with `nimble install pixie` | |
import std/[strformat, random] | |
import pixie | |
const | |
numRows = 32 | |
numColumns = 64 | |
numStates = numRows * numColumns | |
numRandGen = 4 | |
numRand = numStates div numRandGen | |
stateWh = vec2(8, 8) | |
stateMargin = vec2(4, 4) | |
vertMargin = (stateWh.y + stateMargin.y) * (numRows + 2) | |
initPos = stateWh | |
let image = newImage(initPos.x.int + (stateWh.x + stateMargin.x).int * numColumns, vertMargin.int * 2) | |
image.fill(rgba(255, 255, 255, 255)) | |
let ctx = newContext(image) | |
ctx.fillStyle = rgba(64, 64, 255, 255) | |
ctx.strokeStyle.color = rgba(128, 0, 0, 255) | |
var pos = initPos | |
for i in 0 ..< numRows: | |
for j in 0 ..< numColumns: | |
ctx.fillRect(rect(pos, stateWh)) | |
ctx.fillRect(rect(pos + vec2(0, vertMargin), stateWh)) | |
pos.x += stateWh.x + stateMargin.x | |
pos.x = initPos.x | |
pos.y += (stateWh.y + stateMargin.y) | |
proc drawPRNG(stateId: int; isBottom = false) = | |
proc drawPRNGImpl(ip: IVec2; isBottom: bool) {.inline.} = | |
let | |
fp = vec2(ip) | |
p = fp * (stateWh + stateMargin) + vec2(0, if isBottom: vertMargin else: 0) | |
rct = rect(initPos + p - (stateMargin * 0.5), (stateWh + stateMargin) * vec2(numRandGen, 1)) | |
ctx.fillRoundedRect(rct, stateMargin.x) | |
ctx.strokeRoundedRect(rct, stateMargin.x) | |
let ip = ivec2(int32(stateId mod numColumns), int32(stateId div numColumns)) | |
drawPRNGImpl(ip, isBottom) | |
if ip.x + numRandGen > numColumns: | |
drawPRNGImpl(ivec2(((ip.x + numRandGen) mod numColumns) - numRandGen, ((ip.y + 1) mod numRows)), isBottom) | |
ctx.fillStyle = rgba(255, 0, 0, 64) | |
pos = initPos | |
randomize() | |
for i in 0 ..< (numRand div 4): | |
drawPRNG(i * numRandGen) | |
let r = rand(numStates - 1) | |
drawPRNG(r.int, true) | |
image.writeFile(&"prng{i:03}.png") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Each blue box represents a pseudo random number generater(PRNG) state.
Red rounded box represents PRNG that generates 4 random numbers by updating state 4 times.
Upper block represents how PRNGs created with jump function uses PRNG states.
Lower block represents how PRNGs created with random seed uses PRNG states.
In lower block, several PRNGs uses same states.
That means a part of random number output sequence from one PRNG matchs a part of random number output sequence from other PRNG.
This animation gif was created from output png files with following command:
It seems uploading mp4 or mov files to gist comment doesn't work.