Statistics
| Branch: | Revision:

root / include / cnumgen.h @ 47c4b975

History | View | Annotate | Download (13.3 KB)

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