Saltar al contenido

JavaScript Math.random Distribución normal (curva de campana gaussiana)?

Solución:

Dado que este es el primer resultado de Google para “js gaussian random” en mi experiencia, siento la obligación de dar una respuesta real a esa consulta.

La transformada de Box-Muller convierte dos variantes uniformes independientes en (0, 1) en dos variantes gaussianas estándar (media 0, varianza 1). Esto probablemente no sea muy eficaz debido a la sqrt, log, y cos llamadas, pero este método es superior a los enfoques del teorema del límite central (sumando N variables uniformes) porque no restringe la salida al rango acotado (-N / 2, N / 2). También es muy simple:

// Standard Normal variate using Box-Muller transform.
function randn_bm() {
    var u = 0, v = 0;
    while(u === 0) u = Math.random(); //Converting [0,1) to (0,1)
    while(v === 0) v = Math.random();
    return Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v );
}

Distribución normal entre 0 y 1

Basado en la respuesta de Maxwell, este código usa la transformada Box-Muller para darle una distribución normal entre 0 y 1 inclusive. Simplemente vuelve a muestrear los valores si está a más de 3.6 desviaciones estándar (menos del 0.02% de probabilidad).

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;
}

Visualizaciones

ingrese la descripción de la imagen aquí

n = 100

ingrese la descripción de la imagen aquí

n = 10,000

ingrese la descripción de la imagen aquí

n = 10,000,000

Distribución normal con mínimo, máximo, sesgo

Esta versión le permite dar un factor mínimo, máximo y de sesgo. Vea mis ejemplos de uso en la parte inferior.

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
    num = Math.pow(num, skew); // Skew
    num *= max - min; // Stretch to fill range
    num += min; // offset to min
    return num;
}

ingrese la descripción de la imagen aquí

randn_bm(-500, 1000, 1);

ingrese la descripción de la imagen aquí

randn_bm(10, 20, 0.25);

ingrese la descripción de la imagen aquí

randn_bm(10, 20, 3);

Aquí está el JSFiddle para estas capturas de pantalla: https://jsfiddle.net/2uc346hp/

Quiero saber si la función de JavaScript Math.random es una distribución normal o no

Javascript Math.random es no a Distribución normal (curva de campana gaussiana). De ES 2015, 20.2.2.27 “Devuelve un valor numérico con signo positivo, mayor o igual a 0 pero menor que 1, elegido aleatoriamente o pseudoaleatoriamente con una distribución aproximadamente uniforme sobre ese rango, utilizando un algoritmo o estrategia dependiente de la implementación. la función no acepta argumentos “. Entonces, la colección proporcionada cuando n es lo suficientemente alta obtendremos una distribución aproximadamente uniforme. Todos los valores en el intervalo tendrán la misma probabilidad de aparición (línea recta paralela al eje x, que denota un número entre 0.0 y 1.0).

¿Cómo puedo obtener números de distribución normal?

Hay varias formas de obtener una colección de números con una distribución normal. Como respondió Maxwell Collard, la transformada Box-Muller transforma la distribución uniforme en distribución normal (el código se puede encontrar en la respuesta de Maxwell Collard).

Una respuesta a otra respuesta de stackoverflow a una pregunta tiene una respuesta con otra distribución uniforme a los algoritmos de distribución normal. Tales como: Zigurat, Proporción de uniformes, Invertir el CDF Además, una de las respuestas dice que: dice:

El algoritmo Ziggurat es bastante eficiente para esto, aunque la transformación Box-Muller es más fácil de implementar desde cero (y no muy lenta).

Y finalmente

Quiero reconstruir una máquina Schmidt (físico alemán), la máquina produce números aleatorios de 0 o 1 y tienen que tener una distribución normal para poder dibujarlos en la curva de campana gaussiana.

Cuando tenemos solo dos valores (0 o 1), la curva gaussiana se ve igual que una distribución uniforme con 2 valores posibles. Es por eso que un simple

function randomZero_One(){
    return Math.round(Math.random());
}

bastaría. Devolvería pseudoaleatoriamente con valores de probabilidad aproximadamente iguales 0 y 1.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *