… | |
… | |
26 | #include <compiler.h> |
26 | #include <compiler.h> |
27 | |
27 | |
28 | // P. L'Ecuyer, “Maximally Equidistributed Combined Tausworthe Generators”, Mathematics of Computation, 65, 213 (1996), 203–213. |
28 | // P. L'Ecuyer, “Maximally Equidistributed Combined Tausworthe Generators”, Mathematics of Computation, 65, 213 (1996), 203–213. |
29 | // http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps |
29 | // http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps |
30 | // http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps |
30 | // http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps |
31 | struct tausworthe_random_generator |
31 | struct tausworthe_rng |
32 | { |
32 | { |
33 | uint32_t state [4]; |
33 | uint32_t state [4]; |
34 | |
34 | |
35 | void seed (uint32_t seed); |
35 | void seed (uint32_t seed); |
36 | uint32_t next (); |
36 | uint32_t next (); |
… | |
… | |
39 | // Xorshift RNGs, George Marsaglia |
39 | // Xorshift RNGs, George Marsaglia |
40 | // http://www.jstatsoft.org/v08/i14/paper |
40 | // http://www.jstatsoft.org/v08/i14/paper |
41 | // this one is about 40% faster than the tausworthe one above (i.e. not much), |
41 | // this one is about 40% faster than the tausworthe one above (i.e. not much), |
42 | // despite the inlining, and has the issue of only creating 2**32-1 numbers. |
42 | // despite the inlining, and has the issue of only creating 2**32-1 numbers. |
43 | // see also http://www.iro.umontreal.ca/~lecuyer/myftp/papers/xorshift.pdf |
43 | // see also http://www.iro.umontreal.ca/~lecuyer/myftp/papers/xorshift.pdf |
44 | struct xorshift_random_generator |
44 | struct xorshift_rng |
45 | { |
45 | { |
46 | uint32_t x, y; |
46 | uint32_t x, y; |
47 | |
47 | |
48 | void seed (uint32_t seed) |
48 | void seed (uint32_t seed) |
49 | { |
49 | { |
… | |
… | |
58 | y = y ^ (y >> 13) ^ t ^ (t >> 10); |
58 | y = y ^ (y >> 13) ^ t ^ (t >> 10); |
59 | return y; |
59 | return y; |
60 | } |
60 | } |
61 | }; |
61 | }; |
62 | |
62 | |
|
|
63 | template<uint32_t A, uint32_t B> |
|
|
64 | struct lc_rng |
|
|
65 | { |
|
|
66 | uint32_t x; |
|
|
67 | |
|
|
68 | void seed (uint32_t seed) |
|
|
69 | { |
|
|
70 | x = seed; |
|
|
71 | } |
|
|
72 | |
|
|
73 | uint32_t next () |
|
|
74 | { |
|
|
75 | x = x * A + B; |
|
|
76 | return x; |
|
|
77 | } |
|
|
78 | }; |
|
|
79 | |
|
|
80 | typedef lc_rng<3039177861U, 0> borosh_niederreiter_rng; |
|
|
81 | typedef lc_rng<2147001325U, 715136305U> bcpl_rng; |
|
|
82 | |
63 | template<typename T, int N, int k> |
83 | template<typename T, int N, int k> |
64 | struct gfsr_random_generator |
84 | struct gfsr_rng |
65 | { |
85 | { |
66 | int i; |
86 | int i; |
67 | T x[N]; |
87 | T x[N]; |
68 | |
88 | |
69 | // rng must have same bitwidth as T |
89 | // rng must have same bitwidth as T |
… | |
… | |
87 | } |
107 | } |
88 | |
108 | |
89 | // actually should subclass to gfsr32... :) |
109 | // actually should subclass to gfsr32... :) |
90 | void seed (uint32_t seed) |
110 | void seed (uint32_t seed) |
91 | { |
111 | { |
92 | xorshift_random_generator rng; |
112 | xorshift_rng rng; |
93 | |
113 | |
94 | rng.seed (seed); |
114 | rng.seed (seed); |
95 | this->seed_rng (rng); |
115 | this->seed_rng (rng); |
96 | } |
116 | } |
97 | |
117 | |
… | |
… | |
110 | } |
130 | } |
111 | }; |
131 | }; |
112 | |
132 | |
113 | // these are about 2-3 times faster than tausworthe, non-inlined, |
133 | // these are about 2-3 times faster than tausworthe, non-inlined, |
114 | // and likely of higher quality. |
134 | // and likely of higher quality. |
115 | typedef gfsr_random_generator<uint32_t, 250, 103> r250_random_generator; |
135 | typedef gfsr_rng<uint32_t, 250, 103> r250_rng; |
116 | typedef gfsr_random_generator<uint32_t, 521, 168> r521_random_generator; |
136 | typedef gfsr_rng<uint32_t, 521, 168> r521_rng; |
117 | |
137 | |
118 | // freeciv uses this one, so it's good enough for us :) |
138 | // freeciv uses this one, so it's good enough for us :) |
119 | typedef gfsr_random_generator<uint32_t, 55, 24> freeciv_random_generator; |
139 | typedef gfsr_rng<uint32_t, 55, 24> freeciv_rng; |
120 | |
140 | |
121 | // this one should be high quality, but is slightly slower than tausworthe |
141 | // this one should be high quality, but is slightly slower than tausworthe |
122 | struct r250521_random_generator |
142 | struct r250521_rng |
123 | { |
143 | { |
124 | r250_random_generator r250; |
144 | r250_rng r250; |
125 | r521_random_generator r521; |
145 | r521_rng r521; |
126 | |
146 | |
127 | void seed (uint32_t seed); |
147 | void seed (uint32_t seed); |
128 | uint32_t next (); |
148 | uint32_t next (); |
129 | }; |
149 | }; |
130 | |
150 | |
… | |
… | |
156 | return is_constant (r_min <= r_max) && r_min <= r_max |
176 | return is_constant (r_min <= r_max) && r_min <= r_max |
157 | ? r_min + operator ()(r_max - r_min + 1) |
177 | ? r_min + operator ()(r_max - r_min + 1) |
158 | : get_range (r_min, r_max); |
178 | : get_range (r_min, r_max); |
159 | } |
179 | } |
160 | |
180 | |
161 | // return a number within the half-open interval [0..1[ |
|
|
162 | double operator ()() |
|
|
163 | { |
|
|
164 | return this->next () / (double)0x100000000ULL; |
|
|
165 | } |
|
|
166 | |
|
|
167 | uint32_t get_u32 (); |
181 | uint32_t get_u32 (); |
168 | uint64_t get_u64 (); |
182 | uint64_t get_u64 (); |
|
|
183 | float get_float (); |
|
|
184 | double get_double (); |
|
|
185 | |
|
|
186 | // return a number within the half-open interval [0..1[ |
|
|
187 | double operator () () |
|
|
188 | { |
|
|
189 | return get_double (); |
|
|
190 | } |
|
|
191 | |
|
|
192 | uint32_t poisson (double mean); |
169 | |
193 | |
170 | protected: |
194 | protected: |
171 | uint32_t get_range (uint32_t r_max); |
195 | uint32_t get_range (uint32_t r_max); |
172 | int get_range (int r_min, int r_max); |
196 | int get_range (int r_min, int r_max); |
173 | }; |
197 | }; |
174 | |
198 | |
175 | // the default rng used in the game |
199 | // the default rng used in the game |
176 | typedef random_number_generator<freeciv_random_generator> rand_gen; |
200 | typedef random_number_generator<freeciv_rng> rand_gen; |
177 | |
201 | |
178 | // used when we often seed |
202 | // used when we often seed |
179 | typedef random_number_generator<tausworthe_random_generator> seedable_rand_gen; |
203 | typedef random_number_generator<tausworthe_rng> seedable_rand_gen; |
180 | |
204 | |
181 | extern rand_gen rndm, rmg_rndm; |
205 | extern rand_gen rndm, rmg_rndm; |
182 | |
206 | |
183 | #endif |
207 | #endif |
184 | |
208 | |