randomWH API
Generation of Pseudo-Random Variates
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
randomWH.c
Go to the documentation of this file.
1 
9 #include "randomWH.h"
10 
11 
13  .x=0,
14  .y=0,
15  .z=0,
16  .t=0,
17  .initialised=isfalse,
18  .init=Congruence_init,
19  .randomWH=randomWH_null,
20  .read=Congruence_read,
21  .bernoulli=randomWH_bernoulli,
22  .geometric=randomWH_geometric,
23  .binomial=randomWH_binomial,
24  .fairdie=randomWH_fairdie,
25 };
52 void Congruence_init(Congruence* self, long int x,long int y,long int z,long int t){
53  if(x<=0||y<=0||z<=0||t<=0)
54  randomWH_error("Seeds must be positive!");
55  self->x = x;
56  self->y = y;
57  self->z = z;
58  self->t = t;
59  if (self->initialised)
60  return;
61  self->initialised = istrue;
62  switch(sizeof(long int)/8){
63  case 1:
64  self->randomWH = randomWH_64;
65  break;
66  case 0:
67  self->randomWH = randomWH_32;
68  break;
69  default:
70  randomWH_error("Could not initialise randomWH function pointer");
71  }
72 }
73 
90 void randomWH_error(const char* message){
91  char prefix[] = "Error in randomWH.c: ";
92  fprintf(stderr,"%s %s\n",prefix, message);
93  exit(EXIT_FAILURE);
94 }
95 
125 long int* Congruence_read(Congruence* self){
126  return (long int*)&self->x;
127 }
128 
129 
141 double randomWH_null(Congruence* self){
142  fprintf(stderr,"Could not initialise randomWH function pointer\n");
143  exit(EXIT_FAILURE);
144 }
145 
146 
161 double randomWH_32(Congruence* self){
162  double result;
163  self->x = 11600L * (self->x % 185127L) - 10379L* (self->x/185127L);
164  self->y = 47003L * (self->y % 45688L) - 10479L* (self->y/ 45688L);
165  self->z = 23000L * (self->z % 93368L) - 19423L* (self->z/ 93368L);
166  self->t = 33000L * (self->t % 65075L) - 8123L* (self->t/ 65075L);
167  if (self->x < 0)
168  self->x += 2147483579L;
169  if (self->y < 0)
170  self->y += 2147483543L;
171  if (self->z < 0)
172  self->z += 2147483423L;
173  if (self->t < 0)
174  self->t += 2147483123L;
175  result = (double)(self->x)*0.0000000004656613022697297188506231646486
176  + (double)(self->y)*0.0000000004656613100759859932486569933169
177  + (double)(self->z)*0.0000000004656613360968421314794009471615
178  + (double)(self->t)*0.0000000004656614011489951998100056779817;
179  while (result > 1.0)
180  result -= 1.0;
181  return result;
182 
183 }
184 
198 double randomWH_64(Congruence* self){
199  double result;
200  self->x = (11600L * self->x) % 2147483579L;
201  self->y = (47003L * self->y) % 2147483543L;
202  self->z = (23000L * self->z) % 2147483423L;
203  self->t = (33000L * self->t) % 2147483123L;
204  result = (double)(self->x)*0.0000000004656613022697297188506231646486
205  + (double)(self->y)*0.0000000004656613100759859932486569933169
206  + (double)(self->z)*0.0000000004656613360968421314794009471615
207  + (double)(self->t)*0.0000000004656614011489951998100056779817;
208  while(result > 1.0)
209  result -= 1.0;
210  return result;
211 
212 }
213 
223 long int randomWH_geometric(Congruence* self, double prob){
224  double unif = self->randomWH(self);
225  double p_bar = 1-prob;
226  long int result = 1L;
227  if(p_bar > 0){
228  result += log(unif)/log(p_bar);
229  }
230  return result;
231 }
232 
268 enum BOOLEAN randomWH_bernoulli(Congruence* self, double prob){
269  double unif = self->randomWH(self);
270  enum BOOLEAN result = isfalse;
271 
272  if(unif < prob){
273  result = istrue;
274  }
275  return result;
276 }
277 
288 long int randomWH_binomial(Congruence* self, long int trials, double prob){
289  long int result = 0;
290  long int count;
291 
292  for(count=0;count<trials;count++)
293  result += self->bernoulli(self,prob);
294  return result;
295 }
296 
307 long int randomWH_fairdie(Congruence* self, long int lower_inclusive, long int upper_inclusive){
308  long int result;
309  double randvar = self->randomWH(self);
310  if (randvar == 1.0)
311  return upper_inclusive;
312  randvar = lower_inclusive + randvar * (upper_inclusive - lower_inclusive +1);
313  result = randvar; /* compiler will assign result <- floor(randvar) */
314  return result;
315 }
316 
317 
318