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

Content added Content deleted
(New draft task with Python solution)
 
(→‎{{header|Raku}}: Add a Raku example)
Line 125: Line 125:
2595287583
2595287583
{0: 20002, 1: 20060, 2: 19948, 3: 20059, 4: 19931}</pre>
{0: 20002, 1: 20060, 2: 19948, 3: 20059, 4: 19931}</pre>

=={{header|Raku}}==
{{works with|Rakudo|2020.07}}
{{trans|Python}}

All constants are encapsulated within the class.

<lang perl6>class MRG32k3a {
has @!x1;
has @!x2;

constant a1 = 0, 1403580, -810728;
constant a2 = 527612, 0, -1370589;
constant m1 = 2**32 - 209;
constant m2 = 2**32 - 22853;

submethod BUILD ( Int :$seed where { 0 < $_ < m1 + 1 } = 1 ) { @!x1 = @!x2 = $seed, 0, 0; }

method next-int {
my $x1i = (a1[0] * @!x1[0] + a1[1] * @!x1[1] + a1[2] * @!x1[2]) % m1;
my $x2i = (a2[0] * @!x2[0] + a2[1] * @!x2[1] + a2[2] * @!x2[2]) % m2;
@!x1 = $x1i, |@!x1[0, 1];
@!x2 = $x2i, |@!x2[0, 1];
($x1i - $x2i) % m1 + 1
}

method next-rat { self.next-int / (m1 + 1) }
}


# Test next-int with custom seed
say 'Seed: 1234567; first five Int values:';
my $rng = MRG32k3a.new( :seed(1234567) );
.say for $rng.next-int xx 5;


# Test next-rat (since these are rational numbers by default)
say "\nSeed: 987654321; first 1e5 Rat values histogram:";
$rng = MRG32k3a.new( :seed(987654321) );
say ( ($rng.next-rat * 5).floor xx 100_000 ).Bag;


# Test next-int with default seed and increment
say "\nSeed: default; first five Int values:";
$rng = MRG32k3a.new;
.say for $rng.next-int xx 5;</lang>
{{out}}
<pre>Seed: 1234567; first five Int values:
1459213977
2827710106
4245671317
3877608661
2595287583

Seed: 987654321; first 1e5 Rat values histogram:
Bag(0(20002) 1(20060) 2(19948) 3(20059) 4(19931))

Seed: default; first five Int values:
4294439476
798392476
1012402089
1268414425
3353586348
</pre>