I have a random number generator capable of outputting values in the range $(0, 1)$ in a uniform distribution with the peak centered at $0.5$. For my uses, though, I need a value that is normally distributed, even though its accuracy is not super critical.

After a bit of research on the net, I found several methods, such as Inverse Transform Sampling and Probability Integral Transform, but both methods are way too advanced for my extremely limited knowledge in statistics and I do not really understand them.

The other methods I found were the Box-Muller transform and the Ziggurat algorithm, but they seem overkill for my purposes.

Since I was not satisfied with my findings, I proceeded to analyze the data at my disposal, that is: a uniformly distributed variable. I guessed that I could feed this parameter into some kind of function to skew its value, for example I could use a function defined in the interval $(0, 1)$ with a fast ascension to $0.5$, a "plateau" and then another ascension to $1$, something like a rotated Sigmoid function: $$y=\frac{1}{1+e^{-t}}$$

Its inverse function is $y = -ln(\frac{1-x}{x})$, but its asymptotes are of no use for me. This is the final function I have come up with: $$y = -\frac{1}{c}ln\left(\frac{1-\left(\frac{x}{a} + b\right)}{\frac{x}{a} + b}\right) + 0.5$$

With values of about $a = 1.015$, $b = 0.01$ and $c = 10$ I am able to get pretty close to hitting $y=0$ at $x=0$ and $y=1$ at $x=1$: Plot of my function It still has some quirks, for example it drops below 0 for small values of x and does not reach $1$ even for $x = 1$, but I think that I can tweak the parameters to solve that. But my initial doubt still remains: if my variable $x$ has a value in $(0, 1)$ in uniform distribution, will $f(x)$ have a (approximately) normal distribution centered around $0.5$?


2 Answers 2


You can easily use the Box-Muller transform to generate the samples you want: just use two samples at a time. Letting $(U, V)$ be a pair of samples drawn from your generator, the Box-Muller transform gives you a pair of i.i.d. variables

$$ X = \sqrt{-2 \ln U} \cos (2 \pi V) \\ Y = \sqrt{-2 \ln U} \sin (2 \pi V) $$

If you want a pair $X_i, Y_i \sim \mathcal{N}(0.5, \sigma = 1)$, just take

$$ X_i = X + 0.5, Y_i = Y + 0.5 $$


According to my research, the best way to obtain the inversion from U[0, 1] to Normal distribution is by using an algorithm presented in a famous short paper of Moro (1995)....

Function Moro_NormSInv(u As Double) As Double

    'Calculates the Normal Standard numbers given u, the associated uniform number (0, 1)
    'VBA version of the Moro's (1995) code in C
    'Option Base 1 is necessary to be declared before this function for vector elements positioning to work

    Dim c1, c2, c3, c4, c5, c6, c7, c8, c9
    Dim X As Double
    Dim r As Double
    Dim a As Variant
    Dim b As Variant
    a = Array(2.50662823884, -18.61500062529, 41.39119773534, -25.44106049637)
    b = Array(-8.4735109309, 23.08336743743, -21.06224101826, 3.13082909833)
    c1 = 0.337475482272615
    c2 = 0.976169019091719
    c3 = 0.160797971491821
    c4 = 2.76438810333863E-02
    c5 = 3.8405729373609E-03
    c6 = 3.951896511919E-04
    c7 = 3.21767881768E-05
    c8 = 2.888167364E-07
    c9 = 3.960315187E-07
    X = u - 0.5
    If Abs(X) < 0.42 Then
        r = X ^ 2
        r = X * (((a(4) * r + a(3)) * r + a(2)) * r + a(1)) / ((((b(4) * r + b(3)) * r + b(2)) * r + b(1)) * r + 1)
        If X > 0 Then r = Log(-Log(1 - u))
        If X <= 0 Then r = Log(-Log(u))
        r = c1 + r * (c2 + r * (c3 + r * (c4 + r * (c5 + r * (c6 + r * (c7 + r * (c8 + r * c9)))))))
        If X <= 0 Then r = -r
    End If
    Moro_NormSInv = r
End Function
  • $\begingroup$ Could you provide some links to the paper? Also maybe some basic explanation of the overall algorithm $\endgroup$ Jan 14, 2018 at 17:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .