## root / include / distrib.h @ e1750c09

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
``` |