ARTS  2.2.66
rng.cc
Go to the documentation of this file.
1 /* Copyright (C) 2003-2012 Cory Davis <cory@met.ed.ac.uk>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA. */
17 
18 /*===========================================================================
19  === File description
20  ===========================================================================*/
21 
35 #include "rng.h"
36 #include <cstring>
37 #include <iostream>
38 #include <algorithm>
39 #include <vector>
40 #include <climits>
41 #include <cstddef>
42 #include <cstdlib>
43 #include <cstdio>
44 
45 #include "arts.h"
46 #include "messages.h"
47 
48 
53 {
55 }
56 
57 
62 {
63  gsl_rng_free (r);
64 }
65 
72 void Rng::seed(unsigned long int n, const Verbosity& verbosity)
73 {
74  // Static pool of previously used seeds.
75  static vector<unsigned long int> seeds;
76 
77 #pragma omp critical (Rng_seed)
78  {
79  unsigned long int n_orig = n;
80  //cout << "Requested seed: " << n;
81  while (find(seeds.begin(), seeds.end(), n) != seeds.end())
82  {
83  if (n >= ULONG_MAX - 1)
84  n=0;
85  else
86  n++;
87 
88  // If all possible seeds were already used, we empty the pool and
89  // start over.
90  if (n == n_orig)
91  {
93  out0 << "Rng Warning: Couldn't find an unused seed. Clearing seed pool.\n";
94  seeds.empty();
95  break;
96  }
97  }
98  seeds.push_back(n);
99  seed_no=n;
100  //cout << " Got seed: " << seed_no << endl;
101  }
102 
104 }
105 
106 
110 void Rng::force_seed(unsigned long int n)
111 {
112  seed_no=n;
114 }
115 
116 
120 double Rng::draw()
121 {
122  return gsl_rng_uniform (r);
123 }
124 
125 
129 unsigned long int Rng::showseed() const
130 {
131  return seed_no;
132 }
133 
134 
135 /*
136  rng/mt.c
137 
138  This program is free software; you can redistribute it and/or
139  modify it under the terms of the GNU General Public License as
140  published by the Free Software Foundation; either version 2 of the
141  License, or (at your option) any later version.
142 
143  This program is distributed in the hope that it will be useful, but
144  WITHOUT ANY WARRANTY; without even the implied warranty of
145  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
146  General Public License for more details. You should have received
147  a copy of the GNU General Public License along with this program;
148  if not, write to the Free Foundation, Inc., 59 Temple Place, Suite
149  330, Boston, MA 02111-1307 USA
150 
151  Original implementation was copyright (C) 1997 Makoto Matsumoto and
152  Takuji Nishimura. Coded by Takuji Nishimura, considering the
153  suggestions by Topher Cooper and Marc Rieffel in July-Aug. 1997, "A
154  C-program for MT19937: Integer version (1998/4/6)"
155 
156  This implementation copyright (C) 1998 Brian Gough. I reorganized
157  the code to use the module framework of GSL. The license on this
158  implementation was changed from LGPL to GPL, following paragraph 3
159  of the LGPL, version 2.
160 
161  Update:
162 
163  The seeding procedure has been updated to match the 10/99 release
164  of MT19937.
165 
166  Update:
167 
168  The seeding procedure has been updated again to match the 2002
169  release of MT19937
170 
171  The original code included the comment: "When you use this, send an
172  email to: matumoto@math.keio.ac.jp with an appropriate reference to
173  your work".
174 
175  Makoto Matsumoto has a web page with more information about the
176  generator, http://www.math.keio.ac.jp/~matumoto/emt.html.
177 
178  The paper below has details of the algorithm.
179 
180  From: Makoto Matsumoto and Takuji Nishimura, "Mersenne Twister: A
181  623-dimensionally equidistributerd uniform pseudorandom number
182  generator". ACM Transactions on Modeling and Computer Simulation,
183  Vol. 8, No. 1 (Jan. 1998), Pages 3-30
184 
185  You can obtain the paper directly from Makoto Matsumoto's web page.
186 
187  The period of this generator is 2^{19937} - 1.
188 
189 */
190 
191 static inline unsigned long int mt_get (void *vstate);
192 static double mt_get_double (void *vstate);
193 static void mt_set (void *state, unsigned long int s);
194 
195 #define N 624 /* Period parameters */
196 #define M 397
197 
198 /* most significant w-r bits */
199 static const unsigned long UPPER_MASK = 0x80000000UL;
200 
201 /* least significant r bits */
202 static const unsigned long LOWER_MASK = 0x7fffffffUL;
203 
204 typedef struct
205  {
206  unsigned long mt[N];
207  int mti;
208  }
209 mt_state_t;
210 
211 static inline unsigned long
212 mt_get (void *vstate)
213 {
214  mt_state_t *state = (mt_state_t *) vstate;
215 
216  unsigned long k ;
217  unsigned long int *const mt = state->mt;
218 
219 #define MAGIC(y) (((y)&0x1) ? 0x9908b0dfUL : 0)
220 
221  if (state->mti >= N)
222  { /* generate N words at one time */
223  int kk;
224 
225  for (kk = 0; kk < N - M; kk++)
226  {
227  unsigned long y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
228  mt[kk] = mt[kk + M] ^ (y >> 1) ^ MAGIC(y);
229  }
230  for (; kk < N - 1; kk++)
231  {
232  unsigned long y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
233  mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ MAGIC(y);
234  }
235 
236  {
237  unsigned long y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
238  mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ MAGIC(y);
239  }
240 
241  state->mti = 0;
242  }
243 
244  /* Tempering */
245 
246  k = mt[state->mti];
247  k ^= (k >> 11);
248  k ^= (k << 7) & 0x9d2c5680UL;
249  k ^= (k << 15) & 0xefc60000UL;
250  k ^= (k >> 18);
251 
252  state->mti++;
253 
254  return k;
255 }
256 
257 static double
258 mt_get_double (void * vstate)
259 {
260  return (double)mt_get (vstate) / 4294967296.0 ;
261 }
262 
263 static void
264 mt_set (void *vstate, unsigned long int s)
265 {
266  mt_state_t *state = (mt_state_t *) vstate;
267  int i;
268 
269  if (s == 0)
270  s = 4357; /* the default seed is 4357 */
271 
272  state->mt[0]= s & 0xffffffffUL;
273 
274  for (i = 1; i < N; i++)
275  {
276  /* See Knuth's "Art of Computer Programming" Vol. 2, 3rd
277  Ed. p.106 for multiplier. */
278 
279  state->mt[i] =
280  (1812433253UL * (state->mt[i-1] ^ (state->mt[i-1] >> 30)) + i);
281 
282  state->mt[i] &= 0xffffffffUL;
283  }
284 
285  state->mti = i;
286 }
287 
288 
289 
290 static const gsl_rng_type mt_type =
291 {"mt19937", /* name */
292  0xffffffffUL, /* RAND_MAX */
293  0, /* RAND_MIN */
294  sizeof (mt_state_t),
295  &mt_set,
296  &mt_get,
297  &mt_get_double};
298 
299 
300 const gsl_rng_type *gsl_rng_mt19937 = &mt_type;
301 unsigned long int gsl_rng_default_seed = 0;
302 /* rng/types.c
303  *
304  * Copyright (C) 2001 Brian Gough
305  *
306  * This program is free software; you can redistribute it and/or modify
307  * it under the terms of the GNU General Public License as published by
308  * the Free Software Foundation; either version 2 of the License, or (at
309  * your option) any later version.
310  *
311  * This program is distributed in the hope that it will be useful, but
312  * WITHOUT ANY WARRANTY; without even the implied warranty of
313  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
314  * General Public License for more details.
315  *
316  * You should have received a copy of the GNU General Public License
317  * along with this program; if not, write to the Free Software
318  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
319  */
320 
321 #define N1 100
322 
324 
325 #define ADD(t) {if (i==N1) abort(); gsl_rng_generator_types[i] = (t); i++; };
326 
327 const gsl_rng_type **
329 {
330  int i = 0;
331 
332  /* ADD(gsl_rng_borosh13);
333  ADD(gsl_rng_cmrg);
334  ADD(gsl_rng_coveyou);
335  ADD(gsl_rng_fishman18);
336  ADD(gsl_rng_fishman20);
337  ADD(gsl_rng_fishman2x);
338  ADD(gsl_rng_gfsr4);
339  ADD(gsl_rng_knuthran);
340  ADD(gsl_rng_knuthran2);
341  ADD(gsl_rng_lecuyer21);
342  ADD(gsl_rng_minstd);
343  ADD(gsl_rng_mrg);*/
344  ADD(gsl_rng_mt19937);
345  /* ADD(gsl_rng_mt19937_1999);
346  ADD(gsl_rng_mt19937_1998);
347  ADD(gsl_rng_r250);
348  ADD(gsl_rng_ran0);
349  ADD(gsl_rng_ran1);
350  ADD(gsl_rng_ran2);
351  ADD(gsl_rng_ran3);
352  ADD(gsl_rng_rand);
353  ADD(gsl_rng_rand48);
354  ADD(gsl_rng_random128_bsd);
355  ADD(gsl_rng_random128_glibc2);
356  ADD(gsl_rng_random128_libc5);
357  ADD(gsl_rng_random256_bsd);
358  ADD(gsl_rng_random256_glibc2);
359  ADD(gsl_rng_random256_libc5);
360  ADD(gsl_rng_random32_bsd);
361  ADD(gsl_rng_random32_glibc2);
362  ADD(gsl_rng_random32_libc5);
363  ADD(gsl_rng_random64_bsd);
364  ADD(gsl_rng_random64_glibc2);
365  ADD(gsl_rng_random64_libc5);
366  ADD(gsl_rng_random8_bsd);
367  ADD(gsl_rng_random8_glibc2);
368  ADD(gsl_rng_random8_libc5);
369  ADD(gsl_rng_random_bsd);
370  ADD(gsl_rng_random_glibc2);
371  ADD(gsl_rng_random_libc5);
372  ADD(gsl_rng_randu);
373  ADD(gsl_rng_ranf);
374  ADD(gsl_rng_ranlux);
375  ADD(gsl_rng_ranlux389);
376  ADD(gsl_rng_ranlxd1);
377  ADD(gsl_rng_ranlxd2);
378  ADD(gsl_rng_ranlxs0);
379  ADD(gsl_rng_ranlxs1);
380  ADD(gsl_rng_ranlxs2);
381  ADD(gsl_rng_ranmar);
382  ADD(gsl_rng_slatec);
383  ADD(gsl_rng_taus);
384  ADD(gsl_rng_taus2);
385  ADD(gsl_rng_taus113);
386  ADD(gsl_rng_transputer);
387  ADD(gsl_rng_tt800);
388  ADD(gsl_rng_uni);
389  ADD(gsl_rng_uni32);
390  ADD(gsl_rng_vax);
391  ADD(gsl_rng_waterman14);
392  ADD(gsl_rng_zuf);*/
393  ADD(0);
394 
396 }
397 
398 /* err/stream.c
399  *
400  * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman, Brian Gough
401  *
402  * This program is free software; you can redistribute it and/or modify
403  * it under the terms of the GNU General Public License as published by
404  * the Free Software Foundation; either version 2 of the License, or (at
405  * your option) any later version.
406  *
407  * This program is distributed in the hope that it will be useful, but
408  * WITHOUT ANY WARRANTY; without even the implied warranty of
409  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
410  * General Public License for more details.
411  *
412  * You should have received a copy of the GNU General Public License
413  * along with this program; if not, write to the Free Software
414  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
415  */
416 
417 FILE * gsl_stream = NULL ;
419 
420 void
421 gsl_stream_printf (const char *label, const char *file, int line,
422  const char *reason)
423 {
424  if (gsl_stream == NULL)
425  {
426  gsl_stream = stderr;
427  }
428  if (gsl_stream_handler)
429  {
430  (*gsl_stream_handler) (label, file, line, reason);
431  return;
432  }
433  fprintf (gsl_stream, "gsl: %s:%d: %s: %s\n", file, line, label, reason);
434 
435 }
436 
439 {
440  gsl_stream_handler_t * previous_handler = gsl_stream_handler;
441  gsl_stream_handler = new_handler;
442  return previous_handler;
443 }
444 
445 FILE *
446 gsl_set_stream (FILE * new_stream)
447 {
448  FILE * previous_stream;
449  if (gsl_stream == NULL) {
450  gsl_stream = stderr;
451  }
452  previous_stream = gsl_stream;
453  gsl_stream = new_stream;
454  return previous_stream;
455 }
456 
457 
458 /* err/error.c
459  *
460  * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman, Brian Gough
461  *
462  * This program is free software; you can redistribute it and/or modify
463  * it under the terms of the GNU General Public License as published by
464  * the Free Software Foundation; either version 2 of the License, or (at
465  * your option) any later version.
466  *
467  * This program is distributed in the hope that it will be useful, but
468  * WITHOUT ANY WARRANTY; without even the implied warranty of
469  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
470  * General Public License for more details.
471  *
472  * You should have received a copy of the GNU General Public License
473  * along with this program; if not, write to the Free Software
474  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
475  */
476 
478 
479 static void no_error_handler (const char *reason, const char *file, int line, int gsl_errno);
480 
481 void
482 gsl_error (const char * reason, const char * file, int line, int gsl_errno)
483 {
484  if (gsl_error_handler)
485  {
486  (*gsl_error_handler) (reason, file, line, gsl_errno);
487  return ;
488  }
489 
490  gsl_stream_printf ("ERROR", file, line, reason);
491 
492  fprintf (stderr, "Default GSL error handler invoked.\n");
493  abort ();
494 }
495 
498 {
499  gsl_error_handler_t * previous_handler = gsl_error_handler;
500  gsl_error_handler = new_handler;
501  return previous_handler;
502 }
503 
504 
507 {
508  gsl_error_handler_t * previous_handler = gsl_error_handler;
509  gsl_error_handler = no_error_handler;
510  return previous_handler;
511 }
512 
513 static void
514 no_error_handler (const char *reason _U_, const char *file _U_, int line _U_, int gsl_errno _U_)
515 {
516  /* do nothing */
517  return;
518 }
519 
520 
521 /* rng/rng.c
522  *
523  * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
524  *
525  * This program is free software; you can redistribute it and/or modify
526  * it under the terms of the GNU General Public License as published by
527  * the Free Software Foundation; either version 2 of the License, or (at
528  * your option) any later version.
529  *
530  * This program is distributed in the hope that it will be useful, but
531  * WITHOUT ANY WARRANTY; without even the implied warranty of
532  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
533  * General Public License for more details.
534  *
535  * You should have received a copy of the GNU General Public License
536  * along with this program; if not, write to the Free Software
537  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
538  */
539 
540 gsl_rng *
542 {
543 
544  gsl_rng *r = (gsl_rng *) malloc (sizeof (gsl_rng));
545 
546  if (r == 0)
547  {
548  GSL_ERROR_VAL ("failed to allocate space for rng struct",
549  GSL_ENOMEM, 0);
550  };
551 
552  r->state = malloc (T->size);
553 
554  if (r->state == 0)
555  {
556  free (r); /* exception in constructor, avoid memory leak */
557 
558  GSL_ERROR_VAL ("failed to allocate space for rng state",
559  GSL_ENOMEM, 0);
560  };
561 
562  r->type = T;
563 
564  gsl_rng_set (r, gsl_rng_default_seed); /* seed the generator */
565 
566  return r;
567 }
568 
569 int
570 gsl_rng_memcpy (gsl_rng * dest, const gsl_rng * src)
571 {
572  if (dest->type != src->type)
573  {
574  GSL_ERROR ("generators must be of the same type", GSL_EINVAL);
575  }
576 
577  memcpy (dest->state, src->state, src->type->size);
578 
579  return GSL_SUCCESS;
580 }
581 
582 gsl_rng *
584 {
585  gsl_rng *r = (gsl_rng *) malloc (sizeof (gsl_rng));
586 
587  if (r == 0)
588  {
589  GSL_ERROR_VAL ("failed to allocate space for rng struct",
590  GSL_ENOMEM, 0);
591  };
592 
593  r->state = malloc (q->type->size);
594 
595  if (r->state == 0)
596  {
597  free (r); /* exception in constructor, avoid memory leak */
598 
599  GSL_ERROR_VAL ("failed to allocate space for rng state",
600  GSL_ENOMEM, 0);
601  };
602 
603  r->type = q->type;
604 
605  memcpy (r->state, q->state, q->type->size);
606 
607  return r;
608 }
609 
610 void
611 gsl_rng_set (const gsl_rng * r, unsigned long int seed)
612 {
613  (r->type->set) (r->state, seed);
614 }
615 
616 #ifndef HIDE_INLINE_STATIC
617 unsigned long int
619 {
620  return (r->type->get) (r->state);
621 }
622 
623 double
625 {
626  return (r->type->get_double) (r->state);
627 }
628 
629 double
631 {
632  double x ;
633  do
634  {
635  x = (r->type->get_double) (r->state) ;
636  }
637  while (x == 0) ;
638 
639  return x ;
640 }
641 
642 unsigned long int
643 gsl_rng_uniform_int (const gsl_rng * r, unsigned long int n)
644 {
645  unsigned long int offset = r->type->min;
646  unsigned long int range = r->type->max - offset;
647  unsigned long int scale = range / n;
648  unsigned long int k;
649 
650  if (n > range)
651  {
652  GSL_ERROR_VAL ("n exceeds maximum value of generator",
653  GSL_EINVAL, 0) ;
654  }
655 
656  do
657  {
658  k = (((r->type->get) (r->state)) - offset) / scale;
659  }
660  while (k >= n);
661 
662  return k;
663 }
664 #endif
665 
666 unsigned long int
668 {
669  return r->type->max;
670 }
671 
672 unsigned long int
674 {
675  return r->type->min;
676 }
677 
678 const char *
680 {
681  return r->type->name;
682 }
683 
684 size_t
686 {
687  return r->type->size;
688 }
689 
690 void *
692 {
693  return r->state;
694 }
695 
696 void
698 {
699  size_t i;
700  unsigned char *p = (unsigned char *) (r->state);
701  const size_t n = r->type->size;
702 
703  for (i = 0; i < n; i++)
704  {
705  /* FIXME: we're assuming that a char is 8 bits */
706  printf ("%.2x", *(p + i));
707  }
708 
709 }
710 
711 void
713 {
714  free (r->state);
715  free (r);
716 }
void gsl_stream_printf(const char *label, const char *file, int line, const char *reason)
Definition: rng.cc:421
#define N
Definition: rng.cc:195
const gsl_rng_type * type
Definition: rng.h:139
#define M
Definition: rng.cc:196
unsigned long int min
Definition: rng.h:129
Definition: rng.h:137
unsigned long int max
Definition: rng.h:128
FILE * gsl_stream
Definition: rng.cc:417
Declarations having to do with the four output streams.
#define q
Definition: continua.cc:21469
gsl_rng * gsl_rng_clone(const gsl_rng *q)
Definition: rng.cc:583
unsigned long int gsl_rng_max(const gsl_rng *r)
Definition: rng.cc:667
void force_seed(unsigned long int n)
Definition: rng.cc:110
gsl_rng * r
Definition: rng.h:571
FILE * gsl_set_stream(FILE *new_stream)
Definition: rng.cc:446
void gsl_rng_print_state(const gsl_rng *r)
Definition: rng.cc:697
gsl_rng * gsl_rng_alloc(const gsl_rng_type *T)
Definition: rng.cc:541
size_t size
Definition: rng.h:130
void gsl_error_handler_t(const char *reason, const char *file, int line, int gsl_errno)
Definition: rng.h:386
Rng()
Definition: rng.cc:52
void gsl_rng_set(const gsl_rng *r, unsigned long int seed)
Definition: rng.cc:611
~Rng()
Definition: rng.cc:61
void * state
Definition: rng.h:140
const char * name
Definition: rng.h:127
unsigned long mt[N]
Definition: rng.cc:206
const gsl_rng_type * gsl_rng_mt19937
Definition: rng.cc:300
#define GSL_ERROR_VAL(reason, gsl_errno, value)
Definition: rng.h:413
unsigned long int gsl_rng_uniform_int(const gsl_rng *r, unsigned long int n)
Definition: rng.cc:643
#define N1
Definition: rng.cc:321
The global header file for ARTS.
void gsl_stream_handler_t(const char *label, const char *file, int line, const char *reason)
Definition: rng.h:389
void(* set)(void *state, unsigned long int seed)
Definition: rng.h:131
unsigned long int(* get)(void *state)
Definition: rng.h:132
#define ADD(t)
Definition: rng.cc:325
gsl_error_handler_t * gsl_error_handler
Definition: rng.cc:477
Defines the Rng random number generator class.
void gsl_error(const char *reason, const char *file, int line, int gsl_errno)
Definition: rng.cc:482
gsl_stream_handler_t * gsl_stream_handler
Definition: rng.cc:418
void * gsl_rng_state(const gsl_rng *r)
Definition: rng.cc:691
unsigned long int showseed() const
Definition: rng.cc:129
#define MAGIC(y)
unsigned long int gsl_rng_get(const gsl_rng *r)
Definition: rng.cc:618
unsigned long int gsl_rng_default_seed
Definition: rng.cc:301
double draw()
Definition: rng.cc:120
int gsl_rng_memcpy(gsl_rng *dest, const gsl_rng *src)
Definition: rng.cc:570
#define GSL_ERROR(reason, gsl_errno)
Definition: rng.h:405
gsl_stream_handler_t * gsl_set_stream_handler(gsl_stream_handler_t *new_handler)
Definition: rng.cc:438
double(* get_double)(void *state)
Definition: rng.h:133
size_t gsl_rng_size(const gsl_rng *r)
Definition: rng.cc:685
const gsl_rng_type ** gsl_rng_types_setup(void)
Definition: rng.cc:328
#define _U_
Definition: config.h:167
const char * gsl_rng_name(const gsl_rng *r)
Definition: rng.cc:679
unsigned long int gsl_rng_min(const gsl_rng *r)
Definition: rng.cc:673
int mti
Definition: rng.cc:207
#define CREATE_OUT0
Definition: messages.h:211
double gsl_rng_uniform(const gsl_rng *r)
Definition: rng.cc:624
void seed(unsigned long int n, const Verbosity &verbosity)
Definition: rng.cc:72
gsl_error_handler_t * gsl_set_error_handler(gsl_error_handler_t *new_handler)
Definition: rng.cc:497
void gsl_rng_free(gsl_rng *r)
Definition: rng.cc:712
unsigned long int seed_no
Definition: rng.h:573
const gsl_rng_type * gsl_rng_generator_types[N1]
Definition: rng.cc:323
double gsl_rng_uniform_pos(const gsl_rng *r)
Definition: rng.cc:630
gsl_error_handler_t * gsl_set_error_handler_off(void)
Definition: rng.cc:506