root / include / cnumgen.h @ 47c4b975
History  View  Annotate  Download (13.3 KB)
1 
//==========================================================================


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 noninteger

121 
* k values, which becomes the alpha parameter. The chisquare 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 acceptancerejection 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 gammadistributed 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 chisquare distribution

183 
* with k degrees of freedom. The chisquare distribution arises

184 
* in statistics. If Yi are k independent random variates from the normal

185 
* distribution with unit variance, then the sumofsquares (sum(Yi^2))

186 
* has a chisquare distribution with k degrees of freedom.

187 
*

188 
* The expected value of this distribution is k. Chi_square with parameter

189 
* k is gammadistributed 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 studentt distribution with

200 
* i degrees of freedom. If Y1 has a normal distribution and Y2 has a chisquare

201 
* distribution with k degrees of freedom then X = Y1 / sqrt(Y2/k)

202 
* has a studentt distribution with k degrees of freedom.

203 
*

204 
* Generation is using relationship to gamma and chisquare.

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 xaxis.

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 leftshift

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 (1p).

307 
*

308 
* Generation is using elementary lookup.

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: AcceptanceRejection 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_ 