Note
Adapted from the following fortran 77 code algorithm 712, collected algorithms from acm. this work published in transactions on mathematical software, vol. 18, no. 4, december, 1992, pp. 434-435.
The algorithm uses the ratio of uniforms method of a.j. kinderman and j.f. monahan augmented with quadratic bounding curves.
Author:
function random_normal() implicit none !================================================================================================ !< @note !< !< Adapted from the following fortran 77 code !< algorithm 712, collected algorithms from acm. !< this work published in transactions on mathematical software, !< vol. 18, no. 4, december, 1992, pp. 434-435. !< !< + The function random_normal() returns a normally distributed pseudo-random !< number with zero mean and unit variance. !< + The algorithm uses the ratio of uniforms method of a.j. kinderman !< and j.f. monahan augmented with quadratic bounding curves. !< !< Author: !< !< + Alan Miller !< + csiro division of mathematical & information sciences !< + private bag 10, clayton south mdc !< + clayton 3169, victoria, australia !< !< @endnote !------------------------------------------------------------------------------------------------ real(kind=r8) :: random_normal real(kind=r8) :: s, t, a, b, r1, r2, u, v, x, y, q s = 0.449871_r8 t = -0.386595_r8 a = 0.19600_r8 b = 0.25472_r8 r1 = 0.27597_r8 r2 = 0.27846_r8 ! generate p = (u,v) uniform in rectangle enclosing acceptance region do call random_number(u) call random_number(v) v = 1.7156 * (v - 0.5_r8) ! evaluate the quadratic form x = u - s y = abs(v) - t q = x**2 + y*(a*y - b*x) ! accept p if inside inner ellipse if (q < r1) exit ! reject p if outside outer ellipse if (q > r2) cycle ! reject p if outside acceptance region if (v**2 < -4.0*log(u)*u**2) exit enddo ! return ratio of p's coordinates as the normal deviate random_normal = v/u return endfunction random_normal