The Normal (or Gaussian) distribution is a frequently used distribution in statistics. While most programming languages provide a uniformly distributed random number generator, one can derive normally distributed random numbers from a uniform generator.



The task

 Take a uniform random number generator and create a large (you decide how large) set of numbers that follow a normal (Gaussian) distribution. Calculate the dataset's mean and standard deviation, and show a histogram of the data.
 Mention any native language support for the generation of normally distributed random numbers.


Reference

 You may refer to code in Statistics/Basic if available.


' FB 1.05.0 Win64
 
Const pi As Double = 3.141592653589793
Randomize
 
' Generates normally distributed random numbers with mean 0 and standard deviation 1
Function randomNormal() As Double 
  Return Cos(2.0 * pi * Rnd) * Sqr(-2.0 * Log(Rnd))
End Function
 
Sub normalStats(sampleSize As Integer)
  If sampleSize < 1 Then Return 
  Dim r(1 To sampleSize) As Double
  Dim h(-1 To 10) As Integer '' all zero by default
  Dim sum As Double = 0.0
  Dim hSum As Integer = 0
 
  ' Generate 'sampleSize' normally distributed random numbers with mean 0.5 and standard deviation 0.25
  ' calculate their sum
  ' and in which box they will fall when drawing the histogram
  For i As Integer = 1 To sampleSize
    r(i) = 0.5 + randomNormal / 4.0
    sum += r(i)
    If r(i) < 0.0 Then
      h(-1) += 1
    ElseIf r(i) >= 1.0 Then
      h(10) += 1
    Else
      h(Int(r(i) * 10)) += 1
    End If
  Next
 
  For i As Integer = -1 To 10 : hSum += h(i) :  Next
  ' adjust one of the h() values if necessary to ensure hSum = sampleSize
  Dim adj As Integer = sampleSize - hSum
  If adj <> 0 Then
    For i As Integer = -1 To 10 
      h(i) += adj
      If h(i) >= 0 Then Exit For
      h(i) -= adj
    Next
  End If
 
  Dim mean As Double = sum / sampleSize
 
  Dim sd As Double
  sum = 0.0
  ' Now calculate their standard deviation
  For i As Integer = 1 To sampleSize
    sum += (r(i) - mean) ^ 2.0
  Next
  sd  = Sqr(sum/sampleSize)
 
  ' Draw a histogram of the data with interval 0.1 
  Dim numStars As Integer
  ' If sample size > 300 then normalize histogram to 300
  Dim scale As Double = 1.0
  If sampleSize > 300 Then scale = 300.0 / sampleSize 
  Print "Sample size "; sampleSize
  Print
  Print Using "  Mean #.######"; mean;
  Print Using "  SD #.######"; sd
  Print
  For i As Integer = -1 To 10
    If i = -1 Then
      Print Using "< 0.00 : ";
    ElseIf i = 10 Then
      Print Using ">=1.00 : ";
    Else
      Print Using "  #.## : "; i/10.0;
    End If
    Print Using "##### " ; h(i);
    numStars = Int(h(i) * scale + 0.5)
    Print String(numStars, "*")
  Next 
End Sub
 
normalStats 100
Print
normalStats 1000
Print
normalStats 10000
Print
normalStats 100000 
Print
Print "Press any key to quit"
Sleep