Mercurial > projects > ldc
comparison 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 |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 /******************************************************************************* | |
2 | |
3 copyright: Copyright (c) 2004. All rights reserved | |
4 | |
5 license: BSD style: $(LICENSE) | |
6 | |
7 version: Initial release: April 2004 | |
8 | |
9 author: Various | |
10 | |
11 *******************************************************************************/ | |
12 | |
13 module tango.math.Random; | |
14 | |
15 | |
16 version (Win32) | |
17 private extern(Windows) int QueryPerformanceCounter (ulong *); | |
18 | |
19 version (Posix) | |
20 { | |
21 private import tango.stdc.posix.sys.time; | |
22 } | |
23 | |
24 | |
25 /****************************************************************************** | |
26 | |
27 KISS (via George Marsaglia & Paul Hsieh) | |
28 | |
29 the idea is to use simple, fast, individually promising | |
30 generators to get a composite that will be fast, easy to code | |
31 have a very long period and pass all the tests put to it. | |
32 The three components of KISS are | |
33 | |
34 x(n)=a*x(n-1)+1 mod 2^32 | |
35 y(n)=y(n-1)(I+L^13)(I+R^17)(I+L^5), | |
36 z(n)=2*z(n-1)+z(n-2) +carry mod 2^32 | |
37 | |
38 The y's are a shift register sequence on 32bit binary vectors | |
39 period 2^32-1; The z's are a simple multiply-with-carry sequence | |
40 with period 2^63+2^32-1. | |
41 | |
42 The period of KISS is thus 2^32*(2^32-1)*(2^63+2^32-1) > 2^127 | |
43 | |
44 ******************************************************************************/ | |
45 | |
46 class Random | |
47 { | |
48 /********************************************************************** | |
49 | |
50 Shared instance: | |
51 --- | |
52 auto random = Random.shared.next; | |
53 --- | |
54 | |
55 **********************************************************************/ | |
56 public static Random shared; | |
57 | |
58 private uint kiss_k; | |
59 private uint kiss_m; | |
60 private uint kiss_x = 1; | |
61 private uint kiss_y = 2; | |
62 private uint kiss_z = 4; | |
63 private uint kiss_w = 8; | |
64 private uint kiss_carry = 0; | |
65 | |
66 /********************************************************************** | |
67 | |
68 Create a static and shared instance: | |
69 --- | |
70 auto random = Random.shared.next; | |
71 --- | |
72 | |
73 **********************************************************************/ | |
74 | |
75 static this () | |
76 { | |
77 shared = new Random; | |
78 } | |
79 | |
80 /********************************************************************** | |
81 | |
82 Creates and seeds a new generator with the current time | |
83 | |
84 **********************************************************************/ | |
85 | |
86 this () | |
87 { | |
88 this.seed; | |
89 } | |
90 | |
91 /********************************************************************** | |
92 | |
93 Seed the generator with current time | |
94 | |
95 **********************************************************************/ | |
96 | |
97 final Random seed () | |
98 { | |
99 ulong s; | |
100 | |
101 version (Posix) | |
102 { | |
103 timeval tv; | |
104 | |
105 gettimeofday (&tv, null); | |
106 s = tv.tv_usec; | |
107 } | |
108 version (Win32) | |
109 QueryPerformanceCounter (&s); | |
110 | |
111 return seed (cast(uint) s); | |
112 } | |
113 | |
114 /********************************************************************** | |
115 | |
116 Seed the generator with a provided value | |
117 | |
118 **********************************************************************/ | |
119 | |
120 final Random seed (uint seed) | |
121 { | |
122 kiss_x = seed | 1; | |
123 kiss_y = seed | 2; | |
124 kiss_z = seed | 4; | |
125 kiss_w = seed | 8; | |
126 kiss_carry = 0; | |
127 return this; | |
128 } | |
129 | |
130 /********************************************************************** | |
131 | |
132 Returns X such that 0 <= X <= uint.max | |
133 | |
134 **********************************************************************/ | |
135 | |
136 final uint next () | |
137 { | |
138 kiss_x = kiss_x * 69069 + 1; | |
139 kiss_y ^= kiss_y << 13; | |
140 kiss_y ^= kiss_y >> 17; | |
141 kiss_y ^= kiss_y << 5; | |
142 kiss_k = (kiss_z >> 2) + (kiss_w >> 3) + (kiss_carry >> 2); | |
143 kiss_m = kiss_w + kiss_w + kiss_z + kiss_carry; | |
144 kiss_z = kiss_w; | |
145 kiss_w = kiss_m; | |
146 kiss_carry = kiss_k >> 30; | |
147 return kiss_x + kiss_y + kiss_w; | |
148 } | |
149 | |
150 /********************************************************************** | |
151 | |
152 Returns X such that 0 <= X < max | |
153 | |
154 Note that max is exclusive, making it compatible with | |
155 array indexing | |
156 | |
157 **********************************************************************/ | |
158 | |
159 final uint next (uint max) | |
160 { | |
161 return next() % max; | |
162 } | |
163 | |
164 /********************************************************************** | |
165 | |
166 Returns X such that min <= X < max | |
167 | |
168 Note that max is exclusive, making it compatible with | |
169 array indexing | |
170 | |
171 **********************************************************************/ | |
172 | |
173 final uint next (uint min, uint max) | |
174 { | |
175 return next(max-min) + min; | |
176 } | |
177 } | |
178 |