Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate random number with a non-uniform distribution

Javascript's Math.random() returns a psuedo-random number with "uniform" distribution.

I need to generate a random number in the range [0,1] that is skewed to either side. (Meaning, higher chance of getting more numbers next to 0 or next to 1)

Ideally I would like to have a parameter to set this curve.

I supposed I can do Math.random^2 to get such a result, but what more sophisticated ways are there to achieve this?

like image 623
OpherV Avatar asked Apr 19 '13 17:04

OpherV


2 Answers

I think you want beta distribution with alpha=beta=0.5

It is possible to transform uniform random number to beta distribution using inverse cumulative distribution.

unif = Math.random()

I am not familiar with javascript, but this should be clear:

beta = sin(unif*pi/2)^2

PS: you can generate many such numbers and plot histogram enter image description here

Edit:

For skewing towards 0, transform the beta values as -

beta_left = (beta < 0.5) ? 2*beta : 2*(1-beta);

enter image description here

For skewing towards 1, transform as -

beta_right = (beta > 0.5) ? 2*beta-1 : 2*(1-beta)-1;

enter image description here

like image 138
Nishanth Avatar answered Oct 05 '22 00:10

Nishanth


I just came up with a simpler way to get random numbers skewed to each side, and which doesn't have any dependencies.

This method uses two of Javascript's regular random numbers. The first is multiplied with itself (the larger the exponent, the bigger the skewing effect), and the second chooses which side of the distribution to skew to.

function skewedRandom() {
    const a = Math.pow(Math.random(), 2);
    if (Math.random() < 0.5) {
        return a;
    }
    return 1 - a;
}

In this code the exponent is set to 2. A sample histogram from 10,000 executions with the exponent at 2 as above:

Histogram with exponent 2

With exponent 3:

Histogram with exponent 3

And with exponent 10: Histogram with exponent 10

like image 28
tremby Avatar answered Oct 04 '22 23:10

tremby