Pseudo-random numbers/Splitmix64: Difference between revisions
Content added Content deleted
m (Jasmin) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 66: | Line 66: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="11l">T Splitmix64 |
||
UInt64 state |
UInt64 state |
||
Line 91: | Line 91: | ||
L 100'000 |
L 100'000 |
||
hist[Int(random_gen.next_float() * 5)]++ |
hist[Int(random_gen.next_float() * 5)]++ |
||
print(hist)</ |
print(hist)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 107: | Line 107: | ||
'''package specification:''' |
'''package specification:''' |
||
< |
<syntaxhighlight lang="ada">with Interfaces; use Interfaces; |
||
package Random_Splitmix64 is |
package Random_Splitmix64 is |
||
Line 114: | Line 114: | ||
function next_float return Float; |
function next_float return Float; |
||
procedure Set_State (Seed : in Unsigned_64); |
procedure Set_State (Seed : in Unsigned_64); |
||
end Random_Splitmix64;</ |
end Random_Splitmix64;</syntaxhighlight> |
||
'''package body:''' |
'''package body:''' |
||
< |
<syntaxhighlight lang="ada">package body Random_Splitmix64 is |
||
Internal : Unsigned_64 := 1234567; |
Internal : Unsigned_64 := 1234567; |
||
Line 151: | Line 151: | ||
end Set_State; |
end Set_State; |
||
end Random_Splitmix64;</ |
end Random_Splitmix64;</syntaxhighlight> |
||
'''Main procedure:''' |
'''Main procedure:''' |
||
< |
<syntaxhighlight lang="ada">with Interfaces; use Interfaces; |
||
with Random_Splitmix64; use Random_Splitmix64; |
with Random_Splitmix64; use Random_Splitmix64; |
||
with Ada.Text_IO; use Ada.Text_IO; |
with Ada.Text_IO; use Ada.Text_IO; |
||
Line 183: | Line 183: | ||
end Main; |
end Main; |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 200: | Line 200: | ||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
{{works with|ALGOL 68G|Any Tested with release 2.8.3.win32}} |
{{works with|ALGOL 68G|Any Tested with release 2.8.3.win32}} |
||
< |
<syntaxhighlight lang="algol68">BEGIN # generate some pseudo random numbers using Splitmix64 # |
||
# note that although LONG INT is 64 bits in Algol 68G, LONG BITS is longer than 64 bits # |
# note that although LONG INT is 64 bits in Algol 68G, LONG BITS is longer than 64 bits # |
||
LONG BITS mask 64 = LONG 16rffffffffffffffff; |
LONG BITS mask 64 = LONG 16rffffffffffffffff; |
||
Line 247: | Line 247: | ||
print( ( newline ) ) |
print( ( newline ) ) |
||
END |
END |
||
END</ |
END</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 260: | Line 260: | ||
=={{header|C}}== |
=={{header|C}}== |
||
Code copied from the reference C implementation used by Java, and using GNU GCC v7.1.1. |
Code copied from the reference C implementation used by Java, and using GNU GCC v7.1.1. |
||
< |
<syntaxhighlight lang="c">/* Written in 2015 by Sebastiano Vigna (vigna@acm.org) |
||
To the extent possible under law, the author has dedicated all copyright |
To the extent possible under law, the author has dedicated all copyright |
||
Line 306: | Line 306: | ||
printf("%d: %d ", i, vec5[i]); |
printf("%d: %d ", i, vec5[i]); |
||
} |
} |
||
</ |
</syntaxhighlight>{{out}} |
||
<pre> |
<pre> |
||
6457827717110365317 |
6457827717110365317 |
||
Line 317: | Line 317: | ||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
< |
<syntaxhighlight lang="factor">USING: io kernel math math.bitwise math.functions |
||
math.statistics namespaces prettyprint sequences ; |
math.statistics namespaces prettyprint sequences ; |
||
Line 338: | Line 338: | ||
"Seed: 987654321; first 100,000 float values histogram" print |
"Seed: 987654321; first 100,000 float values histogram" print |
||
987654321 seed 100,000 [ next-float 5 * >integer ] replicate |
987654321 seed 100,000 [ next-float 5 * >integer ] replicate |
||
histogram .</ |
histogram .</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 357: | Line 357: | ||
{{works with|gforth|0.7.3}} |
{{works with|gforth|0.7.3}} |
||
< |
<syntaxhighlight lang="forth">variable rnd-state |
||
: rnd-base-op ( z factor shift -- u ) 2 pick swap rshift rot xor * ; |
: rnd-base-op ( z factor shift -- u ) 2 pick swap rshift rot xor * ; |
||
Line 396: | Line 396: | ||
; |
; |
||
counts-fill counts-disp</ |
counts-fill counts-disp</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 413: | Line 413: | ||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
< |
<syntaxhighlight lang="fsharp">// Pure F# Implementation of SplitMix64 |
||
let a: uint64 = 0x9e3779b97f4a7c15UL |
let a: uint64 = 0x9e3779b97f4a7c15UL |
||
Line 442: | Line 442: | ||
printfn "%i" fourth |
printfn "%i" fourth |
||
printfn "%i" fifth |
printfn "%i" fifth |
||
0</ |
0</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 454: | Line 454: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 493: | Line 493: | ||
fmt.Printf(" %d : %d\n", i, counts[i]) |
fmt.Printf(" %d : %d\n", i, counts[i]) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 513: | Line 513: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">import Data.Bits |
||
import Data.Word |
import Data.Word |
||
import Data.List |
import Data.List |
||
Line 527: | Line 527: | ||
randoms = unfoldr (pure . next) |
randoms = unfoldr (pure . next) |
||
toFloat n = fromIntegral n / (2^64 - 1)</ |
toFloat n = fromIntegral n / (2^64 - 1)</syntaxhighlight> |
||
<pre>λ> mapM_ print $ take 5 $ randoms 1234567 |
<pre>λ> mapM_ print $ take 5 $ randoms 1234567 |
||
Line 542: | Line 542: | ||
=={{header|Jasmin}}== |
=={{header|Jasmin}}== |
||
<lang>u64 c1 = 0x9e3779b97f4a7c15; |
<syntaxhighlight lang="text">u64 c1 = 0x9e3779b97f4a7c15; |
||
u64 c2 = 0xbf58476d1ce4e5b9; |
u64 c2 = 0xbf58476d1ce4e5b9; |
||
u64 c3 = 0x94d049bb133111eb; |
u64 c3 = 0x94d049bb133111eb; |
||
Line 578: | Line 578: | ||
return result; |
return result; |
||
} |
} |
||
exec test(0x1000:8)</ |
exec test(0x1000:8)</syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="julia">const C1 = 0x9e3779b97f4a7c15 |
||
const C2 = 0xbf58476d1ce4e5b9 |
const C2 = 0xbf58476d1ce4e5b9 |
||
const C3 = 0x94d049bb133111eb |
const C3 = 0x94d049bb133111eb |
||
Line 616: | Line 616: | ||
testSplitmix64() |
testSplitmix64() |
||
</ |
</syntaxhighlight>{{out}} |
||
<pre> |
<pre> |
||
6457827717110365317 |
6457827717110365317 |
||
Line 627: | Line 627: | ||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">ClearAll[BitShiftLevelUint, MultiplyUint, GenerateRandomNumbers] |
||
BitShiftLevelUint[z_, n_] := BitShiftRight[z, n] |
BitShiftLevelUint[z_, n_] := BitShiftRight[z, n] |
||
MultiplyUint[z_, n_] := Mod[z n, 2^64] |
MultiplyUint[z_, n_] := Mod[z n, 2^64] |
||
Line 644: | Line 644: | ||
GenerateRandomNumbers[1234567, 5] |
GenerateRandomNumbers[1234567, 5] |
||
nums = GenerateRandomNumbers[987654321, 10^5]; |
nums = GenerateRandomNumbers[987654321, 10^5]; |
||
KeySort[Counts[Floor[5 nums/N[2^64]]]]</ |
KeySort[Counts[Floor[5 nums/N[2^64]]]]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>{6457827717110365317, 3203168211198807973, 9817491932198370423, 4593380528125082431, 16408922859458223821} |
<pre>{6457827717110365317, 3203168211198807973, 9817491932198370423, 4593380528125082431, 16408922859458223821} |
||
Line 650: | Line 650: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">import math, sequtils, strutils |
||
const Two64 = 2.0^64 |
const Two64 = 2.0^64 |
||
Line 686: | Line 686: | ||
for _ in 1..100_000: |
for _ in 1..100_000: |
||
inc counts[int(prng.nextFloat * 5)] |
inc counts[int(prng.nextFloat * 5)] |
||
echo toSeq(counts.pairs).mapIt(($it[0]) & ": " & ($it[1])).join(", "</ |
echo toSeq(counts.pairs).mapIt(($it[0]) & ": " & ($it[1])).join(", "</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 700: | Line 700: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl">use strict; |
||
use warnings; |
use warnings; |
||
no warnings 'portable'; |
no warnings 'portable'; |
||
Line 735: | Line 735: | ||
$rng = splitmix64->new(seed => 987654321); |
$rng = splitmix64->new(seed => 987654321); |
||
$h{int 5 * $rng->next_float}++ for 1 .. 100_000; |
$h{int 5 * $rng->next_float}++ for 1 .. 100_000; |
||
say "$_ $h{$_}" for sort keys %h;</ |
say "$_ $h{$_}" for sort keys %h;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Seed: 1234567, first 5 values: |
<pre>Seed: 1234567, first 5 values: |
||
Line 753: | Line 753: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
As per [[Pseudo-random_numbers/PCG32#Phix]], resorting to mpfr/gmp |
As per [[Pseudo-random_numbers/PCG32#Phix]], resorting to mpfr/gmp |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> |
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> |
||
Line 804: | Line 804: | ||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
<span style="color: #0000FF;">?</span><span style="color: #000000;">r</span> |
<span style="color: #0000FF;">?</span><span style="color: #000000;">r</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 816: | Line 816: | ||
=={{header|Object Pascal}}== |
=={{header|Object Pascal}}== |
||
<syntaxhighlight lang="pascal"> |
|||
<lang Pascal> |
|||
program splitmix64; |
program splitmix64; |
||
Line 894: | Line 894: | ||
Write(i, ': ', vec[i], ' '); |
Write(i, ': ', vec[i], ' '); |
||
end. |
end. |
||
</ |
</syntaxhighlight>{{out}} |
||
<pre> |
<pre> |
||
6457827717110365317 |
6457827717110365317 |
||
Line 905: | Line 905: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(zero *Split) # global state |
||
(de mod64 (N) |
(de mod64 (N) |
||
Line 937: | Line 937: | ||
(roundf (* 5 (*/ (nextSplit) 1.0 18446744073709551616))) |
(roundf (* 5 (*/ (nextSplit) 1.0 18446744073709551616))) |
||
1 ) ) |
1 ) ) |
||
(mapc println (sort R))</ |
(mapc println (sort R))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 956: | Line 956: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang="python">MASK64 = (1 << 64) - 1 |
||
C1 = 0x9e3779b97f4a7c15 |
C1 = 0x9e3779b97f4a7c15 |
||
C2 = 0xbf58476d1ce4e5b9 |
C2 = 0xbf58476d1ce4e5b9 |
||
Line 995: | Line 995: | ||
for i in range(100_000): |
for i in range(100_000): |
||
hist[int(random_gen.next_float() *5)] += 1 |
hist[int(random_gen.next_float() *5)] += 1 |
||
print(hist)</ |
print(hist)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,008: | Line 1,008: | ||
{{works with|Rakudo|2020.07}} |
{{works with|Rakudo|2020.07}} |
||
<lang |
<syntaxhighlight lang="raku" line>class splitmix64 { |
||
has $!state; |
has $!state; |
||
Line 1,032: | Line 1,032: | ||
say "\nSeed: 987654321; first 1e5 Rat values histogram"; |
say "\nSeed: 987654321; first 1e5 Rat values histogram"; |
||
$rng = splitmix64.new( :seed(987654321) ); |
$rng = splitmix64.new( :seed(987654321) ); |
||
say ( ($rng.next-rat * 5).floor xx 100_000 ).Bag;</ |
say ( ($rng.next-rat * 5).floor xx 100_000 ).Bag;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Seed: 1234567; first five Int values |
<pre>Seed: 1234567; first five Int values |
||
Line 1,045: | Line 1,045: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program generates pseudo─random numbers using the split mix 64 bit method.*/ |
||
numeric digits 200 /*ensure enough decimal digs for mult. */ |
numeric digits 200 /*ensure enough decimal digs for mult. */ |
||
parse arg n reps pick seed1 seed2 . /*obtain optional arguments from the CL*/ |
parse arg n reps pick seed1 seed2 . /*obtain optional arguments from the CL*/ |
||
Line 1,095: | Line 1,095: | ||
xor: parse arg a, b; $= /*perform a bit─wise XOR. */ |
xor: parse arg a, b; $= /*perform a bit─wise XOR. */ |
||
do !=1 for length(a); $= $ || (substr(a,!,1) && substr(b,!,1) ) |
do !=1 for length(a); $= $ || (substr(a,!,1) && substr(b,!,1) ) |
||
end /*!*/; return $</ |
end /*!*/; return $</syntaxhighlight> |
||
{{out|output|text= when using the default inputs:}} |
{{out|output|text= when using the default inputs:}} |
||
<pre> |
<pre> |
||
Line 1,116: | Line 1,116: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
< |
<syntaxhighlight lang="ruby">class Splitmix64 |
||
MASK64 = (1 << 64) - 1 |
MASK64 = (1 << 64) - 1 |
||
C1, C2, C3 = 0x9e3779b97f4a7c15, 0xbf58476d1ce4e5b9, 0x94d049bb133111eb |
C1, C2, C3 = 0x9e3779b97f4a7c15, 0xbf58476d1ce4e5b9, 0x94d049bb133111eb |
||
Line 1,138: | Line 1,138: | ||
rand_gen = Splitmix64.new(987654321) |
rand_gen = Splitmix64.new(987654321) |
||
p 100_000.times.lazy.map{(rand_gen.rand_f * 5).floor}.tally.sort.to_h |
p 100_000.times.lazy.map{(rand_gen.rand_f * 5).floor}.tally.sort.to_h |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>6457827717110365317 |
<pre>6457827717110365317 |
||
Line 1,149: | Line 1,149: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
< |
<syntaxhighlight lang="ruby">class Splitmix64(state) { |
||
define ( |
define ( |
||
Line 1,174: | Line 1,174: | ||
var rng = Splitmix64(987654321) |
var rng = Splitmix64(987654321) |
||
var histogram = Bag(1e5.of { floor(5*rng.next_float) }...) |
var histogram = Bag(1e5.of { floor(5*rng.next_float) }...) |
||
histogram.pairs.sort.each { .join(": ").say }</ |
histogram.pairs.sort.each { .join(": ").say }</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,195: | Line 1,195: | ||
{{libheader|Wren-big}} |
{{libheader|Wren-big}} |
||
No 64 bit integers so we use BigInt with a mask. |
No 64 bit integers so we use BigInt with a mask. |
||
< |
<syntaxhighlight lang="ecmascript">import "/big" for BigInt |
||
var Const1 = BigInt.fromBaseString("9e3779b97f4a7c15", 16) |
var Const1 = BigInt.fromBaseString("9e3779b97f4a7c15", 16) |
||
Line 1,228: | Line 1,228: | ||
} |
} |
||
System.print("\nThe counts for 100,000 repetitions are:") |
System.print("\nThe counts for 100,000 repetitions are:") |
||
for (i in 0..4) System.print(" %(i) : %(counts[i])")</ |
for (i in 0..4) System.print(" %(i) : %(counts[i])")</syntaxhighlight> |
||
{{out}} |
{{out}} |