Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

when generating normally-distributed random values, what is the most efficient way to define the range?

FYI: random == pseudo-random

A. when generating uniformly-random numbers, I can specify a range, i.e.:

(Math.random()-Math.random())*10+5
//generates numbers between -5 and 15

B. generating a set of random values with a version of Gaussian-esque normal randomness:

//pass in the mean and standard deviation
function randomNorm(mean, stdev) {
  return Math.round((Math.random()*2-1)+(Math.random()*2-1)+(Math.random()*2-1))*stdev+mean);
}

//using the following values:
{
  mean:400, 
  standard_deviation:1
  //results in a range of 397-403, or +-range of 3
},
{
  mean:400, 
  standard_deviation:10
  //results in a range of 372-429, or +-range of 30
},
{
  mean:400, 
  standard_deviation:25
  //results in a range of 326-471, or +-range of 75
}

each one gives me a range of approximately standard_deviation*(+-3) (assuming I left the program running longer).

C. I can calculate this range as follows:

  1. assuming I want a range from 300-500, so var total_range = 200;
  2. my mean is 400, my +-range is total_range/2 (var r = 100)
  3. so standard_deviation would be r/3 or in this case 33.333.

This seems to be working, but I have no idea what I'm doing with math so I feel like an idiot, this solution feels kludgy and not totally accurate.

My question: is there some formula that I'm dancing around that can help me here? my requirements are as follows:

  1. must be able to define a range of numbers accurately.
  2. must be done in JavaScript, as efficiently as possible.

I think maybe I'm close but it's not quite there.

like image 508
jared Avatar asked Nov 29 '22 07:11

jared


1 Answers

Subtracting two random numbers doesn't give you a normal distribution, it will give you numbers that decline linearly on both sides of zero. See the red diagram in this fiddle:

http://jsfiddle.net/Guffa/tvt5K/

To get a good approximation of normal distribution, add six random numbers together. See the green diagram in the fiddle.

So, to get normally distributed random numbers, use:

((Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random()) - 3) / 3

This method is based on the central limit theorem, outlined as the second method here: http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution

like image 114
Guffa Avatar answered Nov 30 '22 21:11

Guffa