Skip to content

Instantly share code, notes, and snippets.

@leeoniya
Forked from bluesmoon/README.md
Created April 19, 2020 20:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leeoniya/6f2268543aa0b6bc6afe78593ed435d8 to your computer and use it in GitHub Desktop.
Save leeoniya/6f2268543aa0b6bc6afe78593ed435d8 to your computer and use it in GitHub Desktop.
Pseudo-Random number generator that follows a Normal or Log-Normal distribution.

Marsaglia-polar.js

This script generates random numbers along a Normal or Log-normal distribution using the Marsaglia polar method.

There are four functions you can use:

  • normalRandom: Generate random numbers that follow a Normal distribution.
  • normalRandomInRange: Generate random numbers that follow a Normal distribution but are clipped to fit within a range
  • normalRandomScaled: Generate random numbers that follow a Normal distribution with a given mean and standard deviation
  • lnRandomScaled: Generate random numbers that follow a Log-normal distribution with a given geometric mean and geometric standard deviation

References:

var spareRandom = null;
function normalRandom()
{
var val, u, v, s, mul;
if(spareRandom !== null)
{
val = spareRandom;
spareRandom = null;
}
else
{
do
{
u = Math.random()*2-1;
v = Math.random()*2-1;
s = u*u+v*v;
} while(s === 0 || s >= 1);
mul = Math.sqrt(-2 * Math.log(s) / s);
val = u * mul;
spareRandom = v * mul;
}
return val;
}
function normalRandomInRange(min, max)
{
var val;
do
{
val = normalRandom();
} while(val < min || val > max);
return val;
}
function normalRandomScaled(mean, stddev)
{
var r = normalRandom();
r = r * stddev + mean;
return Math.round(r);
}
function lnRandomScaled(gmean, gstddev)
{
var r = normalRandom();
r = r * Math.log(gstddev) + Math.log(gmean);
return Math.round(Math.exp(r));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment