TrueSync
TSRandom.cs
1 using System;
2 
3 namespace TrueSync {
4 
8  public class TSRandom {
9  // From http://www.codeproject.com/Articles/164087/Random-Number-Generation
10  // Class TSRandom generates random numbers
11  // from a uniform distribution using the Mersenne
12  // Twister algorithm.
13  private const int N = 624;
14  private const int M = 397;
15  private const uint MATRIX_A = 0x9908b0dfU;
16  private const uint UPPER_MASK = 0x80000000U;
17  private const uint LOWER_MASK = 0x7fffffffU;
18  private const int MAX_RAND_INT = 0x7fffffff;
19  private uint[] mag01 = { 0x0U, MATRIX_A };
20  private uint[] mt = new uint[N];
21  private int mti = N + 1;
22 
26  public static TSRandom instance;
27 
28  internal static void Init() {
29  instance = New(1);
30  }
31 
35  public static TSRandom New(int seed) {
36  TSRandom r = new TSRandom(seed);
37 
38  StateTracker.AddTracking(r, "mt");
39  StateTracker.AddTracking(r, "mti");
40 
41  return r;
42  }
43 
44  private TSRandom() {
45  init_genrand((uint)DateTime.Now.Millisecond);
46  }
47 
48  private TSRandom(int seed) {
49  init_genrand((uint)seed);
50  }
51 
52  private TSRandom(int[] init) {
53  uint[] initArray = new uint[init.Length];
54  for (int i = 0; i < init.Length; ++i)
55  initArray[i] = (uint)init[i];
56  init_by_array(initArray, (uint)initArray.Length);
57  }
58 
59  public static int MaxRandomInt { get { return 0x7fffffff; } }
60 
64  public int Next() {
65  return genrand_int31();
66  }
67 
71  public static int CallNext() {
72  return instance.Next();
73  }
74 
78  public int Next(int minValue, int maxValue) {
79  if (minValue > maxValue) {
80  int tmp = maxValue;
81  maxValue = minValue;
82  minValue = tmp;
83  }
84 
85  int range = maxValue - minValue;
86 
87  return minValue + Next() % range;
88  }
89 
93  public FP Next(float minValue, float maxValue) {
94  int minValueInt = (int)(minValue * 1000), maxValueInt = (int)(maxValue * 1000);
95 
96  if (minValueInt > maxValueInt) {
97  int tmp = maxValueInt;
98  maxValueInt = minValueInt;
99  minValueInt = tmp;
100  }
101 
102  return (FP.Floor((maxValueInt - minValueInt + 1) * NextFP() +
103  minValueInt)) / 1000;
104  }
105 
109  public static int Range(int minValue, int maxValue) {
110  return instance.Next(minValue, maxValue);
111  }
112 
116  public static FP Range(float minValue, float maxValue) {
117  return instance.Next(minValue, maxValue);
118  }
119 
123  public FP NextFP() {
124  return ((FP) Next()) / (MaxRandomInt);
125  }
126 
130  public static FP value {
131  get {
132  return instance.NextFP();
133  }
134  }
135 
139  public static TSVector insideUnitSphere {
140  get {
141  return new TSVector(value, value, value);
142  }
143  }
144 
145  private float NextFloat() {
146  return (float)genrand_real2();
147  }
148 
149  private float NextFloat(bool includeOne) {
150  if (includeOne) {
151  return (float)genrand_real1();
152  }
153  return (float)genrand_real2();
154  }
155 
156  private float NextFloatPositive() {
157  return (float)genrand_real3();
158  }
159 
160  private double NextDouble() {
161  return genrand_real2();
162  }
163 
164  private double NextDouble(bool includeOne) {
165  if (includeOne) {
166  return genrand_real1();
167  }
168  return genrand_real2();
169  }
170 
171  private double NextDoublePositive() {
172  return genrand_real3();
173  }
174 
175  private double Next53BitRes() {
176  return genrand_res53();
177  }
178 
179  public void Initialize() {
180  init_genrand((uint)DateTime.Now.Millisecond);
181  }
182 
183  public void Initialize(int seed) {
184  init_genrand((uint)seed);
185  }
186 
187  public void Initialize(int[] init) {
188  uint[] initArray = new uint[init.Length];
189  for (int i = 0; i < init.Length; ++i)
190  initArray[i] = (uint)init[i];
191  init_by_array(initArray, (uint)initArray.Length);
192  }
193 
194  private void init_genrand(uint s) {
195  mt[0] = s & 0xffffffffU;
196  for (mti = 1; mti < N; mti++) {
197  mt[mti] = (uint)(1812433253U * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti);
198  mt[mti] &= 0xffffffffU;
199  }
200  }
201 
202  private void init_by_array(uint[] init_key, uint key_length) {
203  int i, j, k;
204  init_genrand(19650218U);
205  i = 1;
206  j = 0;
207  k = (int)(N > key_length ? N : key_length);
208  for (; k > 0; k--) {
209  mt[i] = (uint)((uint)(mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1664525U)) + init_key[j] + j);
210  mt[i] &= 0xffffffffU;
211  i++;
212  j++;
213  if (i >= N) {
214  mt[0] = mt[N - 1];
215  i = 1;
216  }
217  if (j >= key_length)
218  j = 0;
219  }
220  for (k = N - 1; k > 0; k--) {
221  mt[i] = (uint)((uint)(mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) *
222  1566083941U)) - i);
223  mt[i] &= 0xffffffffU;
224  i++;
225  if (i >= N) {
226  mt[0] = mt[N - 1];
227  i = 1;
228  }
229  }
230  mt[0] = 0x80000000U;
231  }
232 
233  uint genrand_int32() {
234  uint y;
235  if (mti >= N) {
236  int kk;
237  if (mti == N + 1)
238  init_genrand(5489U);
239  for (kk = 0; kk < N - M; kk++) {
240  y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
241  mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1U];
242  }
243  for (; kk < N - 1; kk++) {
244  y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
245  mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1U];
246  }
247  y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
248  mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1U];
249  mti = 0;
250  }
251  y = mt[mti++];
252  y ^= (y >> 11);
253  y ^= (y << 7) & 0x9d2c5680U;
254  y ^= (y << 15) & 0xefc60000U;
255  y ^= (y >> 18);
256  return y;
257  }
258 
259  private int genrand_int31() {
260  return (int)(genrand_int32() >> 1);
261  }
262 
263  FP genrand_FP() {
264  return (FP)genrand_int32() * (FP.One / (FP)4294967295);
265  }
266 
267  double genrand_real1() {
268  return genrand_int32() * (1.0 / 4294967295.0);
269  }
270  double genrand_real2() {
271  return genrand_int32() * (1.0 / 4294967296.0);
272  }
273 
274  double genrand_real3() {
275  return (((double)genrand_int32()) + 0.5) * (1.0 / 4294967296.0);
276  }
277 
278  double genrand_res53() {
279  uint a = genrand_int32() >> 5, b = genrand_int32() >> 6;
280  return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
281  }
282  }
283 
284 }
int Next(int minValue, int maxValue)
Returns a integer between a min value [inclusive] and a max value [exclusive].
Definition: TSRandom.cs:78
static int Range(int minValue, int maxValue)
Returns a integer between a min value [inclusive] and a max value [exclusive].
Definition: TSRandom.cs:109
int Next()
Returns a random integer.
Definition: TSRandom.cs:64
Generates random numbers based on a deterministic approach.
Definition: TSRandom.cs:8
static FP value
Returns a FP between 0.0 [inclusive] and 1.0 [inclusive].
Definition: TSRandom.cs:130
FP Next(float minValue, float maxValue)
Returns a FP between a min value [inclusive] and a max value [inclusive].
Definition: TSRandom.cs:93
static TSRandom instance
Static instance of TSRandom with seed 1.
Definition: TSRandom.cs:26
static int CallNext()
Returns a random integer.
Definition: TSRandom.cs:71
static TSVector insideUnitSphere
Returns a random TSVector representing a point inside a sphere with radius 1.
Definition: TSRandom.cs:139
FP NextFP()
Returns a FP between 0.0 [inclusive] and 1.0 [inclusive].
Definition: TSRandom.cs:123
static FP Range(float minValue, float maxValue)
Returns a FP between a min value [inclusive] and a max value [inclusive].
Definition: TSRandom.cs:116
static TSRandom New(int seed)
Generates a new instance based on a given seed.
Definition: TSRandom.cs:35