Add the init_by_array functionality from the reference implementation of
[platform/upstream/glib.git] / glib / grand.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /* Originally developed and coded by Makoto Matsumoto and Takuji
21  * Nishimura.  Please mail <matumoto@math.keio.ac.jp>, if you're using
22  * code from this file in your own programs or libraries.
23  * Further information on the Mersenne Twister can be found at
24  * http://www.math.keio.ac.jp/~matumoto/emt.html
25  * This code was adapted to glib by Sebastian Wilhelmi.
26  */
27
28 /*
29  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
30  * file for a list of people on the GLib Team.  See the ChangeLog
31  * files for a list of changes.  These files are distributed with
32  * GLib at ftp://ftp.gtk.org/pub/gtk/.  
33  */
34
35 /* 
36  * MT safe
37  */
38
39 #include "config.h"
40
41 #include <math.h>
42 #include <errno.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <sys/types.h>
46 #include <unistd.h>
47
48 #include "glib.h"
49 #include "gthreadinit.h"
50
51 G_LOCK_DEFINE_STATIC (global_random);
52 static GRand* global_random = NULL;
53
54 /* Period parameters */  
55 #define N 624
56 #define M 397
57 #define MATRIX_A 0x9908b0df   /* constant vector a */
58 #define UPPER_MASK 0x80000000 /* most significant w-r bits */
59 #define LOWER_MASK 0x7fffffff /* least significant r bits */
60
61 /* Tempering parameters */   
62 #define TEMPERING_MASK_B 0x9d2c5680
63 #define TEMPERING_MASK_C 0xefc60000
64 #define TEMPERING_SHIFT_U(y)  (y >> 11)
65 #define TEMPERING_SHIFT_S(y)  (y << 7)
66 #define TEMPERING_SHIFT_T(y)  (y << 15)
67 #define TEMPERING_SHIFT_L(y)  (y >> 18)
68
69 static guint
70 get_random_version (void)
71 {
72   static gboolean initialized = FALSE;
73   static guint random_version;
74   
75   if (!initialized)
76     {
77       const gchar *version_string = g_getenv ("G_RANDOM_VERSION");
78       if (!version_string || version_string[0] == '\000' || 
79           strcmp (version_string, "2.2") == 0)
80         random_version = 22;
81       else if (strcmp (version_string, "2.0") == 0)
82         random_version = 20;
83       else
84         {
85           g_warning ("Unknown G_RANDOM_VERSION \"%s\". Using version 2.2.",
86                      version_string);
87           random_version = 22;
88         }
89       initialized = TRUE;
90     }
91   
92   return random_version;
93 }
94
95 /* This is called from g_thread_init(). It's used to
96  * initialize some static data in a threadsafe way.
97  */
98 void 
99 _g_rand_thread_init (void)
100 {
101   (void)get_random_version ();
102 }
103
104 struct _GRand
105 {
106   guint32 mt[N]; /* the array for the state vector  */
107   guint mti; 
108 };
109
110 /**
111  * g_rand_new_with_seed:
112  * @seed: a value to initialize the random number generator.
113  * 
114  * Creates a new random number generator initialized with @seed.
115  * 
116  * Return value: the new #GRand.
117  **/
118 GRand*
119 g_rand_new_with_seed (guint32 seed)
120 {
121   GRand *rand = g_new0 (GRand, 1);
122   g_rand_set_seed (rand, seed);
123   return rand;
124 }
125
126 /**
127  * g_rand_new_with_seed_array:
128  * @seed: an array of seeds to initialize the random number generator.
129  * @seed_length: an array of seeds to initialize the random number generator.
130  * 
131  * Creates a new random number generator initialized with @seed.
132  * 
133  * Return value: the new #GRand.
134  **/
135 GRand*
136 g_rand_new_with_seed_array (const guint32 *seed, guint seed_length)
137 {
138   GRand *rand = g_new0 (GRand, 1);
139   g_rand_set_seed_array (rand, seed, seed_length);
140   return rand;
141 }
142
143 /**
144  * g_rand_new:
145  * 
146  * Creates a new random number generator initialized with a seed taken
147  * either from <filename>/dev/urandom</filename> (if existing) or from 
148  * the current time (as a fallback).
149  * 
150  * Return value: the new #GRand.
151  **/
152 GRand* 
153 g_rand_new (void)
154 {
155   guint32 seed[4];
156   GTimeVal now;
157 #ifdef G_OS_UNIX
158   static gboolean dev_urandom_exists = TRUE;
159
160   if (dev_urandom_exists)
161     {
162       FILE* dev_urandom;
163
164       do
165         {
166           errno = 0;
167           dev_urandom = fopen("/dev/urandom", "rb");
168         }
169       while G_UNLIKELY (errno == EINTR);
170
171       if (dev_urandom)
172         {
173           int r;
174
175           do
176             {
177               errno = 0;
178               r = fread (seed, sizeof (seed), 1, dev_urandom);
179             }
180           while G_UNLIKELY (errno == EINTR);
181
182           if (r != 1)
183             dev_urandom_exists = FALSE;
184
185           do
186             {
187               errno = 0;
188               fclose (dev_urandom);
189             }
190           while G_UNLIKELY (errno == EINTR);
191         }       
192       else
193         dev_urandom_exists = FALSE;
194     }
195 #else
196   static gboolean dev_urandom_exists = FALSE;
197 #endif
198
199   if (!dev_urandom_exists)
200     {  
201       g_get_current_time (&now);
202       seed[0] = now.tv_sec;
203       seed[1] = now.tv_usec;
204       seed[2] = getpid ();
205       seed[3] = getppid ();
206     }
207
208   return g_rand_new_with_seed_array (seed, 4);
209 }
210
211 /**
212  * g_rand_free:
213  * @rand_: a #GRand.
214  *
215  * Frees the memory allocated for the #GRand.
216  **/
217 void
218 g_rand_free (GRand* rand)
219 {
220   g_return_if_fail (rand != NULL);
221
222   g_free (rand);
223 }
224
225 /**
226  * g_rand_copy:
227  * @rand_: a #GRand.
228  *
229  * Copies a #GRand into a new one with the same exact state as before.
230  * This way you can take a snapshot of the random number generator for
231  * replaying later.
232  *
233  * Return value: the new #GRand.
234  **/
235 GRand *
236 g_rand_copy (GRand* rand)
237 {
238   GRand* new_rand;
239
240   g_return_val_if_fail (rand != NULL, NULL);
241
242   new_rand = g_new0 (GRand, 1);
243   memcpy (new_rand, rand, sizeof (GRand));
244
245   return new_rand;
246 }
247
248 /**
249  * g_rand_set_seed:
250  * @rand_: a #GRand.
251  * @seed: a value to reinitialize the random number generator.
252  *
253  * Sets the seed for the random number generator #GRand to @seed.
254  **/
255 void
256 g_rand_set_seed (GRand* rand, guint32 seed)
257 {
258   g_return_if_fail (rand != NULL);
259
260   switch (get_random_version ())
261     {
262     case 20:
263       /* setting initial seeds to mt[N] using         */
264       /* the generator Line 25 of Table 1 in          */
265       /* [KNUTH 1981, The Art of Computer Programming */
266       /*    Vol. 2 (2nd Ed.), pp102]                  */
267       
268       if (seed == 0) /* This would make the PRNG procude only zeros */
269         seed = 0x6b842128; /* Just set it to another number */
270       
271       rand->mt[0]= seed;
272       for (rand->mti=1; rand->mti<N; rand->mti++)
273         rand->mt[rand->mti] = (69069 * rand->mt[rand->mti-1]);
274       
275       break;
276     case 22:
277       /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
278       /* In the previous version (see above), MSBs of the    */
279       /* seed affect only MSBs of the array mt[].            */
280       
281       rand->mt[0]= seed;
282       for (rand->mti=1; rand->mti<N; rand->mti++)
283         rand->mt[rand->mti] = 1812433253UL * 
284           (rand->mt[rand->mti-1] ^ (rand->mt[rand->mti-1] >> 30)) + rand->mti; 
285       break;
286     default:
287       g_assert_not_reached ();
288     }
289 }
290
291 /**
292  * g_rand_set_seed_array:
293  * @rand_: a #GRand.
294  * @seed: array to initialize with
295  * @seed_length: length of array
296  *
297  * Initializes the random number generator by an array of
298  * longs.  Array can be of arbitrary size, though only the
299  * first 624 values are taken.  This function is useful
300  * if you have many low entropy seeds, or if you require more then
301  * 32bits of actual entropy for your application.
302  **/
303 void
304 g_rand_set_seed_array (GRand* rand, const guint32 *seed, guint seed_length)
305 {
306   int i, j, k;
307
308   g_return_if_fail (rand != NULL);
309   g_return_if_fail (seed_length >= 1);
310
311   g_rand_set_seed (rand, 19650218UL);
312
313   i=1; j=0;
314   k = (N>seed_length ? N : seed_length);
315   for (; k; k--)
316     {
317       rand->mt[i] = (rand->mt[i] ^
318                      ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1664525UL))
319               + seed[j] + j; /* non linear */
320       rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
321       i++; j++;
322       if (i>=N)
323         {
324           rand->mt[0] = rand->mt[N-1];
325           i=1;
326         }
327       if (j>=seed_length)
328         j=0;
329     }
330   for (k=N-1; k; k--)
331     {
332       rand->mt[i] = (rand->mt[i] ^
333                      ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1566083941UL))
334               - i; /* non linear */
335       rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
336       i++;
337       if (i>=N)
338         {
339           rand->mt[0] = rand->mt[N-1];
340           i=1;
341         }
342     }
343
344   rand->mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ 
345 }
346
347 /**
348  * g_rand_int:
349  * @rand_: a #GRand.
350  *
351  * Returns the next random #guint32 from @rand_ equally distributed over
352  * the range [0..2^32-1].
353  *
354  * Return value: A random number.
355  **/
356 guint32
357 g_rand_int (GRand* rand)
358 {
359   guint32 y;
360   static const guint32 mag01[2]={0x0, MATRIX_A};
361   /* mag01[x] = x * MATRIX_A  for x=0,1 */
362
363   g_return_val_if_fail (rand != NULL, 0);
364
365   if (rand->mti >= N) { /* generate N words at one time */
366     int kk;
367     
368     for (kk=0;kk<N-M;kk++) {
369       y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
370       rand->mt[kk] = rand->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
371     }
372     for (;kk<N-1;kk++) {
373       y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
374       rand->mt[kk] = rand->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
375     }
376     y = (rand->mt[N-1]&UPPER_MASK)|(rand->mt[0]&LOWER_MASK);
377     rand->mt[N-1] = rand->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
378     
379     rand->mti = 0;
380   }
381   
382   y = rand->mt[rand->mti++];
383   y ^= TEMPERING_SHIFT_U(y);
384   y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
385   y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
386   y ^= TEMPERING_SHIFT_L(y);
387   
388   return y; 
389 }
390
391 /* transform [0..2^32] -> [0..1] */
392 #define G_RAND_DOUBLE_TRANSFORM 2.3283064365386962890625e-10
393
394 /**
395  * g_rand_int_range:
396  * @rand_: a #GRand.
397  * @begin: lower closed bound of the interval.
398  * @end: upper open bound of the interval.
399  *
400  * Returns the next random #gint32 from @rand_ equally distributed over
401  * the range [@begin..@end-1].
402  *
403  * Return value: A random number.
404  **/
405 gint32 
406 g_rand_int_range (GRand* rand, gint32 begin, gint32 end)
407 {
408   guint32 dist = end - begin;
409   guint32 random;
410
411   g_return_val_if_fail (rand != NULL, begin);
412   g_return_val_if_fail (end > begin, begin);
413
414   switch (get_random_version ())
415     {
416     case 20:
417       if (dist <= 0x10000L) /* 2^16 */
418         {
419           /* This method, which only calls g_rand_int once is only good
420            * for (end - begin) <= 2^16, because we only have 32 bits set
421            * from the one call to g_rand_int (). */
422           
423           /* we are using (trans + trans * trans), because g_rand_int only
424            * covers [0..2^32-1] and thus g_rand_int * trans only covers
425            * [0..1-2^-32], but the biggest double < 1 is 1-2^-52. 
426            */
427           
428           gdouble double_rand = g_rand_int (rand) * 
429             (G_RAND_DOUBLE_TRANSFORM +
430              G_RAND_DOUBLE_TRANSFORM * G_RAND_DOUBLE_TRANSFORM);
431           
432           random = (gint32) (double_rand * dist);
433         }
434       else
435         {
436           /* Now we use g_rand_double_range (), which will set 52 bits for
437              us, so that it is safe to round and still get a decent
438              distribution */
439           random = (gint32) g_rand_double_range (rand, 0, dist);
440         }
441       break;
442     case 22:
443       if (dist == 0)
444         random = 0;
445       else 
446         {
447           /* maxvalue is set to the predecessor of the greatest
448            * multiple of dist less or equal 2^32. */
449           guint32 maxvalue;
450           if (dist <= 0x80000000u) /* 2^31 */
451             {
452               /* maxvalue = 2^32 - 1 - (2^32 % dist) */
453               guint32 leftover = (0x80000000u % dist) * 2;
454               if (leftover >= dist) leftover -= dist;
455               maxvalue = 0xffffffffu - leftover;
456             }
457           else
458             maxvalue = dist - 1;
459           
460           do
461             random = g_rand_int (rand);
462           while (random > maxvalue);
463           
464           random %= dist;
465         }
466       break;
467     default:
468       random = 0;               /* Quiet GCC */
469       g_assert_not_reached ();
470     }      
471  
472   return begin + random;
473 }
474
475 /**
476  * g_rand_double:
477  * @rand_: a #GRand.
478  *
479  * Returns the next random #gdouble from @rand_ equally distributed over
480  * the range [0..1).
481  *
482  * Return value: A random number.
483  **/
484 gdouble 
485 g_rand_double (GRand* rand)
486 {    
487   /* We set all 52 bits after the point for this, not only the first
488      32. Thats why we need two calls to g_rand_int */
489   gdouble retval = g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM;
490   retval = (retval + g_rand_int (rand)) * G_RAND_DOUBLE_TRANSFORM;
491
492   /* The following might happen due to very bad rounding luck, but
493    * actually this should be more than rare, we just try again then */
494   if (retval >= 1.0) 
495     return g_rand_double (rand);
496
497   return retval;
498 }
499
500 /**
501  * g_rand_double_range:
502  * @rand_: a #GRand.
503  * @begin: lower closed bound of the interval.
504  * @end: upper open bound of the interval.
505  *
506  * Returns the next random #gdouble from @rand_ equally distributed over
507  * the range [@begin..@end).
508  *
509  * Return value: A random number.
510  **/
511 gdouble 
512 g_rand_double_range (GRand* rand, gdouble begin, gdouble end)
513 {
514   return g_rand_double (rand) * (end - begin) + begin;
515 }
516
517 /**
518  * g_random_int:
519  *
520  * Return a random #guint32 equally distributed over the range
521  * [0..2^32-1].
522  *
523  * Return value: A random number.
524  **/
525 guint32
526 g_random_int (void)
527 {
528   guint32 result;
529   G_LOCK (global_random);
530   if (!global_random)
531     global_random = g_rand_new ();
532   
533   result = g_rand_int (global_random);
534   G_UNLOCK (global_random);
535   return result;
536 }
537
538 /**
539  * g_random_int_range:
540  * @begin: lower closed bound of the interval.
541  * @end: upper open bound of the interval.
542  *
543  * Returns a random #gint32 equally distributed over the range
544  * [@begin..@end-1].
545  *
546  * Return value: A random number.
547  **/
548 gint32 
549 g_random_int_range (gint32 begin, gint32 end)
550 {
551   gint32 result;
552   G_LOCK (global_random);
553   if (!global_random)
554     global_random = g_rand_new ();
555   
556   result = g_rand_int_range (global_random, begin, end);
557   G_UNLOCK (global_random);
558   return result;
559 }
560
561 /**
562  * g_random_double:
563  *
564  * Returns a random #gdouble equally distributed over the range [0..1).
565  *
566  * Return value: A random number.
567  **/
568 gdouble 
569 g_random_double (void)
570 {
571   double result;
572   G_LOCK (global_random);
573   if (!global_random)
574     global_random = g_rand_new ();
575   
576   result = g_rand_double (global_random);
577   G_UNLOCK (global_random);
578   return result;
579 }
580
581 /**
582  * g_random_double_range:
583  * @begin: lower closed bound of the interval.
584  * @end: upper open bound of the interval.
585  *
586  * Returns a random #gdouble equally distributed over the range [@begin..@end).
587  *
588  * Return value: A random number.
589  **/
590 gdouble 
591 g_random_double_range (gdouble begin, gdouble end)
592 {
593   double result;
594   G_LOCK (global_random);
595   if (!global_random)
596     global_random = g_rand_new ();
597  
598   result = g_rand_double_range (global_random, begin, end);
599   G_UNLOCK (global_random);
600   return result;
601 }
602
603 /**
604  * g_random_set_seed:
605  * @seed: a value to reinitialize the global random number generator.
606  * 
607  * Sets the seed for the global random number generator, which is used
608  * by the <function>g_random_*</function> functions, to @seed.
609  **/
610 void
611 g_random_set_seed (guint32 seed)
612 {
613   G_LOCK (global_random);
614   if (!global_random)
615     global_random = g_rand_new_with_seed (seed);
616   else
617     g_rand_set_seed (global_random, seed);
618   G_UNLOCK (global_random);
619 }
620