ROSS
ross-random.c
Go to the documentation of this file.
1 #include <ross.h>
2 
3 /*
4  * tw_rand_init
5  */
6 tw_rng *
7 tw_rand_init(uint32_t v, uint32_t w)
8 {
9  return rng_init(v, w);
10 }
11 
12 /*
13  * tw_rand_integer
14  *
15  * For LP # gen, return a uniform rn from low to high
16  */
17 /**
18  * NOTE: Don't pass negative values to low!
19  */
20 long
21 tw_rand_integer(tw_rng_stream * g, long low, long high)
22 {
23  long safe_high = high;
24 
25  if (safe_high != LONG_MAX) {
26  safe_high += 1;
27  }
28 
29  if (safe_high <= low) {
30  return (0);
31  } else {
32  return (low + (long)(tw_rand_unif(g) * (safe_high - low)));
33  }
34 }
35 
36 unsigned long
37 tw_rand_ulong(tw_rng_stream * g, unsigned long low, unsigned long high)
38 {
39  unsigned long safe_high = high;
40 
41  if (safe_high != ULONG_MAX) {
42  safe_high += 1;
43  }
44 
45  if (safe_high < low) {
46  return (0);
47  } else {
48  return (low + (unsigned long)(tw_rand_unif(g) * (safe_high - low)));
49  }
50 }
51 
52 long
53 tw_rand_binomial(tw_rng_stream * g, long N, double P)
54 {
55  long sucesses, trials;
56 
57  sucesses = 0;
58 
59  for (trials = 0; trials < N; trials++)
60  {
61  if (tw_rand_unif(g) <= P)
62  sucesses++;
63  }
64 
65  return (sucesses);
66 }
67 
68 double
70 {
71  return (-Lambda * log(tw_rand_unif(g)));
72 }
73 
74 double
75 tw_rand_pareto(tw_rng_stream * g, double shape, double scale)
76 {
77  return( scale * 1.0/pow(tw_rand_unif(g), 1/shape) );
78 }
79 
80 double
81 tw_rand_gamma(tw_rng_stream * g, double shape, double scale)
82 {
83  double a, b, q, phi, d;
84 
85  if (shape > 1)
86  {
87  a = 1 / sqrt(2 * shape - 1);
88  b = shape - log(4);
89  q = shape + 1 / a;
90  phi = 4.5;
91  d = 1 + log(phi);
92 
93  while (1)
94  {
95  double U_One = tw_rand_unif(g);
96  double U_Two = tw_rand_unif(g);
97  double V = a * log(U_One / (1 - U_One));
98  double Y = shape * exp(V);
99  double Z = U_One * U_One * U_Two;
100  double W = b + q * V - Y;
101 
102  double temp1 = W + d - phi * Z;
103  double temp2 = log(Z);
104 
105  if (temp1 >= 0 || W >= temp2)
106  return (scale * Y);
107 
108  }
109  } else if (shape == 1)
110  {
111  return (tw_rand_exponential(g, scale));
112  } else
113  {
114  b = (exp(1) + shape) / exp(1);
115 
116  while (1)
117  {
118  double U_One = tw_rand_unif(g);
119  double P = b * U_One;
120 
121  if (P <= 1)
122  {
123  double Y = pow(P, (1 / shape));
124  double U_Two = tw_rand_unif(g);
125 
126  if (U_Two <= exp(-Y))
127  return (scale * Y);
128  } else
129  {
130  double Y = -log((b - P) / shape);
131  double U_Two = tw_rand_unif(g);
132 
133  if (U_Two <= pow(Y, (shape - 1)))
134  return (scale * Y);
135  }
136  }
137  }
138 }
139 
140 long
142 {
143  int count = 1;
144 
145  while (tw_rand_unif(g) > P)
146  count++;
147 
148  return (count);
149 }
150 
151 double
152 tw_rand_normal01(tw_rng_stream * g, unsigned int *rng_calls)
153 {
154 #ifndef RAND_NORMAL
155  tw_error(TW_LOC, "Please compile using -DRAND_NORMAL!");
156 #endif
157 
158 #ifdef RAND_NORMAL
159  *rng_calls = 0;
161 
162  if ((g->tw_normal_flipflop) ||
163  (g->tw_normal_u1< 0.0) ||
164  (g->tw_normal_u1 >= 1.0) ||
165  (g->tw_normal_u2 < 0.0) ||
166  (g->tw_normal_u2 > 1.0))
167  {
168  g->tw_normal_u1 = tw_rand_unif(g);
169  g->tw_normal_u2 = tw_rand_unif(g);
170  *rng_calls = 2;
171 
172  return (sqrt(-2.0 * log(g->tw_normal_u1)) * sin(tw_opi * g->tw_normal_u2));
173  }
174  else
175  {
176  return (sqrt(-2.0 * log(g->tw_normal_u1)) * cos(tw_opi * g->tw_normal_u2));
177  }
178 #endif
179 }
180 
181 double
182 tw_rand_normal_sd(tw_rng_stream * g, double Mu, double Sd, unsigned int *rng_calls)
183 {
184  return ( Mu + (tw_rand_normal01(g, rng_calls) * Sd));
185 }
186 
187 long
188 tw_rand_poisson(tw_rng_stream * g, double Lambda)
189 {
190  double a, b;
191  long count;
192 
193  a = exp(-Lambda);
194  b = 1;
195  count = 0;
196 
197  b = b * tw_rand_unif(g);
198 
199  while (b >= a)
200  {
201  count++;
202  b = b * tw_rand_unif(g);
203  }
204 
205  return (count);
206 }
207 
208 double
209 tw_rand_lognormal(tw_rng_stream * g, double mean, double sd, unsigned int *rng_calls)
210 {
211  return (exp( mean + sd * tw_rand_normal01(g, rng_calls)));
212 }
213 
214 double
215 tw_rand_weibull(tw_rng_stream * g, double mean, double shape)
216 {
217  double scale = mean / tgamma( ((double)1.0 + (double)1.0/shape));
218  return(scale * pow(-log( tw_rand_unif(g)), (double)1.0/shape));
219 }
long tw_rand_binomial(tw_rng_stream *g, long N, double P)
Definition: ross-random.c:53
#define TW_LOC
Definition: ross-extern.h:164
unsigned long tw_rand_ulong(tw_rng_stream *g, unsigned long low, unsigned long high)
Definition: ross-random.c:37
double tw_rand_pareto(tw_rng_stream *g, double shape, double scale)
Definition: ross-random.c:75
tw_rng * tw_rand_init(uint32_t v, uint32_t w)
Definition: ross-random.c:7
tw_rng * rng_init(int v, int w)
Definition: rand-clcg4.c:338
void tw_error(const char *file, int line, const char *fmt,...) NORETURN
Definition: tw-util.c:74
static tw_stime mean
Definition: phold.h:37
double tw_rand_gamma(tw_rng_stream *g, double shape, double scale)
Definition: ross-random.c:81
long tw_rand_geometric(tw_rng_stream *g, double P)
Definition: ross-random.c:141
double tw_rand_lognormal(tw_rng_stream *g, double mean, double sd, unsigned int *rng_calls)
Definition: ross-random.c:209
double tw_normal_u2
Definition: rand-clcg4.h:43
double tw_normal_u1
Definition: rand-clcg4.h:42
double tw_rand_weibull(tw_rng_stream *g, double mean, double shape)
Definition: ross-random.c:215
long tw_rand_integer(tw_rng_stream *g, long low, long high)
Definition: ross-random.c:21
double tw_rand_normal01(tw_rng_stream *g, unsigned int *rng_calls)
Definition: ross-random.c:152
#define tw_rand_unif(G)
Definition: ross-random.h:5
int tw_normal_flipflop
Definition: rand-clcg4.h:44
long tw_rand_poisson(tw_rng_stream *g, double Lambda)
Definition: ross-random.c:188
double tw_rand_normal_sd(tw_rng_stream *g, double Mu, double Sd, unsigned int *rng_calls)
Definition: ross-random.c:182
double tw_rand_exponential(tw_rng_stream *g, double Lambda)
Definition: ross-random.c:69
#define tw_opi
Definition: ross-random.h:4