1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // PCG32 / (c) 2014 M.E. O'Neill / pcg-random.org
18 // Original code: Licensed under Apache License 2.0 (NO WARRANTY, etc. see website)
19 module iv
.prng
.pcg32
/*is aliced*/;
27 ulong state
= 0x83a6d64d022268cdUL
; // current state: PCG32 iterates through all 2^^64 possible internal states
28 ulong inc = 0x00000055UL
; // sequence constant: a value that defines which of 2^^63 possible random sequences the current state is iterating through; it holds the same value over the lifetime of the PCG32
30 uint s
= 0xe1ad5be5UL
;
33 pure nothrow @trusted @nogc:
34 enum bool isUniformRandom
= true;
36 enum uint max
= 0xffff_ffffu
; // 32 bits
38 enum bool empty
= false;
40 // seed the rng: specified in two parts, state initializer and a sequence selection constant (a.k.a. stream id)
41 this (ulong initstate
, ulong initseq
=42) { pragma(inline
, true); seed(initstate
, initseq
); }
43 private this() (in auto ref PCG32 src
) { pragma(inline
, true); state
= src
.state
; inc = src
.inc; s
= src
.s
; }
45 @property uint front () const { pragma(inline
, true); return s
; }
47 auto save () const { pragma(inline
, true); return PCG32(this); }
50 immutable ulong oldstate
= state
;
51 // advance internal state
52 state
= oldstate
*6364136223846793005UL+(inc|
1);
53 // calculate output function (XSH RR), uses old state for max ILP
54 immutable uint xorshifted
= cast(uint)(((oldstate
>>18u)^oldstate
)>>27u);
55 immutable uint rot
= oldstate
>>59u;
56 s
= (xorshifted
>>rot
)|
(xorshifted
<<((-rot
)&31));
59 // seed the rng: specified in two parts, state initializer and a sequence selection constant (a.k.a. stream id)
60 void seed (ulong initstate
, ulong initseq
) {
62 inc = (initseq
<<1u)|
1u;
72 version(test_pcg32
) unittest {
73 static immutable uint[8] checkValues
= [
85 auto rng = PCG32(0x29a);
87 writefln("ulong state = 0x%08xUL;", rng.state);
88 writefln("ulong inc = 0x%08xUL;", rng.inc);
89 writefln("uint s = 0x%08xUL;", rng.s);
94 foreach (uint v
; checkValues
) {
95 if (v
!= rng
.front
) assert(0);
96 //import std.stdio; writeln(rng.front, "u,");
102 import std
.random
: uniform
;
104 foreach (immutable _
; 0..8) {
106 auto v
= uniform
!"[)"(0, 4, rng
);
114 // *Really* minimal PCG32 code / (c) 2014 M.E. O'Neill / pcg-random.org
115 // Licensed under Apache License 2.0 (NO WARRANTY, etc. see website)
117 struct pcg32_random_t { ulong state, inc; }
119 uint pcg32_random_r (ref pcg32_random_t rng) {
120 ulong oldstate = rng.state;
121 // advance internal state
122 rng.state = oldstate*6364136223846793005UL+(rng.inc|1);
123 // calculate output function (XSH RR), uses old state for max ILP
124 immutable uint xorshifted = ((oldstate>>18u)^oldstate)>>27u;
125 immutable uint rot = oldstate>>59u;
126 return (xorshifted>>rot)|(xorshifted<<((-rot)&31));
129 // pcg32_srandom_r(rng, initstate, initseq):
130 // Seed the rng. Specified in two parts, state initializer and a
131 // sequence selection constant (a.k.a. stream id)
132 void pcg32_srandom_r (ref pcg32_random_t rng, ulong initstate, ulong initseq) {
134 rng.inc = (initseq<<1u)|1u;
136 rng.state += initstate;