Pseudo-random numbers/Combined recursive generator MRG32k3a: Difference between revisions

→‎{{header|jq}}: include "MRG32k3a"
(Corrected output.)
(→‎{{header|jq}}: include "MRG32k3a")
 
(19 intermediate revisions by 10 users not shown)
Line 73:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">V a1 = [Int64(0), 1403580, -810728]
V m1 = Int64(2) ^ 32 - 209
V a2 = [Int64(527612), 0, -1370589]
Line 112:
L 100'000
hist[Int(random_gen.next_float() * 5)]++
print(hist)</langsyntaxhighlight>
 
{{out}}
Line 125:
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">package MRG32KA is
type I64 is range -2**63..2**63 - 1;
m1 : constant I64 := 2**32 - 209;
Line 136:
function Next_Float return Long_Float;
end MRG32KA;
</syntaxhighlight>
</lang>
 
<syntaxhighlight lang="ada">
<lang Ada>
package body MRG32KA is
Line 192:
 
end MRG32KA;
</syntaxhighlight>
</lang>
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; use Ada.Text_IO;
with mrg32ka; use mrg32ka;
 
Line 219:
end Main;
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 232:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <math.h>
#include <stdio.h>
#include <stdint.h>
Line 317:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>1459213977
Line 333:
=={{header|C++}}==
{{trans|C}}
<langsyntaxhighlight lang="cpp">#include <array>
#include <iostream>
 
Line 407:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>1459213977
2827710106
4245671317
3877608661
2595287583
 
0: 20002
1: 20060
2: 19948
3: 20059
4: 19931</pre>
 
=={{header|D}}==
{{trans|C++}}
<syntaxhighlight lang="d">import std.math;
import std.stdio;
 
long mod(long x, long y) {
long m = x % y;
if (m < 0) {
if (y < 0) {
return m - y;
} else {
return m + y;
}
}
return m;
}
 
class RNG {
private:
// First generator
immutable(long []) a1 = [0, 1403580, -810728];
immutable long m1 = (1L << 32) - 209;
long[3] x1;
// Second generator
immutable(long []) a2 = [527612, 0, -1370589];
immutable long m2 = (1L << 32) - 22853;
long[3] x2;
// other
immutable long d = m1 + 1;
 
public:
void seed(long state) {
x1 = [state, 0, 0];
x2 = [state, 0, 0];
}
 
long next_int() {
long x1i = mod((a1[0] * x1[0] + a1[1] * x1[1] + a1[2] * x1[2]), m1);
long x2i = mod((a2[0] * x2[0] + a2[1] * x2[1] + a2[2] * x2[2]), m2);
long z = mod(x1i - x2i, m1);
 
// keep the last three values of the first generator
x1 = [x1i, x1[0], x1[1]];
// keep the last three values of the second generator
x2 = [x2i, x2[0], x2[1]];
 
return z + 1;
}
 
double next_float() {
return cast(double) next_int() / d;
}
}
 
void main() {
auto rng = new RNG();
 
rng.seed(1234567);
writeln(rng.next_int);
writeln(rng.next_int);
writeln(rng.next_int);
writeln(rng.next_int);
writeln(rng.next_int);
writeln;
 
int[5] counts;
rng.seed(987654321);
foreach (i; 0 .. 100_000) {
auto value = cast(int) floor(rng.next_float * 5.0);
counts[value]++;
}
foreach (i,v; counts) {
writeln(i, ": ", v);
}
}</syntaxhighlight>
{{out}}
<pre>1459213977
Line 422 ⟶ 510:
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: arrays kernel math math.order math.statistics
math.vectors prettyprint sequences ;
 
Line 447 ⟶ 535:
 
987654321 seed 100,000 [ next-float 5 * >integer ] replicate
2nip histogram .</langsyntaxhighlight>
{{out}}
<pre>
Line 458 ⟶ 546:
</pre>
 
=={{header|Forth}}==
{{trans|uBasic/4tH}}
{{works with|4tH v3.64}}
<syntaxhighlight lang="forth">6 array (seed) \ holds the seed
6 array (gens) \ holds the generators
\ set up constants
0 (gens) 0 th ! \ 1st generator
1403580 (gens) 1 th !
-810728 (gens) 2 th !
527612 (gens) 3 th ! \ 2nd generator
0 (gens) 4 th !
-1370589 (gens) 5 th !
 
1 32 lshift 209 - value (m) \ 1st generator constant
1 32 lshift 22853 - value (n) \ 2nd generator constant
( n1 n2 -- n3)
: (mod) tuck mod tuck 0< if abs + ;then drop ;
: (generate) do (seed) i th @ (gens) i th @ * + loop swap (mod) ;
: (reseed) ?do (seed) i th ! loop ; ( n1 n2 n3 limit index --)
: randomize 6 0 do dup i 3 mod if >zero then (seed) i th ! loop drop ;
( n --)
: random ( -- n)
(m) 0 3 0 (generate) (n) 0 6 3 (generate) over over
(seed) 4 th @ (seed) 3 th @ rot 6 3 (reseed)
(seed) 1 th @ (seed) 0 th @ rot 3 0 (reseed) - (m) (mod) 1+
;
 
include lib/fp1.4th \ simple floating point support
include lib/zenfloor.4th \ for FLOOR
 
5 array (count) \ setup an array of 5 elements
 
: test
1234567 randomize
random . cr random . cr random . cr
random . cr random . cr cr \ perform the first test
 
987654321 randomize (m) 1+ s>f \ set up denominator
 
100000 0 ?do \ do this 100,000 times
random s>f fover f/ 5 s>f f* floor f>s cells (count) + 1 swap +!
loop fdrop
\ show the results
5 0 ?do i . ." : " (count) i th ? cr loop
;
 
test</syntaxhighlight>
{{out}}
<pre>1459213977
2827710106
4245671317
3877608661
2595287583
 
0 : 20002
1 : 20060
2 : 19948
3 : 20059
4 : 19931
</pre>
=={{header|Go}}==
{{trans|Python}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 527 ⟶ 675:
fmt.Printf(" %d : %d\n", i, counts[i])
}
}</langsyntaxhighlight>
 
{{out}}
Line 538 ⟶ 686:
 
The counts for 100,000 repetitions are:
0 : 20002
1 : 20060
2 : 19948
3 : 20059
4 : 19931
</pre>
 
=={{header|Haskell}}==
 
<syntaxhighlight lang="haskell">import Data.List
 
randoms :: Int -> [Int]
randoms seed = unfoldr go ([seed,0,0],[seed,0,0])
where
go (x1,x2) =
let x1i = sum (zipWith (*) x1 a1) `mod` m1
x2i = sum (zipWith (*) x2 a2) `mod` m2
in Just $ ((x1i - x2i) `mod` m1, (x1i:init x1, x2i:init x2))
a1 = [0, 1403580, -810728]
m1 = 2^32 - 209
a2 = [527612, 0, -1370589]
m2 = 2^32 - 22853
 
randomsFloat = map ((/ (2^32 - 208)) . fromIntegral) . randoms</syntaxhighlight>
 
<pre>*Main> take 5 $ randoms 1234567
[1459213976,2827710105,4245671316,3877608660,2595287582]
 
*Main> let hist = map length . group . sort
*Main> hist . take 100000 $ (floor . (*5)) <$> randomsFloat 987654321
[20002,20060,19948,20059,19931]</pre>
 
=== As a RandomGen instanse ===
<syntaxhighlight lang="haskell">import System.Random
 
newtype MRG32k3a = MRG32k3a ([Int],[Int])
 
mkMRG32k3a s = MRG32k3a ([s,0,0],[s,0,0])
 
instance RandomGen MRG32k3a where
next (MRG32k3a (x1,x2)) =
let x1i = sum (zipWith (*) x1 a1) `mod` m1
x2i = sum (zipWith (*) x2 a2) `mod` m2
in ((x1i - x2i) `mod` m1, MRG32k3a (x1i:init x1, x2i:init x2))
where
a1 = [0, 1403580, -810728]
m1 = 2^32 - 209
a2 = [527612, 0, -1370589]
m2 = 2^32 - 22853
 
split _ = error "MRG32k3a is not splittable"</syntaxhighlight>
 
In this case the sequence or numbers differs from direct unfolding, due to internal uniform shuffling.
 
<pre>*Main> take 5 $ randoms (mkMRG32k3a 1234567)
[2827710105,3877608660,3642754129,1259674122,3002249941]
 
*Main> let hist = map length . group . sort
*Main> hist . take 100000 $ (floor . (*5)) <$> (randoms (mkMRG32k3a 987654321) :: [Float])
[20015,19789,20024,20133,20039]</pre>
 
=={{header|Java}}==
{{trans|C++}}
<syntaxhighlight lang="java">public class App {
private static long mod(long x, long y) {
long m = x % y;
if (m < 0) {
if (y < 0) {
return m - y;
} else {
return m + y;
}
}
return m;
}
 
public static class RNG {
// first generator
private final long[] a1 = {0, 1403580, -810728};
private static final long m1 = (1L << 32) - 209;
private long[] x1;
// second generator
private final long[] a2 = {527612, 0, -1370589};
private static final long m2 = (1L << 32) - 22853;
private long[] x2;
// other
private static final long d = m1 + 1;
 
public void seed(long state) {
x1 = new long[]{state, 0, 0};
x2 = new long[]{state, 0, 0};
}
 
public long nextInt() {
long x1i = mod(a1[0] * x1[0] + a1[1] * x1[1] + a1[2] * x1[2], m1);
long x2i = mod(a2[0] * x2[0] + a2[1] * x2[1] + a2[2] * x2[2], m2);
long z = mod(x1i - x2i, m1);
 
// keep the last three values of the first generator
x1 = new long[]{x1i, x1[0], x1[1]};
// keep the last three values of the second generator
x2 = new long[]{x2i, x2[0], x2[1]};
 
return z + 1;
}
 
public double nextFloat() {
return 1.0 * nextInt() / d;
}
}
 
public static void main(String[] args) {
RNG rng = new RNG();
 
rng.seed(1234567);
System.out.println(rng.nextInt());
System.out.println(rng.nextInt());
System.out.println(rng.nextInt());
System.out.println(rng.nextInt());
System.out.println(rng.nextInt());
System.out.println();
 
int[] counts = {0, 0, 0, 0, 0};
rng.seed(987654321);
for (int i = 0; i < 100_000; i++) {
int value = (int) Math.floor(rng.nextFloat() * 5.0);
counts[value]++;
}
for (int i = 0; i < counts.length; i++) {
System.out.printf("%d: %d%n", i, counts[i]);
}
}
}</syntaxhighlight>
{{out}}
<pre>1459213977
2827710106
4245671317
3877608661
2595287583
 
0: 20002
1: 20060
2: 19948
3: 20059
4: 19931</pre>
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
 
'''Works with jq, the C implementation of jq'''
 
'''Works with gojq, the Go implementation of jq'''
 
'''Works with jaq, the Rust implementation of jq''' provided the
MRG32k3a module (minus its declaration) is inlined.
 
The jq module ''MRG32k3a'' is available at [[:Category:Jq/MRG32k3a.jq | MRG32k3a.jq]].
 
<syntaxhighlight lang="jq">
include "MRG32k3a" {search: "."}; # see above
 
def task1:
foreach range(0; 5) as $i (seed(1234567); nextInt ) | .nextInt;
 
def task2($n):
seed(987654321)
| reduce range(0; $n) as $i (.counts = [range(0;5)|0];
nextFloat
| .counts[ (.nextFloat * 5) | floor ] += 1 )
| "\nThe counts for \($n) repetitions are:",
(range(0;5) as $i | " \($i) : \(.counts[$i] // 0)");
 
task1,
task2(100000)
</syntaxhighlight>
 
{{output}}
<pre>
1459213977
2827710106
4245671317
3877608661
2595287583
 
The counts for 100000 repetitions are:
0 : 20002
1 : 20060
Line 546 ⟶ 879:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">const a1 = [0, 1403580, -810728]
const m1 = 2^32 - 209
const a2 = [527612, 0, -1370589]
Line 580 ⟶ 913:
end
foreach(p -> print(p[1], ": ", p[2], " "), enumerate(hist))
</langsyntaxhighlight>{{out}}
<pre>
1459213977
Line 592 ⟶ 925:
=={{header|Kotlin}}==
{{trans|C++}}
<langsyntaxhighlight lang="scala">import kotlin.math.floor
 
fun mod(x: Long, y: Long): Long {
Line 661 ⟶ 994:
println("${iv.index}: ${iv.value}")
}
}</langsyntaxhighlight>
{{out}}
<pre>1459213977
Line 676 ⟶ 1,009:
 
=={{header|Nim}}==
<langsyntaxhighlight Nimlang="nim">import algorithm, math, sequtils, strutils, tables
 
const
Line 723 ⟶ 1,056:
for _ in 1..100_000:
counts.inc int(gen.nextFloat() * 5)
echo sorted(toSeq(counts.pairs)).mapIt($it[0] & ": " & $it[1]).join(", ")</langsyntaxhighlight>
 
{{out}}
Line 733 ⟶ 1,066:
 
0: 20002, 1: 20060, 2: 19948, 3: 20059, 4: 19931</pre>
 
=={{header|Pari/GP}}==
Pretty straightforward translation from the directions. Used column/vector multiplication (essentially he dot product) instead of the more tedious form given in the definition of x1i and x2i; rationals (t_FRAC) used in place of floating-point since GP lacks floating-point.
<syntaxhighlight lang="parigp">a1 = [0, 1403580, -810728];
m1 = 2^32-209;
a2 = [527612, 0, -1370589];
m2 = 2^32-22853;
d = m1+1;
seed(s)=x1=x2=[s,0,0];
next_int()=
{
my(x1i=a1*x1~%m1, x2i=a2*x2~%m2);
x1 = [x1i, x1[1], x1[2]];
x2 = [x2i, x2[1], x2[2]];
(x1i-x2i)%m1 + 1;
}
next_float()=next_int()/d;
 
seed(1234567);
vector(5,i,next_int())
seed(987654321);
v=vector(5); for(i=1,1e5, v[next_float()*5\1+1]++); v</syntaxhighlight>
{{out}}
<pre>%1 = [1459213977, 2827710106, 4245671317, 3877608661, 2595287583]
%2 = [20002, 20060, 19948, 20059, 19931]</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
Line 757 ⟶ 1,115:
 
sub next_int {
my ($class,$self) = @_;
unshift @{$$self{x1}}, ($a1[0] * $$self{x1}[0] + $a1[1] * $$self{x1}[1] + $a1[2] * $$self{x1}[2]) % m1; pop @{$$self{x1}};
unshift @{$$self{x2}}, ($a2[0] * $$self{x2}[0] + $a2[1] * $$self{x2}[1] + $a2[2] * $$self{x2}[2]) % m2; pop @{$$self{x2}};
Line 763 ⟶ 1,121:
}
 
sub next_float { next_int(@$_)[0]->next_int / (m1 + 1) }
}
 
say 'Seed: 1234567, first 5 values:';
my $rng = MRG32k3a->new( seed => 1234567 );
say MRG32k3a$rng->next_int($rng) for 1..5;
 
my %h;
say "\nSeed: 987654321, values histogram:";
$rng = MRG32k3a->new( seed => 987654321 );
$h{int 5 * MRG32k3a$rng->next_float($rng)}++ for 1..100_000;
say "$_ $h{$_}" for sort keys %h;</langsyntaxhighlight>
{{out}}
<pre>Seed: 1234567, first 5 values:
Line 791 ⟶ 1,149:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
-- First generator
<span style="color: #008080;">constant</span>
a1 = {0, 1403580, -810728},
<span style="color: #000080;font-style:italic;">-- First generator</span>
m1 = power(2,32) - 209,
<span style="color: #000000;">a1</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1403580</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">810728</span><span style="color: #0000FF;">},</span>
-- Second Generator
<span style="color: #000000;">m1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">32</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">209</span><span style="color: #0000FF;">,</span>
a2 = {527612, 0, -1370589},
<span style="color: #000080;font-style:italic;">-- Second Generator</span>
m2 = power(2,32) - 22853,
<span style="color: #000000;">a2</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">527612</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1370589</span><span style="color: #0000FF;">},</span>
d = m1 + 1
<span style="color: #000000;">m2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">32</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">22853</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">m1</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">1</span>
sequence x1 = {0, 0, 0}, /* list of three last values of gen #1 */
x2 = {0, 0, 0} /* list of three last values of gen #2 */
<span style="color: #004080;">sequence</span> <span style="color: #000000;">x1</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">/* list of three last values of gen #1 */</span>
<span style="color: #000000;">x2</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}</span> <span style="color: #000080;font-style:italic;">/* list of three last values of gen #2 */</span>
procedure seed(integer seed_state)
assert(seed_state>0 and seed_state<d)
<span style="color: #008080;">procedure</span> <span style="color: #000000;">seed</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">seed_state</span><span style="color: #0000FF;">)</span>
x1 = {seed_state, 0, 0}
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">seed_state</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #000000;">seed_state</span><span style="color: #0000FF;"><</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
x2 = {seed_state, 0, 0}
<span style="color: #000000;">x1</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">seed_state</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}</span>
end procedure
<span style="color: #000000;">x2</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">seed_state</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
function next_int()
atom x1i = mod(a1[1]*x1[1] + a1[2]*x1[2] + a1[3]*x1[3],m1),
<span style="color: #008080;">function</span> <span style="color: #000000;">next_int</span><span style="color: #0000FF;">()</span>
x2i = mod(a2[1]*x2[1] + a2[2]*x2[2] + a2[3]*x2[3],m2)
<span style="color: #004080;">atom</span> <span style="color: #000000;">x1i</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">a1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">a1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">],</span><span style="color: #000000;">m1</span><span style="color: #0000FF;">),</span>
x1 = {x1i, x1[1], x1[2]} /* Keep last three */
<span style="color: #000000;">x2i</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">a2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">a2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">],</span><span style="color: #000000;">m2</span><span style="color: #0000FF;">)</span>
x2 = {x2i, x2[1], x2[2]} /* Keep last three */
<span style="color: #000000;">x1</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x1i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]}</span> <span style="color: #000080;font-style:italic;">/* Keep last three */</span>
atom z = mod(x1i-x2i,m1),
<span style="color: #000000;">x2</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x2i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">x2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]}</span> <span style="color: #000080;font-style:italic;">/* Keep last three */</span>
answer = (z + 1)
<span style="color: #004080;">atom</span> <span style="color: #000000;">z</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x1i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">x2i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m1</span><span style="color: #0000FF;">),</span>
return answer
<span style="color: #000000;">answer</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">z</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">answer</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function next_float()
return next_int() / d
<span style="color: #008080;">function</span> <span style="color: #000000;">next_float</span><span style="color: #0000FF;">()</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">next_int</span><span style="color: #0000FF;">()</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">d</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
seed(1234567)
for i=1 to 5 do
<span style="color: #000000;">seed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1234567</span><span style="color: #0000FF;">)</span>
printf(1,"%d\n",next_int())
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">5</span> <span style="color: #008080;">do</span>
end for
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">next_int</span><span style="color: #0000FF;">())</span>
seed(987654321)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
sequence r = repeat(0,5)
<span style="color: #000000;">seed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">987654321</span><span style="color: #0000FF;">)</span>
for i=1 to 100_000 do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
r[floor(next_float()*5)+1] += 1
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">100_000</span> <span style="color: #008080;">do</span>
end for
<span style="color: #004080;">integer</span> <span style="color: #000000;">rdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">next_float</span><span style="color: #0000FF;">()*</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
?r</lang>
<span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rdx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">r</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 841 ⟶ 1,203:
2595287583
{20002,20060,19948,20059,19931}
</pre>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python"># Constants
a1 = [0, 1403580, -810728]
m1 = 2**32 - 209
Line 890 ⟶ 1,252:
for i in range(100_000):
hist[int(random_gen.next_float() *5)] += 1
print(hist)</langsyntaxhighlight>
 
{{out}}
Line 906 ⟶ 1,268:
All constants are encapsulated within the class.
 
<syntaxhighlight lang="raku" perl6line>class MRG32k3a {
has @!x1;
has @!x2;
Line 942 ⟶ 1,304:
say "\nSeed: default; first five Int values:";
$rng = MRG32k3a.new;
.say for $rng.next-int xx 5;</langsyntaxhighlight>
{{out}}
<pre>Seed: 1234567; first five Int values:
Line 963 ⟶ 1,325:
=={{header|Ruby}}==
{{trans|C}}
<langsyntaxhighlight lang="ruby">def mod(x, y)
m = x % y
if m < 0 then
Line 1,030 ⟶ 1,392:
counts.each_with_index { |v,i|
print i, ": ", v, "\n"
}</langsyntaxhighlight>
{{out}}
<pre>1459213977
Line 1,043 ⟶ 1,405:
3: 20059
4: 19931</pre>
===Mimicking the Pseudo-code===
<syntaxhighlight lang="ruby"># Constants
# First generator
A1 = [0, 1403580, -810728]
M1 = 2**32 - 209
# Second Generator
A2 = [527612, 0, -1370589]
M2 = 2**32 - 22853
D = M1 + 1
class MRG32k3a
 
def seed(seed_state)
raise ArgumentError unless seed_state.between?(0, D)
@x1 = [seed_state, 0, 0]
@x2 = [seed_state, 0, 0]
end
def next_int
x1i = (A1[0]*@x1[0] + A1[1]*@x1[1] + A1[2]*@x1[2]).modulo M1
x2i = (A2[0]*@x2[0] + A2[1]*@x2[1] + A2[2]*@x2[2]).modulo M2
@x1 = [x1i, @x1[0], @x1[1]] # Keep last three
@x2 = [x2i, @x2[0], @x2[1]] # Keep last three
z = (x1i - x2i) % M1
return z + 1
end
def next_float
next_int.to_f / D
end
end
 
random_gen = MRG32k3a.new
random_gen.seed(1234567)
5.times{ puts random_gen.next_int}
 
random_gen = MRG32k3a.new
random_gen.seed(987654321)
p 100_000.times.map{(random_gen.next_float() * 5).floor}.tally.sort.to_h
</syntaxhighlight>
 
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">class MRG32k3a(seed) {
 
define(
m1 = (2**32 - 209)
m2 = (2**32 - 22853)
)
 
define(
a1 = %n< 0 1403580 -810728>
a2 = %n<527612 0 -1370589>
)
 
has x1 = [seed, 0, 0]
has x2 = x1.clone
 
method next_int {
x1.unshift(a1.map_kv {|k,v| v * x1[k] }.sum % m1); x1.pop
x2.unshift(a2.map_kv {|k,v| v * x2[k] }.sum % m2); x2.pop
(x1[0] - x2[0]) % (m1 + 1)
}
 
method next_float { self.next_int / (m1 + 1) -> float }
}
 
say "Seed: 1234567, first 5 values:"
var rng = MRG32k3a(seed: 1234567)
5.of { rng.next_int }.each { .say }
 
say "\nSeed: 987654321, values histogram:";
var rng = MRG32k3a(seed: 987654321)
var freq = 100_000.of { rng.next_float * 5 -> int }.freq
freq.sort.each_2d {|k,v| say "#{k} #{v}" }</syntaxhighlight>
{{out}}
<pre>
Seed: 1234567, first 5 values:
1459213977
2827710106
4245671317
3877608661
2595287583
 
Seed: 987654321, values histogram:
0 20002
1 20060
2 19948
3 20059
4 19931
</pre>
 
=={{header|uBasic/4tH}}==
{{works with|v3.64}}
{{trans|C}}
Since uBasic/4tH has no floating point support, only the integer part of the task can be implemented.
<syntaxhighlight lang="text">@(0) = 0 ' First generator
@(1) = 1403580
@(2) = -810728
m = SHL(1, 32) - 209
 
@(3) = 527612 ' Second generator
@(4) = 0
@(5) = -1370589
n = SHL(1, 32) - 22853
 
d = SHL(1, 32) - 209 + 1 ' m + 1
 
Proc _Seed(1234567)
Print FUNC(_NextInt)
Print FUNC(_NextInt)
Print FUNC(_NextInt)
Print FUNC(_NextInt)
Print FUNC(_NextInt)
Print
End
 
_Mod Param(2)
Local(1)
c@ = a@ % b@
If c@ < 0 Then
If b@ < 0 Then
Return (c@-b@)
Else
Return (c@+b@)
Endif
EndIf
Return (c@)
 
_Seed Param(1) ' seed the PRNG
@(6) = a@
@(7) = 0
@(8) = 0
 
@(9) = a@
@(10) = 0
@(11) = 0
Return
 
_NextInt ' get the next random integer value
Local(3)
 
a@ = FUNC(_Mod((@(0) * @(6) + @(1) * @(7) + @(2) * @(8)), m))
b@ = FUNC(_Mod((@(3) * @(9) + @(4) * @(10) + @(5) * @(11)), n))
c@ = FUNC(_Mod(a@ - b@, m))
 
' keep last three values of the first generator
@(8) = @(7)
@(7) = @(6)
@(6) = a@
 
' keep last three values of the second generator
@(11) = @(10)
@(10) = @(9)
@(9) = b@
 
Return (c@ + 1)</syntaxhighlight>
{{out}}
<pre>1459213977
2827710106
4245671317
3877608661
2595287583
 
 
0 OK, 0:398
</pre>
 
=={{header|Wren}}==
{{trans|Python}}
<langsyntaxhighlight ecmascriptlang="wren">// constants
var A1 = [0, 1403580, -810728]
var M1 = 2.pow(32) - 209
Line 1,095 ⟶ 1,626:
}
System.print("\nThe counts for 100,000 repetitions are:")
for (i in 0..4) System.print(" %(i) : %(counts[i])")</langsyntaxhighlight>
 
{{out}}
2,502

edits