Nonuniform Random Number Generators II
June 11, 2009
According to the central limit theorem, a large enough sample from any distribution will converge to a normal distribution. So we might as well use the built in uniform distribution, which has variance 1/12, and the fact that the sum of independent random variables has variance equal to the sum of the variances.
def rnorm(mean=0, sd=1)
n = 30
sum = Array.new(n) { rand }.inject { |m,o| m+o }
zscore = (sum - (n/2.0))/(n/12.0)**0.5
zscore * sd + mean
end
How to make a quick ASCII histogram of the results:
h = Hash.new(0)
1000.times { h[(10*rnorm).to_i.to_f/10] += 1 }
(-35..35).each { |k| puts "#{k.abs/10.0} #{'#' * h[k/10.0]}" }
A javascript version:
function rnorm(mean,sd) {
n=30;
if (null == mean) { mean = 0; }
if (null == sd) { sd = 1;}
for(sum=0, i=0;i < n; i++) {
sum += Math.random();
}
zscore = (sum - (n/2))/Math.pow(n/12,0.5);
return zscore * sd + mean;
}
6/16 update: code fix: tripped up by the fact that 3/2 == 1 in ruby. In javascript 3/2 == 1.5