Pseudo-random numbers/Xorshift star: Difference between revisions
Pseudo-random numbers/Xorshift star (view source)
Revision as of 11:51, 29 January 2024
, 3 months agoAdd Rust implementation
(Add Swift) |
(Add Rust implementation) |
||
(4 intermediate revisions by 4 users not shown) | |||
Line 27:
/* Let u64 denote an unsigned 64 bit integer type. */
/* Let u32 denote an unsigned 32 bit integer type. */
class Xorshift_star
u64 state /* Must be seeded to non-zero initial value */
u64 const = HEX '2545F4914F6CDD1D'
method seed(u64 num):
state = num
Line 87 ⟶ 86:
{{trans|Python}}
<
UInt64 state
Line 113 ⟶ 112:
L 100'000
hist[Int(random_gen.next_float() * 5)]++
print(hist)</
{{out}}
Line 127 ⟶ 126:
=={{header|Ada}}==
Raises Unseeded_Error exception if state is not initialized before generating a pseudo-random value.
<
with Ada.Text_IO; use Ada.Text_IO;
Line 179 ⟶ 178:
end Main;
</syntaxhighlight>
{{output}}
<pre>
Line 198 ⟶ 197:
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}}
Will generate a runtime error if state is not initialised before use.
<
# note that although LONG INT is 64 bits in Algol 68G, LONG BITS is longer than 64 bits #
LONG BITS state;
Line 236 ⟶ 235:
print( ( newline ) )
END
END</
{{out}}
<pre>
Line 248 ⟶ 247:
=={{header|C}}==
<
#include <stdint.h>
#include <stdio.h>
Line 299 ⟶ 298:
return 0;
}</
{{out}}
<pre>3540625527
Line 315 ⟶ 314:
=={{header|C++}}==
{{trans|C}}
<
#include <cstdint>
#include <iostream>
Line 368 ⟶ 367:
return 0;
}</
{{out}}
<pre>3540625527
Line 384 ⟶ 383:
=={{header|D}}==
{{trans|C++}}
<
import std.stdio;
Line 433 ⟶ 432:
writeln(i, ": ", v);
}
}</
{{out}}
<pre>3540625527
Line 451 ⟶ 450:
{{libheader| System.Math}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
program Xorshift_star;
Line 523 ⟶ 522:
{$IFNDEF UNIX} Readln; {$ENDIF}
end.</
=={{header|F_Sharp|F#}}==
===The Functions===
<
// Xorshift star. Nigel Galloway: August 14th., 2020
let fN=(fun(n:uint64)->n^^^(n>>>12))>>(fun n->n^^^(n<<<25))>>(fun n->n^^^(n>>>27))
let Xstar32=Seq.unfold(fun n->let n=fN n in Some(uint32((n*0x2545F4914F6CDD1DUL)>>>32),n))
let XstarF n=Xstar32 n|>Seq.map(fun n->(float n)/4294967296.0)
</syntaxhighlight>
===The Tasks===
<
Xstar32 1234567UL|>Seq.take 5|>Seq.iter(printfn "%d")
</syntaxhighlight>
{{out}}
<pre>
Line 545 ⟶ 544:
3809424708
</pre>
<
XstarF 987654321UL|>Seq.take 100000|>Seq.countBy(fun n->int(n*5.0))|>Seq.iter(printf "%A");printfn ""
</syntaxhighlight>
{{out}}
<pre>
Line 554 ⟶ 553:
=={{header|Factor}}==
<
prettyprint sequences ;
Line 584 ⟶ 583:
987654321 >>state
100,000 [ dup next-float 5 * >integer ] replicate nip
histogram .</
{{out}}
<pre>
Line 597 ⟶ 596:
=={{header|Go}}==
{{trans|Python}}
<
import (
Line 641 ⟶ 640:
fmt.Printf(" %d : %d\n", i, counts[i])
}
}</
{{out}}
Line 658 ⟶ 657:
4 : 20007
</pre>
=={{header|Haskell}}==
Implement given algorithm as an instance of <code>RandomGen</code> class.
<syntaxhighlight lang="haskell">import Data.Bits
import Data.Word
import System.Random
import Data.List
newtype XorShift = XorShift Word64
instance RandomGen XorShift where
next (XorShift state) = (out newState, XorShift newState)
where
newState = (\z -> z `xor` (z `shiftR` 27)) .
(\z -> z `xor` (z `shiftL` 25)) .
(\z -> z `xor` (z `shiftR` 12)) $ state
out x = fromIntegral $ (x * 0x2545f4914f6cdd1d) `shiftR` 32
split _ = error "XorShift is not splittable"
randoms' :: RandomGen g => g -> [Int]
randoms' = unfoldr (pure . next)
toFloat n = fromIntegral n / (2^32 - 1)</syntaxhighlight>
Direct usage of generator:
<pre>*Main> mapM_ print $ take 5 $ randoms' (XorShift 1234567)
3540625527
2750739987
4037983143
1993361440
3809424708
*Main> let hist = map length . group . sort
*Main> hist . take 100000 $ (floor . (*5) . toFloat) <$> (randoms' (XorShift 987654321))
[20103,19922,19937,20031,20007]</pre>
Using <code>Random</code> class gives different results due to internal shuffling:
<pre>*Main> mapM_ print $ take 5 $ randoms (XorShift 1234567)
2750739987
1993361440
1794978290
626183142
2911384526
*Main> let hist = map length . group . sort
*Main> hist . take 100000 $ (floor . (*5)) <$> (randoms (XorShift 987654321) :: [Float])
[20263,19783,19949,19957,20048]</pre>
=={{header|Java}}==
{{trans|C++}}
<
private static final long MAGIC = Long.parseUnsignedLong("2545F4914F6CDD1D", 16);
private long state;
Line 707 ⟶ 757:
}
}
}</
{{out}}
<pre>3540625527
Line 723 ⟶ 773:
=={{header|Julia}}==
{{trans|Python}}
<
const CONST = 0x2545F4914F6CDD1D
Line 760 ⟶ 810:
testXorShiftStar()
</
<pre>
3540625527
Line 772 ⟶ 822:
=={{header|Kotlin}}==
{{trans|Java}}
<
class XorShiftStar {
Line 820 ⟶ 870:
println("${iv.index}: ${iv.value}")
}
}</
{{out}}
<pre>3540625527
Line 836 ⟶ 886:
=={{header|Lua}}==
{{trans|C}}
<
local g = {
magic = 0x2545F4914F6CDD1D,
Line 876 ⟶ 926:
for i,v in pairs(counts) do
print(i..': '..v)
end</
{{out}}
<pre>3540625527
Line 891 ⟶ 941:
=={{header|Nim}}==
<
const C = 0x2545F4914F6CDD1Du64
Line 927 ⟶ 977:
for _ in 1..100_000:
counts.inc int(gen.nextFloat() * 5)
echo sorted(toSeq(counts.pairs)).mapIt($it[0] & ": " & $it[1]).join(", ")</
{{out}}
Line 939 ⟶ 989:
=={{header|Perl}}==
<
use warnings;
no warnings 'portable';
Line 976 ⟶ 1,026:
$rng = Xorshift_star->new(seed => 987654321);
$h{int 5 * $rng->next_float}++ for 1 .. 100_000;
say "$_ $h{$_}" for sort keys %h;</
{{out}}
<pre>Seed: 1234567, first 5 values:
Line 995 ⟶ 1,045:
As per [[Pseudo-random_numbers/PCG32#Phix]], resorting to mpfr/gmp
{{libheader|Phix/mpfr}}
<!--<
<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>
Line 1,040 ⟶ 1,090:
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">r</span>
<!--</
{{out}}
<pre>
Line 1,052 ⟶ 1,102:
=={{header|Python}}==
<
mask32 = (1 << 32) - 1
const = 0x2545F4914F6CDD1D
Line 1,091 ⟶ 1,141:
for i in range(100_000):
hist[int(random_gen.next_float() *5)] += 1
print(hist)</
{{out}}
Line 1,107 ⟶ 1,157:
Raku does not have unsigned Integers at this time (Integers are arbitrary sized) so use explicit bit masks during bitwise operations. All constants are encapsulated inside the class.
<syntaxhighlight lang="raku"
has $!state;
Line 1,137 ⟶ 1,187:
say "\nSeed: default; first five Int values";
$rng = Xorshift-star.new;
.say for $rng.next-int xx 5;</
{{out}}
<pre>Seed: 1234567; first five Int values
Line 1,158 ⟶ 1,208:
=={{header|REXX}}==
<
numeric digits 200 /*ensure enough decimal digs for mult. */
parse arg n reps pick seed1 seed2 . /*obtain optional arguments from the CL*/
Line 1,207 ⟶ 1,257:
xor: parse arg a, b; $= /*perform a bit─wise XOR. */
do !=1 for length(a); $= $ || (substr(a,!,1) && substr(b,!,1) )
end /*!*/; return $</
{{out|output|text= when using the default inputs:}}
<pre>
Line 1,229 ⟶ 1,279:
=={{header|Ruby}}==
Using Ruby 3.0 end-les method def:
<
MASK64 = (1 << 64) - 1
MASK32 = (1 << 32) - 1
Line 1,254 ⟶ 1,304:
tally = Hash.new(0)
100_000.times{ tally[(random_gen.next_float*5).floor] += 1 }
puts tally.sort.map{|ar| ar.join(": ") }</
{{out}}
<pre>
Line 1,268 ⟶ 1,318:
4: 20007
</pre>
=={{header|Rust}}==
{{trans|C++}}
<syntaxhighlight lang="Rust">
struct XorShiftStar {
magic: u64,
state: u64,
}
impl XorShiftStar {
fn new() -> Self {
Self {
magic: 0x2545_F491_4F6C_DD1D,
state: 0,
}
}
fn seed(&mut self, num: u64) {
self.state = num;
}
fn next_int(&mut self) -> u32 {
let mut x = self.state;
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
self.state = x;
((x.wrapping_mul(self.magic)) >> 32) as u32
}
fn next_float(&mut self) -> f32 {
self.next_int() as f32 / (1u64 << 32) as f32
}
}
fn main() {
let mut rng = XorShiftStar::new();
rng.seed(1234567);
println!("{}", rng.next_int());
println!("{}", rng.next_int());
println!("{}", rng.next_int());
println!("{}", rng.next_int());
println!("{}", rng.next_int());
println!();
let mut counts = [0; 5];
rng.seed(987654321);
for _ in 0..100000 {
let j = (rng.next_float() * 5.0).floor() as usize;
counts[j] += 1;
}
for (i, count) in counts.iter().enumerate() {
println!("{}: {}", i, count);
}
}
</syntaxhighlight>
{{out}}
<pre>
3540625527
2750739987
4037983143
1993361440
3809424708
0: 20103
1: 19922
2: 19937
3: 20031
4: 20007
</pre>
=={{header|Sidef}}==
{{trans|Perl}}
<
define (
Line 1,297 ⟶ 1,418:
var rng = Xorshift_star(987654321)
var histogram = Bag(1e5.of { floor(5*rng.next_float) }...)
histogram.pairs.sort.each { .join(": ").say }</
{{out}}
<pre>
Line 1,313 ⟶ 1,434:
=={{header|Swift}}==
<
struct XorshiftStar {
Line 1,357 ⟶ 1,478:
}
print(counts)</
{{out}}
Line 1,372 ⟶ 1,493:
{{libheader|Wren-big}}
As Wren doesn't have a 64-bit integer type, we use BigInt instead.
<
var Const = BigInt.fromBaseString("2545F4914F6CDD1D", 16)
Line 1,407 ⟶ 1,528:
}
System.print("\nThe counts for 100,000 repetitions are:")
for (i in 0..4) System.print(" %(i) : %(counts[i])")</
{{out}}
|