//========================================================================== // DISTRIB.H // // OMNeT++/OMNEST // Discrete System Simulation in C++ // // Random variate generation class // // //========================================================================== #ifndef __CNUMGEN_H_ #define __CNUMGEN_H_ #include "simkerneldefs.h" #include "random.h" class cMersenneTwister; class SIM_API cNumberGenerator : public cObject { private: int nrRngs; cRNG** rngs; /** * internal */ double gamma_Marsaglia2000(double a, int rng); /** * internal */ double gamma_MarsagliaTransf(double alpha, int rng); /** * internal */ double unit_normal(int rng); /** * internal */ void checkBounds(int rngId); public: /** * constructor */ cNumberGenerator(unsigned nrNumGens); /** * destructor */ virtual ~cNumberGenerator(); /** * @name Continuous distributions * * @ingroup RandomNumbers */ //@{ /** * Returns a random variate with uniform distribution in the range [a,b). * * @param a, b the interval, abefore truncation. The actual random variate returned * will have a different mean and standard deviation. * * @param mean mean of the normal distribution * @param stddev standard deviation of the normal distribution * @param rng the underlying random number generator */ double truncnormal(double mean, double stddev, int rng=0); /** * Returns a random variate from the gamma distribution with parameters * alpha>0, theta>0. Alpha is known as the "shape" parameter, and theta * as the "scale" parameter. * * Some sources in the literature use the inverse scale parameter * beta = 1 / theta, called the "rate" parameter. Various other notations * can be found in the literature; our usage of (alpha,theta) is consistent * with Wikipedia and Mathematica (Wolfram Research). * * Gamma is the generalization of the Erlang distribution for non-integer * k values, which becomes the alpha parameter. The chi-square distribution * is a special case of the gamma distribution. * * For alpha=1, Gamma becomes the exponential distribution with mean=theta. * * The mean of this distribution is alpha*theta, and variance is alpha*theta2. * * Generation: if alpha=1, it is generated as exponential(theta). * * For alpha>1, we make use of the acceptance-rejection method in * "A Simple Method for Generating Gamma Variables", George Marsaglia and * Wai Wan Tsang, ACM Transactions on Mathematical Software, Vol. 26, No. 3, * September 2000. * * The alpha<1 case makes use of the alpha>1 algorithm, as suggested by the * above paper. * * @remark the name gamma_d is chosen to avoid ambiguity with * a function of the same name * * @param alpha >0 the "shape" parameter * @param theta >0 the "scale" parameter * @param rng the underlying random number generator */ double gamma_d(double alpha, double theta, int rng=0); /** * Returns a random variate from the beta distribution with parameters * alpha1, alpha2. * * Generation is using relationship to Gamma distribution: if Y1 has gamma * distribution with alpha=alpha1 and beta=1 and Y2 has gamma distribution * with alpha=alpha2 and beta=2, then Y = Y1/(Y1+Y2) has beta distribution * with parameters alpha1 and alpha2. * * @param alpha1, alpha2 >0 * @param rng the underlying random number generator */ double beta(double alpha1, double alpha2, int rng=0); /** * Returns a random variate from the Erlang distribution with k phases * and mean mean. * * This is the sum of k mutually independent random variables, each with * exponential distribution. Thus, the kth arrival time * in the Poisson process follows the Erlang distribution. * * Erlang with parameters m and k is gamma-distributed with alpha=k * and beta=m/k. * * Generation makes use of the fact that exponential distributions * sum up to Erlang. * * @param k number of phases, k>0 * @param mean >0 * @param rng the underlying random number generator */ double erlang_k(unsigned int k, double mean, int rng=0); /** * Returns a random variate from the chi-square distribution * with k degrees of freedom. The chi-square distribution arises * in statistics. If Yi are k independent random variates from the normal * distribution with unit variance, then the sum-of-squares (sum(Yi^2)) * has a chi-square distribution with k degrees of freedom. * * The expected value of this distribution is k. Chi_square with parameter * k is gamma-distributed with alpha=k/2, beta=2. * * Generation is using relationship to gamma distribution. * * @param k degrees of freedom, k>0 * @param rng the underlying random number generator */ double chi_square(unsigned int k, int rng=0); /** * Returns a random variate from the student-t distribution with * i degrees of freedom. If Y1 has a normal distribution and Y2 has a chi-square * distribution with k degrees of freedom then X = Y1 / sqrt(Y2/k) * has a student-t distribution with k degrees of freedom. * * Generation is using relationship to gamma and chi-square. * * @param i degrees of freedom, i>0 * @param rng the underlying random number generator */ double student_t(unsigned int i, int rng=0); /** * Returns a random variate from the Cauchy distribution (also called * Lorentzian distribution) with parameters a,b where b>0. * * This is a continuous distribution describing resonance behavior. * It also describes the distribution of horizontal distances at which * a line segment tilted at a random angle cuts the x-axis. * * Generation uses inverse transform. * * @param a * @param b b>0 * @param rng the underlying random number generator */ double cauchy(double a, double b, int rng=0); /** * Returns a random variate from the triangular distribution with parameters * a <= b <= c. * * Generation uses inverse transform. * * @param a, b, c a <= b <= c * @param rng the underlying random number generator */ double triang(double a, double b, double c, int rng=0); /** * Returns a random variate from the lognormal distribution with "scale" * parameter m and "shape" parameter w. m and w correspond to the parameters * of the underlying normal distribution (m: mean, w: standard deviation.) * * Generation is using relationship to normal distribution. * * @param m "scale" parameter, m>0 * @param w "shape" parameter, w>0 * @param rng the underlying random number generator */ inline double lognormal(double m, double w, int rng=0) { return exp(normal(m, w, rng)); } /** * Returns a random variate from the Weibull distribution with parameters * a, b > 0, where a is the "scale" parameter and b is the "shape" parameter. * Sometimes Weibull is given with alpha and beta parameters, then alpha=b * and beta=a. * * The Weibull distribution gives the distribution of lifetimes of objects. * It was originally proposed to quantify fatigue data, but it is also used * in reliability analysis of systems involving a "weakest link," e.g. * in calculating a device's mean time to failure. * * When b=1, Weibull(a,b) is exponential with mean a. * * Generation uses inverse transform. * * @param a the "scale" parameter, a>0 * @param b the "shape" parameter, b>0 * @param rng the underlying random number generator */ double weibull(double a, double b, int rng=0); /** * Returns a random variate from the shifted generalized Pareto distribution. * * Generation uses inverse transform. * * @param a,b the usual parameters for generalized Pareto * @param c shift parameter for left-shift * @param rng the underlying random number generator */ double pareto_shifted(double a, double b, double c, int rng=0); //@} /** * @name Discrete distributions * * @ingroup RandomNumbers */ //@{ /** * Returns a random integer with uniform distribution in the range [a,b], * inclusive. (Note that the function can also return b.) * * @param a, b the interval, a U) ? 1 : 0; } /** * Returns a random integer from the binomial distribution with * parameters n and p, that is, the number of successes in n independent * trials with probability p. * * Generation is using the relationship to Bernoulli distribution (runtime * is proportional to n). * * @param n n>=0 * @param p 0<=p<=1 * @param rng the underlying random number generator */ int binomial(int n, double p, int rng=0); /** * Returns a random integer from the geometric distribution with parameter p, * that is, the number of independent trials with probability p until the * first success. * * This is the n=1 special case of the negative binomial distribution. * * Generation uses inverse transform. * * @param p 0=0 * @param p 030: Acceptance-Rejection due to Atkinson (see Banks, page 166) * * @param lambda > 0 * @param rng the underlying random number generator */ int poisson(double lambda, int rng=0); /** * Produces random integer in range [0,r) using generator 0. */ long intrand(long r); /** * Produces random double in range [0,1) using generator 0. */ double dblrand(); //@} /** * @name Compatibility * * @ingroup RandomNumbers */ //@{ /** * DEPRECATED: use uniform() instead. */ double genk_uniform(double gen_nr, double a, double b); /** * DEPRECATED: use intuniform() instead. */ double genk_intuniform(double gen_nr, double a, double b); /** * DEPRECATED: use exponential() instead. */ double genk_exponential(double gen_nr, double p); /** * DEPRECATED: use normal() instead. */ double genk_normal(double gen_nr, double mean, double variance); /** * DEPRECATED: use truncnormal() instead. */ double genk_truncnormal(double gen_nr, double mean, double variance); //@} }; #endif // __CNUMGEN_H_