C language produces a standard normal or Gaussian distribution random number
Three ways to produce a normal or Gaussian distribution:
1. Applying the central limit theorem (large number theorem)
1 #include2 #include3 4 #defineNSUM 255 6 DoubleGaussrand ()7 {8 Doublex =0;9 inti;Ten for(i =0; i < NSUM; i++) One { AX + = (Double) rand ()/Rand_max; - } - theX-= NSUM/2.0; -x/= sqrt (NSUM/12.0); - - returnx; +}
2. Using the methods provided by box and Muller, discussed on the Internet in Knuth (more commonly used methods)
Box-muller, usually to get random numbers that obey a normal distribution, The basic idea is to get the random numbers that obey the uniform distribution first; Then, the random number subjected to uniform distribution is changed to obey the normal distribution. Box-muller is a method of generating random numbers. The implicit principle of the box-muller algorithm is very esoteric, but the result is quite simple. If there are two consistent random numbers U1 and U2 within the (0,1] range,
You can use either of the following two equations to calculate the random number Z for a normal distribution:
z = R * cos (θ) or z = R * sin (θ)
wherein, R = sqrt ( -2 * ln (U2)), θ= 2 *π* U1
The normal value Z has a mean of equal to 0 and a standard deviation equal to 1, which can be mapped to a statistic X with a mean of M and a standard deviation of SD using the following equation:
X = m + (Z * SD)
C Code: (in computer programming, the log function ==ln () function, with e as the base of the natural logarithm, log10 is the base of the 10 function)
1#include <stdlib.h>2#include <stdio.h>3 #definePI 3.141592654double
Double Gaussrand ()4 {5 Static DoubleU, V;6 Static intPhase =0;7 DoubleZ;8 9 if(Phase = =0)Ten { OneU = rand ()/(Rand_max + 1. 0); AV = rand ()/(Rand_max +1.0); - Z = sqrt ( -2.0 * log (U)) * Sin (2.0 * PI *) V); - } the Else - { - Z = sqrt (-2.0 * log(U)) * cos (2.0 * PI * V); - } + -Phase =1-phase; + retrn Z; A }
C + + code:
1#include <cstdlib>2#include <cmath>3#include <limits>4 DoubleGenerategaussiannoise (DoubleMuDoubleSigma)5 {6 Const DoubleEpsilon = std::numeric_limits<Double>:: Min ();7 Const DoubleTWO_PI =2.0*3.14159265358979323846;8 9 Static Doublez0, Z1;Ten Static BOOLgenerate; OneGenerate =!generate; A - if(!generate) - returnZ1 * Sigma +mu; the - DoubleU1, U2; - Do - { +u1 = rand () * (1.0/Rand_max); -U2 = rand () * (1.0/Rand_max); + } A while(U1 <=Epsilon); at -Z0 = sqrt (-2.0* Log (u1)) * COS (TWO_PI *U2); -Z1 = sqrt (-2.0* Log (u1)) * Sin (TWO_PI *U2); - returnZ0 * Sigma +mu; -}
3 Using methods originally provided by Marsaglia
1#include <stdlib.h>2#include <stdio.h>3 DoubleGaussrand ()4 {5 Static DoubleV1, V2, S;6 Static intPhase =0;7 DoubleX;8 9 if(Phase = =0)Ten { One Do{ A DoubleU1 = (Double) rand ()/Rand_max; - DoubleU2 = (Double) rand ()/Rand_max; - theV1 =2* U1-1; -V2 =2* U2-1; -S = V1 * V1 + V2 *V2; -} while(S >=1|| S = =0) + -X = V1 * SQRT (-2* LOG (S)/S); + } A Else at { -X = V2 * SQRT (-2* LOG (S)/S); - } - -Phase =1-phase; - returnX; in}
Reference: http://blog.chinaunix.net/uid-22666248-id-357093.html
Https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
C language produces a standard normal or Gaussian distribution random number