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, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 module iv
.prng
.bj
/*is aliced*/;
22 // ////////////////////////////////////////////////////////////////////////// //
25 // http://burtleburtle.net/bob/rand/smallprng.html
28 // seeded with 0xdeadf00du
36 void randomize () @trusted {
38 import win32
.windef
, win32
.winbase
;
39 uint s0
= xyzzyPRNGHashU32(cast(uint)GetCurrentProcessId());
40 uint s1
= xyzzyPRNGHashU32(cast(uint)GetTickCount());
44 import core
.sys
.posix
.fcntl
;
45 import core
.sys
.posix
.unistd
;
46 uint s0
= 0xdeadf00du
;
47 int fd
= open("/dev/urandom", O_RDONLY
);
49 read(fd
, &s0
, s0
.sizeof
);
57 enum bool isUniformRandom
= true;
58 enum uint min
= uint.min
;
59 enum uint max
= uint.max
;
61 enum bool empty
= false;
62 @property uint front () const { pragma(inline
, true); return d
; }
63 alias popFront
= next
;
64 @property auto save () const { BJRng res
= void; res
.a
= this.a
; res
.b
= this.b
; res
.c
= this.c
; res
.d
= this.d
; return res
; }
66 this (uint aseed
) { pragma(inline
, true); seed(aseed
); }
68 void seed (uint seed
) {
71 foreach (immutable _
; 0..20) next
;
74 @property uint next () {
75 enum ROT(string var
, string cnt
) = `cast(uint)(((`~var
~`)<<(`~cnt
~`))|((`~var
~`)>>(32-(`~cnt
~`))))`;
78 e = a-BJPRNG_ROT(b, 27);
79 a = b^BJPRNG_ROT(c, 17);
84 /* better, but slower at least in idiotic m$vc */
85 e
= a
-mixin(ROT
!("b", "23"));
86 a
= b^
mixin(ROT
!("c", "16"));
87 b
= c
+mixin(ROT
!("d", "11"));
95 version(test_bj
) unittest {
96 static immutable uint[8] checkValues
= [
108 foreach (ulong v
; checkValues
) {
109 if (v
!= rng
.front
) assert(0);
110 //import std.stdio; writeln(rng.front, "u");
116 import std
.random
: uniform
;
118 foreach (immutable _
; 0..8) {
120 auto v
= uniform
!"[)"(0, 4, rng
);
127 // ////////////////////////////////////////////////////////////////////////// //
128 // One of the by George Marsaglia's prng generators.
129 // It is based on George Marsaglia's MWC (multiply with carry) generator.
130 // Although it is very simple, it passes Marsaglia's DIEHARD series of random
131 // number generator tests.
134 // These values are not magical, just the default values Marsaglia used.
135 // Any pair of unsigned integers should be fine.
136 enum uint DefaultW
= 521288629u;
137 enum uint DefaultZ
= 362436069u;
141 uint lastnum
= (DefaultZ
<<16)+DefaultW
;
145 void randomize () @trusted {
147 import win32
.windef
, win32
.winbase
;
148 w
= xyzzyPRNGHashU32(cast(uint)GetCurrentProcessId());
149 z
= xyzzyPRNGHashU32(cast(uint)GetTickCount());
152 import core
.sys
.posix
.fcntl
;
153 import core
.sys
.posix
.unistd
;
156 int fd
= open("/dev/urandom", O_RDONLY
);
158 read(fd
, &w
, w
.sizeof
);
159 read(fd
, &z
, z
.sizeof
);
166 enum bool isUniformRandom
= true;
167 enum uint min
= uint.min
;
168 enum uint max
= uint.max
;
170 enum bool empty
= false;
171 @property uint front () const { pragma(inline
, true); return lastnum
; }
172 alias popFront
= next
;
173 @property auto save () const { GMRngSeed64 res
= void; res
.w
= this.w
; res
.z
= this.z
; res
.lastnum
= this.lastnum
; return res
; }
175 this (ulong aseed
) { pragma(inline
, true); seed(aseed
); }
177 void seed (ulong seed
) {
178 z
= cast(uint)(seed
>>32);
179 w
= cast(uint)(seed
&0xffffffffu
);
180 if (w
== 0) w
= DefaultW
;
181 if (z
== 0) z
= DefaultZ
;
185 @property uint next () {
186 if (w
== 0) w
= DefaultW
;
187 if (z
== 0) z
= DefaultZ
;
188 z
= 36969*(z
&0xffff)+(z
>>16);
189 w
= 18000*(w
&0xffff)+(w
>>16);
190 return (lastnum
= (z
<<16)+w
);
194 version(test_gms64
) unittest {
195 static immutable uint[8] checkValues
= [
206 auto rng
= GMRngSeed64(0);
207 foreach (ulong v
; checkValues
) {
208 if (v
!= rng
.front
) assert(0);
209 //import std.stdio; writeln(rng.front, "u");
215 import std
.random
: uniform
;
216 auto rng
= GMRngSeed64(0);
217 foreach (immutable _
; 0..8) {
219 auto v
= uniform
!"[)"(0, 4, rng
);
226 // ////////////////////////////////////////////////////////////////////////// //
227 // one of the by George Marsaglia's prng generators, period about 2^160. fast.
230 // seeded with 0xdeadf00du
231 uint x
= 0xdeadf00du
;
232 uint y
= 0xe3324aa1u
;
233 uint z
= 0x7ed1c277u
;
234 uint w
= 0x89574524u
;
235 uint v
= 0x359c34a7u
;
236 uint lastnum
= 0x4d00381eu
; // almost arbitrary
240 void randomize () @trusted {
242 import win32
.windef
, win32
.winbase
;
244 s0
[0] = xyzzyPRNGHashU32(cast(uint)GetCurrentProcessId());
245 s0
[1] = xyzzyPRNGHashU32(cast(uint)GetTickCount());
249 import core
.sys
.posix
.fcntl
;
250 import core
.sys
.posix
.unistd
;
252 int fd
= open("/dev/urandom", O_RDONLY
);
254 read(fd
, s0
.ptr
, s0
.sizeof
);
262 enum bool isUniformRandom
= true;
263 enum uint min
= uint.min
;
264 enum uint max
= uint.max
;
266 enum bool empty
= false;
267 @property uint front () const { pragma(inline
, true); return lastnum
; }
268 alias popFront
= next
;
269 @property auto save () const { GMRng res
= void; res
.x
= this.x
; res
.y
= this.y
; res
.z
= this.z
; res
.w
= this.w
; res
.v
= this.v
; res
.lastnum
= this.lastnum
; return res
; }
271 this (uint aseed
) { pragma(inline
, true); seed(aseed
); }
273 void seed (uint seed
) {
274 x
= (seed ? seed
: 0xdeadf00du
);
275 y
= xyzzyPRNGHashU32(x
+1);
276 z
= xyzzyPRNGHashU32(y
+1);
277 w
= xyzzyPRNGHashU32(z
+1);
278 v
= xyzzyPRNGHashU32(w
+1);
282 void seed (uint s0
, uint s1
, uint s2
, uint s3
, uint s4
) {
288 if (x
== 0) x
= 0xdeadf00du
;
289 if (y
== 0) y
= xyzzyPRNGHashU32(x
+1);
290 if (z
== 0) z
= xyzzyPRNGHashU32(y
+1);
291 if (w
== 0) w
= xyzzyPRNGHashU32(z
+1);
292 if (v
== 0) v
= xyzzyPRNGHashU32(w
+1);
296 void seed (in uint[] seed
) {
297 x
= (seed
.length
> 0 ? seed
[0] : 0xdeadf00du
);
298 y
= (seed
.length
> 1 ? seed
[1] : xyzzyPRNGHashU32(x
+1));
299 z
= (seed
.length
> 2 ? seed
[2] : xyzzyPRNGHashU32(y
+1));
300 w
= (seed
.length
> 3 ? seed
[3] : xyzzyPRNGHashU32(z
+1));
301 v
= (seed
.length
> 4 ? seed
[4] : xyzzyPRNGHashU32(w
+1));
302 if (x
== 0) x
= 0xdeadf00du
;
303 if (y
== 0) y
= xyzzyPRNGHashU32(x
+1);
304 if (z
== 0) z
= xyzzyPRNGHashU32(y
+1);
305 if (w
== 0) w
= xyzzyPRNGHashU32(z
+1);
306 if (v
== 0) v
= xyzzyPRNGHashU32(w
+1);
310 @property uint next () {
317 v
= (v^
(v
<<6))^
(t^
(t
<<13));
318 return (lastnum
= (y
+y
+1)*v
);
322 version(test_gms
) unittest {
323 static immutable uint[8] checkValues
= [
335 foreach (ulong v
; checkValues
) {
336 if (v
!= rng
.front
) assert(0);
337 //import std.stdio; writeln(rng.front, "u");
343 import std
.random
: uniform
;
345 foreach (immutable _
; 0..8) {
347 auto v
= uniform
!"[)"(0, 4, rng
);
354 // ////////////////////////////////////////////////////////////////////////// //
355 version(test_prng
) unittest {
357 template checkRng(T
) {
358 static assert(isInfinite
!T
, T
.stringof
~" is not infinite range");
359 static assert(isInputRange
!T
, T
.stringof
~" is not inpute range");
360 static assert(isForwardRange
!T
, T
.stringof
~" is not forward range");
361 enum checkRng
= true;
363 static assert(checkRng
!BJRng
);
364 static assert(checkRng
!GMRngSeed64
);
365 static assert(checkRng
!GMRng
);
369 // ////////////////////////////////////////////////////////////////////////// //
370 private uint xyzzyPRNGHashU32() (uint a
) {