Pseudo-random numbers/PCG32: Difference between revisions

m (syntax highlighting fixup automation)
 
(13 intermediate revisions by 5 users not shown)
Line 83:
V shifted = UInt32(((old >> 18) (+) old) >> 27)
V rot = UInt32(old >> 59)
R (shifted >> rot) [|] (shifted << (((-)~rot + 1) [&] 31))
 
F seed(UInt64 seed_state, seed_sequence)
Line 366:
3 : 19809
4 : 20005</pre>
 
=={{header|C#}}==
{{trans|C++}}
<syntaxhighlight lang="C#">
using System;
 
class PCG32
{
private const ulong N = 6364136223846793005;
private ulong state = 0x853c49e6748fea9b;
private ulong inc = 0xda3e39cb94b95bdb;
 
public uint NextInt()
{
ulong old = state;
state = old * N + inc;
uint shifted = (uint)(((old >> 18) ^ old) >> 27);
uint rot = (uint)(old >> 59);
return (shifted >> (int)rot) | (shifted << (int)((~rot + 1) & 31));
}
 
public double NextFloat()
{
return ((double)NextInt()) / (1UL << 32);
}
 
public void Seed(ulong seedState, ulong seedSequence)
{
state = 0;
inc = (seedSequence << 1) | 1;
NextInt();
state += seedState;
NextInt();
}
}
 
class Program
{
static void Main(string[] args)
{
var r = new PCG32();
 
r.Seed(42, 54);
Console.WriteLine(r.NextInt());
Console.WriteLine(r.NextInt());
Console.WriteLine(r.NextInt());
Console.WriteLine(r.NextInt());
Console.WriteLine(r.NextInt());
Console.WriteLine();
 
int[] counts = new int[5];
r.Seed(987654321, 1);
for (int i = 0; i < 100000; i++)
{
int j = (int)Math.Floor(r.NextFloat() * 5.0);
counts[j]++;
}
 
Console.WriteLine("The counts for 100,000 repetitions are:");
for (int i = 0; i < counts.Length; i++)
{
Console.WriteLine($" {i} : {counts[i]}");
}
}
}
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005
 
</pre>
 
 
=={{header|C++}}==
Line 371 ⟶ 454:
<syntaxhighlight lang="cpp">#include <array>
#include <iostream>
#include <math.h>
 
class PCG32 {
Line 507 ⟶ 591:
3 : 19809
4 : 20005</pre>
 
=={{header|Dart}}==
{{trans|Python}}
<syntaxhighlight lang="Dart">
import 'dart:math';
 
class PCG32 {
BigInt fState = BigInt.zero;
BigInt fInc = BigInt.zero;
final BigInt mask64 = (BigInt.one << 64) - BigInt.one;
final BigInt mask32 = (BigInt.one << 32) - BigInt.one;
final BigInt k = BigInt.parse('6364136223846793005');
 
PCG32(BigInt seedState, BigInt seedSequence) {
seed(seedState, seedSequence);
}
 
PCG32.noSeed() {
fState = BigInt.zero;
fInc = BigInt.zero;
}
 
void seed(BigInt seedState, BigInt seedSequence) {
fState = BigInt.zero;
fInc = ((seedSequence << 1) | BigInt.one) & mask64;
nextInt();
fState += seedState;
nextInt();
}
 
BigInt nextInt() {
BigInt old = fState;
fState = ((old * k) + fInc) & mask64;
BigInt xorshifted = ( ((old >> 18) ^ old) >> 27) & mask32;
BigInt rot = (old >> 59) & mask32;
BigInt shifted = (xorshifted >> rot.toInt()) | (xorshifted << ((-rot) & BigInt.from(31)).toInt());
return shifted & mask32;
}
 
double nextFloat() {
return nextInt().toDouble() / (BigInt.one << 32).toDouble();
}
 
List<BigInt> nextIntRange(int size) {
List<BigInt> result = [];
for (int i = 0; i < size; i++) {
result.add(nextInt());
}
return result;
}
}
 
void main() {
var pcg32 = PCG32(BigInt.from(42), BigInt.from(54));
 
for (int i = 0; i < 5; i++) {
print(pcg32.nextInt().toString());
}
 
pcg32.seed(BigInt.from(987654321), BigInt.one);
 
var count = <int, int>{};
 
for (int i = 0; i < 100000; i++) {
int key = (pcg32.nextFloat() * 5).truncate();
count[key] = (count[key] ?? 0) + 1;
}
 
print('\nThe counts for 100,000 repetitions are:');
count.forEach((key, value) {
print('$key : $value');
});
}
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
2 : 20115
3 : 19809
0 : 20049
4 : 20005
1 : 20022
 
</pre>
 
=={{header|Delphi}}==
Line 679 ⟶ 853:
(2, 20115)(3, 19809)(0, 20049)(4, 20005)(1, 20022)
</pre>
 
=={{header|Factor}}==
{{trans|Python}}
Line 724 ⟶ 899:
H{ { 0 20049 } { 1 20022 } { 2 20115 } { 3 19809 } { 4 20005 } }
</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="vbnet">#define floor(x) ((x*2.0-0.5) Shr 1)
 
Const As Ulongint mask64 = &HFFFFFFFFFFFFFFFF
Const As Ulongint mask32 = &HFFFFFFFF
Const As Ulongint cte = 6364136223846793005
 
Dim Shared As Ulongint state, inc
 
Function next_int() As Ulongint
' return random 32 bit unsigned int
Dim As Ulongint old = state
state = ((old * cte) + inc) And mask64
Dim As Ulongint xorshifted = (((old Shr 18) Xor old) Shr 27) And mask32
Dim As Ulongint rot = (old Shr 59) And mask32
Dim As Ulongint answer = (xorshifted Shr rot) Or (xorshifted Shl ((-rot) And 31))
answer And= mask32
Return answer
End Function
 
Function next_float() As Double
' return random float between 0 and 1
Return next_int() / (2 ^ 32)
End Function
 
Sub seed(seed_state As Ulongint, seed_sequence As Ulongint)
state = 0
inc = ((seed_sequence Shl 1) Or 1) And mask64
next_int()
state = (state + seed_state) And mask64
next_int()
End Sub
 
Dim As Integer i, hist(4)
 
seed(42, 54)
For i = 1 To 5
Print next_int()
Next i
 
Print !"\nThe counts for 100,000 repetitions are:"
seed(987654321, 1)
For i = 1 To 100000
hist(floor(next_float() * 5)) += 1
Next i
For i = 0 To 4
Print Using "hist(#) = #####"; i; hist(i)
Next i
 
Sleep</syntaxhighlight>
{{out}}
<pre>2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
hist(0) = 20049
hist(1) = 20022
hist(2) = 20115
hist(3) = 19809
hist(4) = 20005</pre>
 
=={{header|Go}}==
Line 952 ⟶ 1,191:
3 : 19809
4 : 20005</pre>
 
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
 
'''Works with gojq, the Go implementation of jq'''
 
The following uses some functions from the [[:Category:jq/bitwise.jq|"bitwise" module]].
If, for example, your jq does not support modules, you could insert the relevant definitions
therefrom in place of the "include" directive.
<syntaxhighlight lang=jq>
include "bitwise" {search: "."}; # see above
 
def Const: 6364136223846793005;
def Mask64: 18446744073709551615; # i.e. (1 | leftshift(64)) - 1
def Mask32: 4294967295; # i.e. (1 | leftshift(32)) - 1
 
# An initialization function if you do not wish to use seed/2
def rcg32:
{state: 9600629759793949339, # 0x853c49e6748fea9b
inc: 15726070495360670683 # 0xda3e39cb94b95bdb
};
 
# Input: {state, inc}
# Output: {state, inc, nextInt}
def nextInt:
.state as $old
| .state = bitwise_and($old * Const + .inc; Mask64)
| bitwise_and(( bitwise_xor($old | rightshift(18); $old) | rightshift(27)); Mask32) as $xorshifted
| bitwise_and($old|rightshift(59) ; Mask32) as $rot
| .nextInt = bitwise_and(
bitwise_or(
$xorshifted | rightshift($rot) ;
$xorshifted | leftshift( bitwise_and( 32 - $rot; 31) )) ;
Mask32) ;
 
def nextFloat:
nextInt
| .nextFloat = .nextInt / pow(2;32);
 
def seed($seedState; $seedSequence):
{state: 0,
inc: bitwise_and( bitwise_xor($seedSequence|leftshift(1); 1); Mask64)
}
| nextInt
| .state += $seedState
| nextInt;
 
def task1($n):
foreach range(0; $n) as $i (seed(42; 54); nextInt)
| .nextInt;
 
def task2($n):
reduce range(0; $n) as $i (seed(987654321; 1);
nextFloat
| .counts[((.nextFloat * 5)|floor)] += 1)
| "\nThe counts for \($n) repetitions are:",
(range(0; 5) as $i | "\($i) : \(.counts[$i])") ;
 
task1(5),
task2(100000)
</syntaxhighlight>
{{output}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100000 repetitions are:
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005
</pre>
 
=={{header|Julia}}==
Line 1,151 ⟶ 1,466:
3: 19809
4: 20005</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
{{trans|Julia}}
<syntaxhighlight lang="Mathematica">
ClearAll["Global`*"];
 
(*Constants*)
mask32 = BitAnd[2^32 - 1];
CONST = 6364136223846793005;
 
(*Convert Hex String to Expression*)
Hex[x_?StringQ] := ToExpression["16^^" <> StringDrop[x, 2]];
 
(*Definition of PCG32 Structure*)
PCG32[state_: Hex["0x853c49e6748fea9b"],
inc_: Hex["0xda3e39cb94b95bdb"]] := <|"state" -> state,
"inc" -> inc|>;
 
(*Function to generate next integer*)
nextInt[pcg_Association] :=
Module[{old, xorshifted, rot, newState}, old = pcg["state"];
newState = BitAnd[(old*CONST + pcg["inc"]), 2^64 - 1];
xorshifted =
BitAnd[BitShiftRight[BitXor[BitShiftRight[old, 18], old], 27],
mask32];
rot = BitAnd[BitShiftRight[old, 59], mask32];
<|"state" -> newState, "inc" -> pcg["inc"],
"nextInt" ->
BitAnd[BitOr[BitShiftRight[xorshifted, rot],
BitShiftLeft[xorshifted, BitAnd[-rot, 31]]], mask32]|>];
 
(*Function to generate next float*)
nextFloat[pcg_Association] := nextInt[pcg]["nextInt"]/2^32;
 
(*Function to seed the generator*)
seed[pcg_Association, st_, seq_] :=
Module[{newPcg},
newPcg = <|"state" -> 0,
"inc" -> BitOr[BitShiftLeft[seq, 1], 1]|>;
newPcg = nextInt[newPcg];
<|"state" -> newPcg["state"] + st, "inc" -> newPcg["inc"]|>];
 
(*Test function*)
testPCG32[] :=
Module[{randomGen, hist, n, nextGen}, randomGen = PCG32[];
randomGen = seed[randomGen, 42, 54];
Do[
nextGen = nextInt[randomGen];
randNumber = nextGen["nextInt"];
If[randNumber != 0, Print[randNumber]];
randomGen = nextGen
, {6}];
randomGen = seed[randomGen, 987654321, 1];
hist = ConstantArray[0, 5];
Do[nextGen = nextInt[randomGen];
hist[[Floor[nextFloat[nextGen]*5] + 1]] += 1;
randomGen = nextGen, {100000}];
Print[hist];
Do[Print[n - 1, ": ", hist[[n]], " "], {n, 1, 5}];];
 
(*Run the test*)
testPCG32[];
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
{20049, 20022, 20115, 19809, 20005}
0: 20049
1: 20022
2: 20115
3: 19809
4: 20005
 
</pre>
 
=={{header|Nim}}==
Line 1,198 ⟶ 1,591:
 
0: 20049, 1: 20022, 2: 20115, 3: 19809, 4: 20005</pre>
 
=={{header|OCaml}}==
<syntaxhighlight lang="ocaml">let (>>) = Int64.shift_right_logical
 
let int32_bound n x =
Int64.(to_int ((mul (logand (of_int32 x) 0xffffffffL) (of_int n)) >> 32))
 
let int32_rotate_right x n =
Int32.(logor (shift_left x (-n land 31)) (shift_right_logical x n))
 
let pcg32_next inc st =
Int64.(add (mul st 0x5851f42d4c957f2dL) inc)
 
let pcg32_output st =
int32_rotate_right
(Int32.logxor (Int64.to_int32 (st >> 27)) (Int64.to_int32 (st >> 45)))
(Int64.to_int (st >> 59))
 
let seq_pcg32 (st, f) =
let rec repeat st () = Seq.Cons (pcg32_output st, repeat (f st)) in
repeat (f st)
 
let pcg32 seed_st seed_sq =
let inc = Int64.(add (succ seed_sq) seed_sq) in
Int64.add seed_st inc, pcg32_next inc</syntaxhighlight>
;<nowiki>Test:</nowiki>
<syntaxhighlight lang="ocaml">let () =
pcg32 42L 54L |> seq_pcg32 |> Seq.take 5
|> Seq.iter (Printf.printf " %lu") |> print_newline
 
let () =
pcg32 987654321L 1L |> seq_pcg32 |> Seq.map (int32_bound 5) |> Seq.take 100000
|> Seq.fold_left (fun a n -> a.(n) <- succ a.(n); a) (Array.make 5 0)
|> Array.iteri (Printf.printf "%u: %u\n")</syntaxhighlight>
{{out}}
<pre>
2707161783 2068313097 3122475824 2211639955 3215226955
0: 20049
1: 20022
2: 20115
3: 19809
4: 20005
</pre>
 
=={{header|Perl}}==
Line 1,882 ⟶ 2,318:
</pre>
 
=={{header|Rust}}==
{{trans|C++}}
<syntaxhighlight lang="Rust">
struct PCG32 {
multiplier: u64,
state: u64,
inc: u64,
}
 
impl PCG32 {
fn new() -> Self {
PCG32 {
multiplier: 6364136223846793005,
state: 0x853c49e6748fea9b,
inc: 0xda3e39cb94b95bdb,
}
}
 
fn next_int(&mut self) -> u32 {
let old = self.state;
self.state = old.wrapping_mul(self.multiplier).wrapping_add(self.inc);
let xorshifted = (((old >> 18) ^ old) >> 27) as u32;
let rot = (old >> 59) as u32;
(xorshifted >> rot) | (xorshifted << ((!rot).wrapping_add(1) & 31))
}
 
fn next_float(&mut self) -> f64 {
(self.next_int() as f64) / ((1u64 << 32) as f64)
}
 
fn seed(&mut self, seed_state: u64, seed_sequence: u64) {
self.state = 0;
self.inc = (seed_sequence << 1) | 1;
self.next_int();
self.state = self.state.wrapping_add(seed_state);
self.next_int();
}
}
 
fn main() {
let mut rng = PCG32::new();
 
rng.seed(42, 54);
for _ in 0..5 {
println!("{}", rng.next_int());
}
 
println!();
 
let mut counts = [0; 5];
rng.seed(987654321, 1);
for _ in 0..100000 {
let j = (rng.next_float() * 5.0).floor() as usize;
counts[j] += 1;
}
 
println!("The counts for 100,000 repetitions are:");
for (i, count) in counts.iter().enumerate() {
println!(" {} : {}", i, count);
}
}
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005
 
</pre>
 
=={{header|Scala}}==
{{trans|Java}}
<syntaxhighlight lang="Scala">
object PCG32 {
private val N = 6364136223846793005L
 
private var state = 0x853c49e6748fea9bL
private var inc = 0xda3e39cb94b95bdbL
 
def seed(seedState: Long, seedSequence: Long): Unit = {
state = 0
inc = (seedSequence << 1) | 1
nextInt()
state += seedState
nextInt()
}
 
def nextInt(): Int = {
val old = state
state = old * N + inc
val shifted = (((old >>> 18) ^ old) >>> 27).toInt
val rot = (old >>> 59).toInt
(shifted >>> rot) | (shifted << ((~rot + 1) & 31))
}
 
def nextFloat(): Double = {
val u = nextInt() & 0xffffffffL
u.toDouble / (1L << 32)
}
}
 
object Main extends App {
val r = PCG32
 
r.seed(42, 54)
println(Integer.toUnsignedString(r.nextInt()))
println(Integer.toUnsignedString(r.nextInt()))
println(Integer.toUnsignedString(r.nextInt()))
println(Integer.toUnsignedString(r.nextInt()))
println(Integer.toUnsignedString(r.nextInt()))
println()
 
val counts = Array(0, 0, 0, 0, 0)
r.seed(987654321, 1)
for (_ <- 1 to 100000) {
val j = Math.floor(r.nextFloat() * 5.0).toInt
counts(j) += 1
}
 
println("The counts for 100,000 repetitions are:")
for (i <- counts.indices) {
println(s" $i : ${counts(i)}")
}
}
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005
 
</pre>
 
=={{header|Scheme}}==
Line 1,969 ⟶ 2,555:
4 : 20005
</pre>
 
 
=={{header|Sidef}}==
Line 2,081 ⟶ 2,666:
 
0: 20049, 1: 20022, 2: 20115, 3: 19809, 4: 20005</pre>
 
=={{header|Tcl}}==
{{trans|C}}
<syntaxhighlight lang="Tcl">
proc uint32 {n} {
return [expr {$n & 0xffffffff}]
}
 
proc uint64 {n} {
return [expr {$n & 0xffffffffffffffff}]
}
 
set N 6364136223846793005
set state 0x853c49e6748fea9b
set inc 0xda3e39cb94b95bdb
 
proc pcg32_seed {seed_state seed_sequence} {
global state inc
set state 0
set inc [expr {($seed_sequence << 1) | 1}]
pcg32_int
set state [expr {$state + $seed_state}]
pcg32_int
}
 
proc pcg32_int {} {
global state N inc
set old $state
set state [uint64 [expr {$old * $N + $inc}]]
set shifted [uint32 [expr {(($old >> 18) ^ $old) >> 27}]]
set rot [uint32 [expr {$old >> 59}]]
return [uint32 [expr {($shifted >> $rot) | ($shifted << ((~$rot + 1) & 31))}]]
}
 
proc pcg32_float {} {
return [expr {1.0 * [pcg32_int] / (1 << 32)}]
}
 
# -------------------------------------------------------------------
 
pcg32_seed 42 54
puts [pcg32_int]
puts [pcg32_int]
puts [pcg32_int]
puts [pcg32_int]
puts [pcg32_int]
puts ""
 
set counts {0 0 0 0 0}
pcg32_seed 987654321 1
for {set i 1} {$i <= 100000} {incr i} {
set j [expr {int([pcg32_float] * 5.0) + 1}]
lset counts [expr {$j - 1}] [expr {[lindex $counts [expr {$j - 1}]] + 1}]
}
 
puts "The counts for 100,000 repetitions are:"
foreach idx {0 1 2 3 4} {
puts " $idx: [lindex $counts $idx]"
}
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
0: 20049
1: 20022
2: 20115
3: 19809
4: 20005
 
</pre>
 
 
=={{header|uBasic/4tH}}==
Line 2,127 ⟶ 2,789:
 
0 OK, 0:391</pre>
 
=={{header|Wren}}==
{{trans|Python}}
{{libheader|Wren-big}}
As Wren doesn't have a 64-bit integer type, we use BigInt instead.
<syntaxhighlight lang="ecmascriptwren">import "./big" for BigInt
 
var Const = BigInt.new("6364136223846793005")
2,507

edits