Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef __r123_gslmicrorng_dot_h__
00033 #define __r123_gslmicrorng_dot_h__
00034
00035
00036 #include <gsl/gsl_rng.h>
00037 #include <string.h>
00038
00079 #define GSL_MICRORNG(NAME, CBRNGNAME) \
00080 const gsl_rng_type *gsl_rng_##NAME; \
00081 \
00082 typedef struct{ \
00083 CBRNGNAME##_ctr_t ctr; \
00084 CBRNGNAME##_ctr_t r; \
00085 CBRNGNAME##_key_t key; \
00086 R123_ULONG_LONG n; \
00087 int elem; \
00088 } NAME##_state; \
00089 \
00090 static unsigned long int NAME##_get(void *vstate){ \
00091 NAME##_state *st = (NAME##_state *)vstate; \
00092 const int N=sizeof(st->ctr.v)/sizeof(st->ctr.v[0]); \
00093 if( st->elem == 0 ){ \
00094 CBRNGNAME##_ctr_t c = st->ctr; \
00095 c.v[N-1] |= st->n<<(R123_W(CBRNGNAME##_ctr_t)-32); \
00096 st->n++; \
00097 st->r = CBRNGNAME(c, st->key); \
00098 st->elem = N; \
00099 } \
00100 return 0xffffffff & st->r.v[--st->elem]; \
00101 } \
00102 \
00103 static double \
00104 NAME##_get_double (void * vstate) \
00105 { \
00106 return NAME##_get (vstate)/4294967296.; \
00107 } \
00108 \
00109 static void NAME##_set(void *vstate, unsigned long int s){ \
00110 NAME##_state *st = (NAME##_state *)vstate; \
00111 (void)s; \
00112 st->elem = 0; \
00113 st->n = ~0; \
00114 } \
00115 \
00116 static const gsl_rng_type NAME##_type = { \
00117 #NAME, \
00118 0xffffffffUL, \
00119 0, \
00120 sizeof(NAME##_state), \
00121 &NAME##_set, \
00122 &NAME##_get, \
00123 &NAME##_get_double \
00124 }; \
00125 \
00126 R123_STATIC_INLINE void NAME##_reset(const gsl_rng* gr, CBRNGNAME##_ctr_t c, CBRNGNAME##_key_t k) { \
00127 NAME##_state* state = (NAME##_state *)gr->state; \
00128 state->ctr = c; \
00129 state->key = k; \
00130 state->n = 0; \
00131 state->elem = 0; \
00132 } \
00133 \
00134 const gsl_rng_type *gsl_rng_##NAME = &NAME##_type
00135
00136 #endif