Mercurial > projects > ldc
view tango/tango/math/Random.d @ 341:1bb99290e03a trunk
[svn r362] Started merging the old 'test' dir as well as the newer 'tangotests' dir into 'tests/mini' and 'tests/minicomplex'.
author | lindquist |
---|---|
date | Sun, 13 Jul 2008 02:51:19 +0200 |
parents | 1700239cab2e |
children |
line wrap: on
line source
/******************************************************************************* 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; } }