Random Noise Generators

When you need to use randomness in your code, you only have a few tools at your disposal. Uniform sampling is built into Javascript with Math.random() and there are other libraries out there to get normally distributed random numbers, and more exotic distributions like Pareto, etc.

What if you want to sample from something else, like a cubic function for example: f(x)=x3f(x) = x^3? How do you that? The method required is called the Inverse Transform Sampling Technique.

For a given probability function f(x)f(x), if you integrate this function to get the cumulative distributions function F(x)F(x), you can then sample uniformily on the y-axis and the corresponding x position will be sampled from the original function.

In the case of the commonly used probability functions, like Gaussian, etc, there is a nice closed form solution, but for other functions it makes more sense to do a lookup from samples of the CDF.


The process is fairly simple:

  1. For the given Probability Density Function (PDF) f(x)f(x), generate N samples
  2. Integrate the function to get the Cumulative Density Function (CDF) F(x)F(x)
  3. Generate a random variable yy from the uniform distribution and do a lookup of the corresponding xx value


Here is an example of how such a function could be implemented in TypeScript.

export function randomF(f: (x: number) => number, nPts = 1000) {
  const dx = 1 / (nPts - 1);

  const pdfData: [number, number][] = Array.from({
    length: nPts,
  }).map((_, idx) => [idx * dx, f(idx * dx)]);

  const cdfData: [number, number][] = pdfData
    .reduce((a, b) => [...a, [b[0], a[a.length - 1][1] + dx * b[1]]], [[0, 0]]);

  this.pdfData = pdfData;
  this.cdfData = cdfData;

  const maxD = Math.max(...cdfData.map((d) => d[1]));

  return function () {
    const x = Math.random() * maxD;
    const idx = cdfData.findIndex((d) => d[1] > x);

    return cdfData[idx][0];

Example Usage

And here is how you could use that function to generate random samples from a cubic function:

const rGen = randomF((x) => x ** 3);
const sample = rGen();



f(x)=1f(x) = 1



f(x)=xf(x) = x


f(x)=x3f(x) = x^3
f(x)=x3+0.2f(x) = x^3 + 0.2
f(x)=x2+(1x)10f(x) = x^2 + (1 - x)^{10}

Pareto Distribution


f(x)=1+cos(2πx)f(x) = 1 + \cos(2\pi x)
f(x)=1+cos(2πx+π)f(x) = 1 + \cos(2\pi x + \pi)