Statistics
| Branch: | Revision:

root / include / distrib.h @ master

History | View | Annotate | Download (12.5 KB)

1 01873262 Georg Kunz
//==========================================================================
2
// DISTRIB.H
3
//
4
//                     OMNeT++/OMNEST
5
//            Discrete System Simulation in C++
6
//
7
// Random variate generation
8
//
9
// Authors: Werner Sandmann (ws), Kay Michael Masslow (kmm), Kyeong Soo (Joseph) Kim (jk)
10
// Documentation, maintenance: Andras Varga
11
//
12
// @date 11/26/2002 "doxygenification" (kmm)
13
// @date 11/20/2002 some final comments (ws)
14
// @date 10/22/2002 implemented various discrete distributions (kmm)
15
//
16
//==========================================================================
17
18
19
#ifndef __DISTRIB_H_
20
#define __DISTRIB_H_
21
22
#include "simkerneldefs.h"
23
#include "random.h"
24
#include "simtime.h"
25
26
NAMESPACE_BEGIN
27
28
/**
29
 * @ingroup RandomNumbers
30
 * @defgroup RandomNumbersCont Continuous distributions
31
 */
32
//@{
33
34
/**
35
 * Returns a random variate with uniform distribution in the range [a,b).
36
 *
37
 * @param a, b the interval, a<b
38
 * @param rng the underlying random number generator
39
 */
40
SIM_API double uniform(double a, double b, int rng=0);
41
42
/**
43
 * SimTime version of uniform(double,double,int), for convenience.
44
 */
45
inline SimTime uniform(SimTime a, SimTime b, int rng=0) {return uniform(a.dbl(), b.dbl(), rng);}
46
47
/**
48
 * Returns a random variate from the exponential distribution with the
49
 * given mean (that is, with parameter lambda=1/mean).
50
 *
51
 * @param mean mean value
52
 * @param rng the underlying random number generator
53
 */
54
SIM_API double exponential(double mean, int rng=0);
55
56
/**
57
 * SimTime version of exponential(double,int), for convenience.
58
 */
59
inline SimTime exponential(SimTime mean, int rng=0) {return exponential(mean.dbl(), rng);}
60
61
/**
62
 * Returns a random variate from the normal distribution with the given mean
63
 * and standard deviation.
64
 *
65
 * @param mean mean of the normal distribution
66
 * @param stddev standard deviation of the normal distribution
67
 * @param rng the underlying random number generator
68
 */
69
SIM_API double normal(double mean, double stddev, int rng=0);
70
71
/**
72
 * SimTime version of normal(double,double,int), for convenience.
73
 */
74
inline SimTime normal(SimTime mean, SimTime stddev, int rng=0) {return normal(mean.dbl(), stddev.dbl(), rng);}
75
76
/**
77
 * Normal distribution truncated to nonnegative values.
78
 * It is implemented with a loop that discards negative values until
79
 * a nonnegative one comes. This means that the execution time is not bounded:
80
 * a large negative mean with much smaller stddev is likely to result
81
 * in a large number of iterations.
82
 *
83
 * The mean and stddev parameters serve as parameters to the normal
84
 * distribution <i>before</i> truncation. The actual random variate returned
85
 * will have a different mean and standard deviation.
86
 *
87
 * @param mean mean of the normal distribution
88
 * @param stddev standard deviation of the normal distribution
89
 * @param rng the underlying random number generator
90
 */
91
SIM_API double truncnormal(double mean, double stddev, int rng=0);
92
93
/**
94
 * SimTime version of truncnormal(double,double,int), for convenience.
95
 */
96
inline SimTime truncnormal(SimTime mean, SimTime stddev, int rng=0) {return normal(mean.dbl(), stddev.dbl(), rng);}
97
98
/**
99
 * Returns a random variate from the gamma distribution with parameters
100
 * alpha>0, theta>0. Alpha is known as the "shape" parameter, and theta
101
 * as the "scale" parameter.
102
 *
103
 * Some sources in the literature use the inverse scale parameter
104
 * beta = 1 / theta, called the "rate" parameter. Various other notations
105
 * can be found in the literature; our usage of (alpha,theta) is consistent
106
 * with Wikipedia and Mathematica (Wolfram Research).
107
 *
108
 * Gamma is the generalization of the Erlang distribution for non-integer
109
 * k values, which becomes the alpha parameter. The chi-square distribution
110
 * is a special case of the gamma distribution.
111
 *
112
 * For alpha=1, Gamma becomes the exponential distribution with mean=theta.
113
 *
114
 * The mean of this distribution is alpha*theta, and variance is alpha*theta<sup>2</sup>.
115
 *
116
 * Generation: if alpha=1, it is generated as exponential(theta).
117
 *
118
 * For alpha>1, we make use of the acceptance-rejection method in
119
 * "A Simple Method for Generating Gamma Variables", George Marsaglia and
120
 * Wai Wan Tsang, ACM Transactions on Mathematical Software, Vol. 26, No. 3,
121
 * September 2000.
122
 *
123
 * The alpha\<1 case makes use of the alpha\>1 algorithm, as suggested by the
124
 * above paper.
125
 *
126
 * @remark the name gamma_d is chosen to avoid ambiguity with
127
 * a function of the same name
128
 *
129
 * @param alpha >0  the "shape" parameter
130
 * @param theta >0  the "scale" parameter
131
 * @param rng the underlying random number generator
132
 */
133
SIM_API double gamma_d(double alpha, double theta, int rng=0);
134
135
/**
136
 * Returns a random variate from the beta distribution with parameters
137
 * alpha1, alpha2.
138
 *
139
 * Generation is using relationship to Gamma distribution: if Y1 has gamma
140
 * distribution with alpha=alpha1 and beta=1 and Y2 has gamma distribution
141
 * with alpha=alpha2 and beta=2, then Y = Y1/(Y1+Y2) has beta distribution
142
 * with parameters alpha1 and alpha2.
143
 *
144
 * @param alpha1, alpha2 >0
145
 * @param rng the underlying random number generator
146
 */
147
SIM_API double beta(double alpha1, double alpha2, int rng=0);
148
149
/**
150
 * Returns a random variate from the Erlang distribution with k phases
151
 * and mean mean.
152
 *
153
 * This is the sum of k mutually independent random variables, each with
154
 * exponential distribution. Thus, the kth arrival time
155
 * in the Poisson process follows the Erlang distribution.
156
 *
157
 * Erlang with parameters m and k is gamma-distributed with alpha=k
158
 * and beta=m/k.
159
 *
160
 * Generation makes use of the fact that exponential distributions
161
 * sum up to Erlang.
162
 *
163
 * @param k number of phases, k>0
164
 * @param mean >0
165
 * @param rng the underlying random number generator
166
 */
167
SIM_API double erlang_k(unsigned int k, double mean, int rng=0);
168
169
/**
170
 * Returns a random variate from the chi-square distribution
171
 * with k degrees of freedom.  The chi-square distribution arises
172
 * in statistics. If Yi are k independent random variates from the normal
173
 * distribution with unit variance, then the sum-of-squares (sum(Yi^2))
174
 * has a chi-square distribution with k degrees of freedom.
175
 *
176
 * The expected value of this distribution is k. Chi_square with parameter
177
 * k is gamma-distributed with alpha=k/2, beta=2.
178
 *
179
 * Generation is using relationship to gamma distribution.
180
 *
181
 * @param k degrees of freedom, k>0
182
 * @param rng the underlying random number generator
183
 */
184
SIM_API double chi_square(unsigned int k, int rng=0);
185
186
/**
187
 * Returns a random variate from the student-t distribution with
188
 * i degrees of freedom. If Y1 has a normal distribution and Y2 has a chi-square
189
 * distribution with k degrees of freedom then X = Y1 / sqrt(Y2/k)
190
 * has a student-t distribution with k degrees of freedom.
191
 *
192
 * Generation is using relationship to gamma and chi-square.
193
 *
194
 * @param i degrees of freedom, i>0
195
 * @param rng the underlying random number generator
196
 */
197
SIM_API double student_t(unsigned int i, int rng=0);
198
199
/**
200
 * Returns a random variate from the Cauchy distribution (also called
201
 * Lorentzian distribution) with parameters a,b where b>0.
202
 *
203
 * This is a continuous distribution describing resonance behavior.
204
 * It also describes the distribution of horizontal distances at which
205
 * a line segment tilted at a random angle cuts the x-axis.
206
 *
207
 * Generation uses inverse transform.
208
 *
209
 * @param a
210
 * @param b  b>0
211
 * @param rng the underlying random number generator
212
 */
213
SIM_API double cauchy(double a, double b, int rng=0);
214
215
/**
216
 * Returns a random variate from the triangular distribution with parameters
217
 * a <= b <= c.
218
 *
219
 * Generation uses inverse transform.
220
 *
221
 * @param a, b, c   a <= b <= c
222
 * @param rng the underlying random number generator
223
 */
224
SIM_API double triang(double a, double b, double c, int rng=0);
225
226
/**
227
 * Returns a random variate from the lognormal distribution with "scale"
228
 * parameter m and "shape" parameter w. m and w correspond to the parameters
229
 * of the underlying normal distribution (m: mean, w: standard deviation.)
230
 *
231
 * Generation is using relationship to normal distribution.
232
 *
233
 * @param m  "scale" parameter, m>0
234
 * @param w  "shape" parameter, w>0
235
 * @param rng the underlying random number generator
236
 */
237
inline double lognormal(double m, double w, int rng=0)
238
{
239
    return exp(normal(m, w, rng));
240
}
241
242
/**
243
 * Returns a random variate from the Weibull distribution with parameters
244
 * a, b > 0, where a is the "scale" parameter and b is the "shape" parameter.
245
 * Sometimes Weibull is given with alpha and beta parameters, then alpha=b
246
 * and beta=a.
247
 *
248
 * The Weibull distribution gives the distribution of lifetimes of objects.
249
 * It was originally proposed to quantify fatigue data, but it is also used
250
 * in reliability analysis of systems involving a "weakest link," e.g.
251
 * in calculating a device's mean time to failure.
252
 *
253
 * When b=1, Weibull(a,b) is exponential with mean a.
254
 *
255
 * Generation uses inverse transform.
256
 *
257
 * @param a  the "scale" parameter, a>0
258
 * @param b  the "shape" parameter, b>0
259
 * @param rng the underlying random number generator
260
 */
261
SIM_API double weibull(double a, double b, int rng=0);
262
263
/**
264
 * Returns a random variate from the shifted generalized Pareto distribution.
265
 *
266
 * Generation uses inverse transform.
267
 *
268
 * @param a,b  the usual parameters for generalized Pareto
269
 * @param c    shift parameter for left-shift
270
 * @param rng the underlying random number generator
271
 */
272
SIM_API double pareto_shifted(double a, double b, double c, int rng=0);
273
274
//@}
275
276
/**
277
 * @ingroup RandomNumbers
278
 * @defgroup RandomNumbersDiscr Discrete distributions
279
 */
280
//@{
281
282
/**
283
 * Returns a random integer with uniform distribution in the range [a,b],
284
 * inclusive. (Note that the function can also return b.)
285
 *
286
 * @param a, b  the interval, a<b
287
 * @param rng the underlying random number generator
288
 */
289
SIM_API int intuniform(int a, int b, int rng=0);
290
291
/**
292
 * Returns the result of a Bernoulli trial with probability p,
293
 * that is, 1 with probability p and 0 with probability (1-p).
294
 *
295
 * Generation is using elementary look-up.
296
 *
297
 * @param p  0=<p<=1
298
 * @param rng the underlying random number generator
299
 */
300
inline int bernoulli(double p, int rng=0)
301
{
302
    double U = genk_dblrand(rng);
303
    return (p > U) ? 1 : 0;
304
}
305
306
/**
307
 * Returns a random integer from the binomial distribution with
308
 * parameters n and p, that is, the number of successes in n independent
309
 * trials with probability p.
310
 *
311
 * Generation is using the relationship to Bernoulli distribution (runtime
312
 * is proportional to n).
313
 *
314
 * @param n n>=0
315
 * @param p 0<=p<=1
316
 * @param rng the underlying random number generator
317
 */
318
SIM_API int binomial(int n, double p, int rng=0);
319
320
/**
321
 * Returns a random integer from the geometric distribution with parameter p,
322
 * that is, the number of independent trials with probability p until the
323
 * first success.
324
 *
325
 * This is the n=1 special case of the negative binomial distribution.
326
 *
327
 * Generation uses inverse transform.
328
 *
329
 * @param p  0<p<=1
330
 * @param rng the underlying random number generator
331
 */
332
SIM_API int geometric(double p, int rng=0);
333
334
/**
335
 * Returns a random integer from the negative binomial distribution with
336
 * parameters n and p, that is, the number of failures occurring before
337
 * n successes in independent trials with probability p of success.
338
 *
339
 * Generation is using the relationship to geometric distribution (runtime is
340
 * proportional to n).
341
 *
342
 * @param n  n>=0
343
 * @param p  0<p<1
344
 * @param rng the underlying random number generator
345
 */
346
SIM_API int negbinomial(int n, double p, int rng=0);
347
348
//
349
// hypergeometric() doesn't work yet
350
//
351
// /* *
352
//  * Returns a random integer from the hypergeometric distribution with
353
//  * parameters a,b and n.
354
//  *
355
//  * If you have a+b items (a items of type A and b items of type B)
356
//  * and you draw n items from them without replication, this function
357
//  * will return the number of type A items in the drawn set.
358
//  *
359
//  * Generation uses inverse transform due to Fishman (see Banks, page 165).
360
//  *
361
//  * @param a, b  a,b>0
362
//  * @param n     0<=n<=a+b
363
//  * @param rng the underlying random number generator
364
//  */
365
// SIM_API int hypergeometric(int a, int b, int n, int rng=0);
366
367
/**
368
 * Returns a random integer from the Poisson distribution with parameter lambda,
369
 * that is, the number of arrivals over unit time where the time between
370
 * successive arrivals follow exponential distribution with parameter lambda.
371
 *
372
 * Lambda is also the mean (and variance) of the distribution.
373
 *
374
 * Generation method depends on value of lambda:
375
 *
376
 *   - 0<lambda<=30: count number of events
377
 *   - lambda>30: Acceptance-Rejection due to Atkinson (see Banks, page 166)
378
 *
379
 * @param lambda  > 0
380
 * @param rng the underlying random number generator
381
 */
382
SIM_API int poisson(double lambda, int rng=0);
383
384
//@}
385
386
NAMESPACE_END
387
388
389
#endif