snowfrogdev
snowfrogdev

Reputation: 6873

How to generate an inclusively bounded Pareto random integer from JavaScript's Math.random

From Wikipedia:

enter image description here

I have tried to implement this formula, even though it is based on using a random number uniformly distributed on (0,1) and produces fractions while Math.random in JavaScript produces numbers on [0,1) and I'm looking for integers with no success:

function getRandomIntInclusivePareto(min, max, alpha = 1) {
  const u = Math.random();
  const x =
    (-(
    (u * max ** alpha - u * min ** alpha - max ** alpha) / 
    (max ** alpha * min ** alpha)
    )) ** -(1 / alpha);

  return x;
}

console.log(getRandomIntInclusivePareto(0, 1024));

What formula (or better yet, code) would allow me to generate inclusively bounded random Pareto integer using Math.random?

I'm looking for this kind of API:

function getRandomParetoIntInclusive(min, max, alpha = 1)

Upvotes: 4

Views: 615

Answers (1)

Severin Pappadeux
Severin Pappadeux

Reputation: 20120

Ok, first there is a bug in your code, you cannot have inclusive 0, console.log(getRandomIntInclusivePareto(0, 1024) won't work.

Second, to get integer you have to compute probabilities for integer and sample values as a discrete distribution. Formula(s) and code you provided is for continuous sampling, it won't work for discrete Paretto. To do discrete sampling, you have to set list (or range) of samples with their probabilities. I'm using https://github.com/jacobmenick/sampling code for discrete sampling. Probabilities are computed via Paretto distribution. Just copy the code from the link and put it on top of the code snippet below in order to run.

Node 12.1, x64 Win10

function getRandomIntInclusivePareto(min, max, alpha = 1.0) {
    var probabilities = []; // probabilities 
    for (var k = min; k <= max; ++k) {
        probabilities.push(1.0/Math.pow(k, alpha)); // computed according to Paretto
    }                                               // would be normalized by SJS

    var disc = SJS.Discrete(probabilities); // discrete sampler, returns value in the [0...probabilities.length-1] range
    q = disc.draw() + min; // back to [min...max] interval

    return q;
}

console.log("Testing Paretto");

var t = getRandomIntInclusivePareto(1, 10, 1.3);

console.log(t);

Upvotes: 1

Related Questions