Category:Jq/MRG32k3a.jq
module {
"name": "MRG32k3a",
"description": "MRG32k3a Combined Recursive Pseudo-Random Number Generator",
"version": "2024.06.16",
"homepage": "https://rosettacode.org/w/index.php?title=Category:Jq/MRG32k3a.jq",
"license": "MIT",
"author": "pkoppstein at gmail dot com",
"reference": "https://www.nag.com/numeric/fl/nagdoc_fl23/pdf/g05/g05intro.pdf"
};
# This jq module has been tested with the C and Go implementations of jq.
def A1: [0, 1403580, -810728];
def M1: 4294967087; # pow(2;32) - 209
def A2: [527612, 0, -1370589];
def M2: 4294944443; # pow(2;32) - 22853
def D: M1 + 1;
# Python-style modulus
def Mod($x; $y):
def abs: if . < 0 then - . else . end;
($x % $y) as $m
| if $m < 0 then $m + ($y|abs) else $m end;
# Initialize the PRNG
def seed($seedState):
{x1: [($seedState % D), 0, 0]} | .x2 = .x1;
# Input: {x1, x2} where .x1 and .x2 are numeric arrays as produced by seed/1 or nextInt/0
# Output: {x1, x2, nextInt}
def nextInt:
Mod(A1[0]*.x1[0] + A1[1]*.x1[1] + A1[2]*.x1[2]; M1) as $x1i
| Mod(A2[0]*.x2[0] + A2[1]*.x2[1] + A2[2]*.x2[2]; M2) as $x2i
| .x1 = [$x1i, .x1[0], .x1[1]] # keep last three
| .x2 = [$x2i, .x2[0], .x2[1]] # keep last three
| .nextInt = Mod($x1i - $x2i; M1) + 1 ;
def nextFloat: nextInt | .nextFloat = (.nextInt / D);
# Input/Output: {prng, array}
def knuthShuffle:
(.array|length) as $n
| if $n <= 1 then .
else .i = $n
| until(.i == 0;
.i += -1
| .prng |= nextFloat
| (.prng|.nextFloat * $n | trunc) as $j
| .array[.i] as $t
| .array[.i] = .array[$j]
| .array[$j] = $t)
end;
# A convenience function for emitting an array of $n PRN
# in range(0;.) using a seed based on `now`.
def prn($n):
. as $k
| reduce range(0;$n) as $i ({prng: (seed(now | tostring | sub("^.*[.]";"") | tonumber))};
.prng |= nextFloat
| .digits += [.prng.nextFloat * $k | trunc] )
| .digits;
This category currently contains no pages or media.