JavaScript Math.random Normal distribution (Gaussian bell curve)?
Since this is the first Google result for "js gaussian random" in my experience, I feel an obligation to give an actual answer to that query.
The Box-Muller transform converts two independent uniform variates on (0, 1) into two standard Gaussian variates (mean 0, variance 1). This probably isn't very performant because of the sqrt
, log
, and cos
calls, but this method is superior to the central limit theorem approaches (summing N uniform variates) because it doesn't restrict the output to the bounded range (-N/2, N/2). It's also really simple:
// Standard Normal variate using Box-Muller transform.
function randn_bm() {
let u = 1 - Math.random(); //Converting [0,1) to (0,1)
let v = Math.random();
return Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v );
}
Normal Distribution Between 0 and 1
Building on Maxwell's Answer, this code uses the Box–Muller transform to give you a normal distribution between 0 and 1 inclusive. It just resamples the values if it's more than 3.6 standard deviations away (less than 0.02% chance).
function randn_bm() {
let u = 0, v = 0;
while(u === 0) u = Math.random(); //Converting [0,1) to (0,1)
while(v === 0) v = Math.random();
let num = Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v );
num = num / 10.0 + 0.5; // Translate to 0 -> 1
if (num > 1 || num < 0) return randn_bm() // resample between 0 and 1
return num
}
Visualizations
n = 100
n = 10,000
n = 10,000,000
Normal Distribution With Min, Max, Skew
This version allows you to give a min, max, and skew factor. See my usage examples at the bottom.
function randn_bm(min, max, skew) {
let u = 0, v = 0;
while(u === 0) u = Math.random() //Converting [0,1) to (0,1)
while(v === 0) v = Math.random()
let num = Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v )
num = num / 10.0 + 0.5 // Translate to 0 -> 1
if (num > 1 || num < 0)
num = randn_bm(min, max, skew) // resample between 0 and 1 if out of range
else{
num = Math.pow(num, skew) // Skew
num *= max - min // Stretch to fill range
num += min // offset to min
}
return num
}
randn_bm(-500, 1000, 1);
randn_bm(10, 20, 0.25);
randn_bm(10, 20, 3);
Here is the JSFiddle for these screenshots: https://jsfiddle.net/2uc346hp/
I want to know if the JavaScript function Math.random is normal distribution or not
Javascript Math.random is not a Normal Distribution(Gaussian bell curve). From ES 2015, 20.2.2.27 "Returns a Number value with positive sign, greater than or equal to 0 but less than 1, chosen randomly or pseudo randomly with approximately uniform distribution over that range, using an implementation-dependent algorithm or strategy. This function takes no arguments." So the provided collection when n is high enough we will get approximately uniform distribution. All values in the interval will have equal probability of appearance(straight line parallel to the x axis, denoting number between 0.0 and 1.0).
how can I get numbers which are normal distribution
There are several ways of getting collection of numbers with a normal distribution. As answered by Maxwell Collard the Box-Muller transform does transform uniform distribution to normal distribution(the code can be found in Maxwell Collard answer).
An answer to another stackoverflow answer to a question has a reply with other uniform distribution to normal distribution algorithms. Such as: Ziggurat, Ratio-of-uniforms, Inverting the CDF Besides one of the answers says that: says:
The Ziggurat algorithm is pretty efficient for this, although the Box-Muller transform is easier to implement from scratch (and not crazy slow).
And finally
I want to rebuilt a Schmidt-machine (German physicist), the machine produces random numbers of 0 or 1 and they have to be normal distributed so I can draw them in Gaussian bell curve.
When we have only two values (0 or 1) Gaussian curve looks the same as uniform distribution with 2 possible values. That is why a simple
function randomZero_One(){
return Math.round(Math.random());
}
would suffice. It would return pseudo-randomly with approximately equal probability values 0 and 1.