Mercurial > projects > ldc
diff tango/tango/math/Random.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tango/tango/math/Random.d Fri Jan 11 17:57:40 2008 +0100 @@ -0,0 +1,178 @@ +/******************************************************************************* + + copyright: Copyright (c) 2004. All rights reserved + + license: BSD style: $(LICENSE) + + version: Initial release: April 2004 + + author: Various + +*******************************************************************************/ + +module tango.math.Random; + + +version (Win32) + private extern(Windows) int QueryPerformanceCounter (ulong *); + +version (Posix) + { + private import tango.stdc.posix.sys.time; + } + + +/****************************************************************************** + + KISS (via George Marsaglia & Paul Hsieh) + + the idea is to use simple, fast, individually promising + generators to get a composite that will be fast, easy to code + have a very long period and pass all the tests put to it. + The three components of KISS are + + x(n)=a*x(n-1)+1 mod 2^32 + y(n)=y(n-1)(I+L^13)(I+R^17)(I+L^5), + z(n)=2*z(n-1)+z(n-2) +carry mod 2^32 + + The y's are a shift register sequence on 32bit binary vectors + period 2^32-1; The z's are a simple multiply-with-carry sequence + with period 2^63+2^32-1. + + The period of KISS is thus 2^32*(2^32-1)*(2^63+2^32-1) > 2^127 + +******************************************************************************/ + +class Random +{ + /********************************************************************** + + Shared instance: + --- + auto random = Random.shared.next; + --- + + **********************************************************************/ + public static Random shared; + + private uint kiss_k; + private uint kiss_m; + private uint kiss_x = 1; + private uint kiss_y = 2; + private uint kiss_z = 4; + private uint kiss_w = 8; + private uint kiss_carry = 0; + + /********************************************************************** + + Create a static and shared instance: + --- + auto random = Random.shared.next; + --- + + **********************************************************************/ + + static this () + { + shared = new Random; + } + + /********************************************************************** + + Creates and seeds a new generator with the current time + + **********************************************************************/ + + this () + { + this.seed; + } + + /********************************************************************** + + Seed the generator with current time + + **********************************************************************/ + + final Random seed () + { + ulong s; + + version (Posix) + { + timeval tv; + + gettimeofday (&tv, null); + s = tv.tv_usec; + } + version (Win32) + QueryPerformanceCounter (&s); + + return seed (cast(uint) s); + } + + /********************************************************************** + + Seed the generator with a provided value + + **********************************************************************/ + + final Random seed (uint seed) + { + kiss_x = seed | 1; + kiss_y = seed | 2; + kiss_z = seed | 4; + kiss_w = seed | 8; + kiss_carry = 0; + return this; + } + + /********************************************************************** + + Returns X such that 0 <= X <= uint.max + + **********************************************************************/ + + final uint next () + { + kiss_x = kiss_x * 69069 + 1; + kiss_y ^= kiss_y << 13; + kiss_y ^= kiss_y >> 17; + kiss_y ^= kiss_y << 5; + kiss_k = (kiss_z >> 2) + (kiss_w >> 3) + (kiss_carry >> 2); + kiss_m = kiss_w + kiss_w + kiss_z + kiss_carry; + kiss_z = kiss_w; + kiss_w = kiss_m; + kiss_carry = kiss_k >> 30; + return kiss_x + kiss_y + kiss_w; + } + + /********************************************************************** + + Returns X such that 0 <= X < max + + Note that max is exclusive, making it compatible with + array indexing + + **********************************************************************/ + + final uint next (uint max) + { + return next() % max; + } + + /********************************************************************** + + Returns X such that min <= X < max + + Note that max is exclusive, making it compatible with + array indexing + + **********************************************************************/ + + final uint next (uint min, uint max) + { + return next(max-min) + min; + } +} +