Category:Jq/MRG32k3a.jq

From Rosetta Code
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.