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