Articulo de referencia

Transformación de Box-Muller

Visualización de la transformada de Box-Muller: los puntos coloreados en el cuadrado unitario (u₁ , u₂ ) , representados como círculos, se mapean a una gaussiana bidimensional (...

Visualización de la transformada de Box-Muller: los puntos coloreados en el cuadrado unitario (u₁ , u₂ ) , representados como círculos, se mapean a una gaussiana bidimensional (z₀ , z₁ ) , representada como cruces. Los gráficos en los márgenes son las funciones de distribución de probabilidad de z₀ y z₁. z₀ y z₁ no tienen límites; parecen estar en [ −2,5 , 2,5 ] debido a la elección de los puntos ilustrados. En el archivo SVG , coloque el cursor sobre un punto para resaltarlo junto con su punto correspondiente.

En matemáticas , la transformada de Box-Muller , introducida por George Edward Pelham Box y Mervin Edgar Muller , [ 1 ] es un método de muestreo de números aleatorios para generar pares de números aleatorios independientes , estándar y con distribución normal ( esperanza cero , varianza unitaria ), a partir de una fuente de números aleatorios con distribución uniforme . El método fue mencionado explícitamente por primera vez por Raymond EAC Paley y Norbert Wiener en su tratado de 1934 sobre transformadas de Fourier en el dominio complejo. [ 2 ] Dado el prestigio de estos últimos autores y la amplia disponibilidad y uso de su tratado, es casi seguro que Box y Muller conocían bien su contenido .

La transformada de Box-Muller se expresa comúnmente en dos formas. La forma básica, tal como la dan Box y Muller, toma dos muestras de la distribución uniforme en el intervalo(0,1){\displaystyle (0,1)}y los asigna a dos muestras estándar con distribución normal. La forma polar toma dos muestras de un intervalo diferente,[1,1]{\displaystyle [-1,1]}y las asigna a dos muestras con distribución normal sin utilizar funciones seno o coseno.

La transformada de Box-Muller se desarrolló como una alternativa computacionalmente más eficiente al método de muestreo de la transformada inversa . [ 3 ] El algoritmo de zigurat proporciona un método más eficiente para procesadores escalares (por ejemplo, CPU antiguas), mientras que la transformada de Box-Muller es superior para procesadores con unidades vectoriales (por ejemplo, GPU o CPU modernas ). [ 4 ]

Forma básica

SuponerU1{\displaystyle U_{1}}yU2{\displaystyle U_{2}}son muestras independientes elegidas de la distribución uniforme en el intervalo unitario(0,1){\displaystyle (0,1)}. Colocar

Z0=2lnU1porque(2πU2)=Rporque(Θ){\displaystyle Z_{0}={\sqrt {-2\ln U_{1}}}\cos(2\pi U_{2})=R\cos(\Theta )}

y

Z1=2lnU1pecado(2πU2)=Rpecado(Θ).{\displaystyle Z_{1}={\sqrt {-2\ln U_{1}}}\sin(2\pi U_{2})=R\sin(\Theta ).}

EntoncesZ0{\displaystyle Z_{0}}yZ1{\displaystyle Z_{1}}son variables aleatorias independientes con una distribución normal estándar .

La derivación [ 5 ] se basa en una propiedad de un sistema cartesiano bidimensional , donde incógnita{\displaystyle X}yY{\displaystyle Y}Las coordenadas se describen mediante dos variables aleatorias independientes y con distribución normal; las variables aleatorias para R 2 y Θ (mostradas arriba) en las coordenadas polares correspondientes también son independientes y pueden expresarse como R2=2lnU1{\displaystyle R^{2}=-2\cdot \ln U_{1}\,} y Θ=2πU2.{\displaystyle \Theta =2\pi U_{2}.\,}

Dado que R² es el cuadrado de la norma de la variable normal bivariada estándar ( X , Y ) , tiene una distribución chi-cuadrado con dos grados de libertad. En el caso especial de dos grados de libertad, la distribución chi-cuadrado coincide con la distribución exponencial , y la ecuación para anterior es una forma sencilla de generar la variable exponencial requerida.

Forma polar

Se utilizan dos valores distribuidos uniformemente, u y v, para obtener el valor s = R² , que también está distribuido uniformemente. A continuación , se aplican las definiciones de seno y coseno a la forma básica de la transformada de Box-Muller para evitar el uso de funciones trigonométricas.

La forma polar fue propuesta inicialmente por James Bell [ 6 ] y posteriormente modificada por R. Knop [ 7 ] . Si bien se han descrito varias versiones diferentes del método polar, aquí se describirá la versión de R. Knop, ya que es la más utilizada, en parte debido a su inclusión en Numerical Recipes . D. Knuth describe una forma ligeramente diferente como "Algoritmo P" en The Art of Computer Programming [ 8 ] .

Dados u y v , independientes y distribuidos uniformemente en el intervalo cerrado [ −1, +1 ] , definimos s = R 2 = u 2 + v 2 . Si s = 0 o s ≥ 1 , descartamos u y v , y probamos con otro par ( u , v ) . Debido a que u y v están distribuidos uniformemente y a que solo se han admitido puntos dentro del círculo unitario , los valores de s también estarán distribuidos uniformemente en el intervalo abierto (0, 1) . Esto último se puede comprobar calculando la función de distribución acumulativa para s en el intervalo (0, 1) . Esta es el área de un círculo con radios{\textstyle {\sqrt {s}}}, dividido porπ{\displaystyle \pi }. A partir de esto, encontramos que la función de densidad de probabilidad tiene el valor constante 1 en el intervalo (0, 1) . Igualmente, el ángulo θ dividido por2π{\displaystyle 2\pi }se distribuye uniformemente en el intervalo [ 0, 1) y es independiente de s .

Ahora identificamos el valor de s con el de U 1 yθ/(2π){\displaystyle \theta /(2\pi )}con el de U 2 en la forma básica. Como se muestra en la figura, los valores deporqueθ=porque2πU2{\displaystyle \cos \theta =\cos 2\pi U_{2}}ypecadoθ=pecado2πU2{\displaystyle \sin \theta =\sin 2\pi U_{2}}en su forma básica se puede reemplazar con las proporcionesporqueθ=/R=/s{\displaystyle \cos \theta =u/R=u/{\sqrt {s}}}ypecadoθ=v/R=v/s{\textstyle \sin \theta =v/R=v/{\sqrt {s}}}, respectivamente. La ventaja es que se puede evitar el cálculo directo de las funciones trigonométricas . Esto resulta útil cuando el cálculo de las funciones trigonométricas es más costoso que la simple división que las reemplaza.

Así como la forma básica produce dos desviaciones normales estándar, también lo hace este cálculo alternativo. z0=2lnU1porque(2πU2)=2lns(s)=2lnss{\displaystyle z_{0}={\sqrt {-2\ln U_{1}}}\cos(2\pi U_{2})={\sqrt {-2\ln s}}\left({\frac {u}{\sqrt {s}}}\right)=u\cdot {\sqrt {\frac {-2\ln s}{s}}}} y z1=2lnU1pecado(2πU2)=2lns(vs)=v2lnss.{\displaystyle z_{1}={\sqrt {-2\ln U_{1}}}\sin(2\pi U_{2})={\sqrt {-2\ln s}}\left({\frac {v}{\sqrt {s}}}\right)=v\cdot {\sqrt {\frac {-2\ln s}{s}}}.}

Contrastando las dos formas

El método polar se diferencia del método básico en que es un tipo de muestreo por rechazo . Descarta algunos números aleatorios generados, pero puede ser más rápido que el método básico porque es más sencillo de calcular (siempre que el generador de números aleatorios sea relativamente rápido) y es más robusto numéricamente. [ 9 ] Evitar el uso de costosas funciones trigonométricas mejora la velocidad con respecto a la forma básica. [ 6 ] Descarta 1 − π /4 ≈ 21,46% del total de pares de números aleatorios distribuidos uniformemente de entrada generados, es decir, descarta 4/ π − 1 ≈ 27,32% de pares de números aleatorios distribuidos uniformemente por cada par de números aleatorios gaussianos generados, lo que requiere 4/ π ≈ 1,2732 números aleatorios de entrada por cada número aleatorio de salida.

La forma básica requiere dos multiplicaciones, 1/2 logaritmo , 1/2 raíz cuadrada y una función trigonométrica para cada variable normal. [ 10 ] En algunos procesadores, el coseno y el seno del mismo argumento se pueden calcular en paralelo usando una sola instrucción. En particular, para máquinas basadas en Intel, se puede usar la instrucción de ensamblador fsincos o la instrucción expi (generalmente disponible desde C como una función intrínseca ) para calcular funciones complejas. exp(iz)=miiz=porquez+ipecadoz,{\displaystyle \exp(iz)=e^{iz}=\cos z+i\sin z,\,} y simplemente separa las partes reales de las imaginarias.

Nota: Para calcular explícitamente la forma polar compleja, utilice las siguientes sustituciones en la forma general,

Dejarr=ln(1){\textstyle r={\sqrt {-\ln(u_{1})}}}yz=2π2.{\textstyle z=2\pi u_{2}.}Entonces rmiiz=ln(1)mii2π2=2ln(1)[porque(2π2)+ipecado(2π2)].{\displaystyle re^{iz}={\sqrt {-\ln(u_{1})}}e^{i2\pi u_{2}}={\sqrt {-2\ln(u_{1})}}\left[\cos(2\pi u_{2})+i\sin(2\pi u_{2})\right].}

La forma polar requiere 3/2 multiplicaciones, 1/2 logaritmo, 1/2 raíz cuadrada y 1/2 división para cada variable normal. El efecto es reemplazar una multiplicación y una función trigonométrica con una sola división y un bucle condicional.

Truncamiento de colas

Cuando se utiliza una computadora para producir una variable aleatoria uniforme, inevitablemente tendrá algunas imprecisiones porque existe un límite inferior sobre cuán cerca pueden estar los números de 0. Si el generador utiliza 32 bits por valor de salida, el número distinto de cero más pequeño que se puede generar es232{\displaystyle 2^{-32}}. CuandoU1{\displaystyle U_{1}}yU2{\displaystyle U_{2}}son iguales a esto la transformada de Box-Muller produce una desviación aleatoria normal igual aδ=2ln(232)porque(2π232)6.660{\textstyle \delta ={\sqrt {-2\ln(2^{-32})}}\cos(2\pi 2^{-32})\approx 6.660}Esto significa que el algoritmo no producirá variables aleatorias que se encuentren a más de 6,660 desviaciones estándar de la media. Esto corresponde a una proporción de2(1Φ(δ))2.738×1011{\displaystyle 2(1-\Phi (\delta ))\simeq 2.738\times 10^{-11}}perdido debido al truncamiento, dondeΦ(δ){\displaystyle \Phi (\delta )}es la distribución normal acumulativa estándar. Con 64 bits, el límite se extiende aδ=9.419{\displaystyle \delta =9.419}desviaciones estándar, para las cuales2(1Φ(δ))<5×1021{\displaystyle 2(1-\Phi (\delta ))<5\times 10^{-21}}.

El número positivo más pequeño que se puede representar en números de punto flotante de precisión simple y doble según el estándar IEEE es subnormal y es2149{\displaystyle 2^{-149}}y21074{\displaystyle 2^{-1074}}respectivamente. Los números normales más pequeños son(21262149){\displaystyle (2^{-126}-2^{-149})}y(2102221074){\displaystyle (2^{-1022}-2^{-1074})}La mayoría de los generadores de números aleatorios que producen un número de punto flotante con distribución uniforme no utilizan esta precisión, ya que funcionan simplemente convirtiendo un entero aleatorio de L bits a punto flotante y luego dividiéndolo por 2L o 2L - 1. [ 11 ] Es posible escribir un algoritmo que utilice esta precisión adicional, aunque para acceder a ella será necesario consumir más bits aleatorios. [ 12 ]

Implementación

C++

La transformación estándar de Box-Muller genera valores de la distribución normal estándar ( es decir, desviación normal estándar ) con media 0 y desviación estándar 1. La implementación que se muestra a continuación en C++ estándar genera valores de cualquier distribución normal con mediaμ{\displaystyle \mu }y varianzaσ2{\displaystyle \sigma ^{2}}. SiZ{\displaystyle Z}es una desviación normal estándar, entoncesincógnita=Zσ+μ{\displaystyle X=Z\sigma +\mu }tendrá una distribución normal con mediaμ{\displaystyle \mu }y desviación estándarσ{\displaystyle \sigma }El generador de números aleatorios se ha inicializadogenerateGaussianNoise para garantizar que las llamadas secuenciales a la función devuelvan nuevos valores pseudoaleatorios .

#include <cmath> #include <limits> #include <random> #include <utility>//"mu" es la media de la distribución y "sigma" es la desviación estándar. std :: pair < ​​double , double > generateGaussianNoise ( double mu , double sigma ) { constexpr double two_pi = 2.0 * M_PI ;// Inicializa el generador de números aleatorios uniformes (runif) en un rango de 0 a 1 static std :: mt19937 rng ( std :: random_device {}()); // Motor mersenne_twister_engine estándar inicializado con rd() static std :: uniform_real_distribution <> runif ( 0.0 , 1.0 );//crea dos números aleatorios, asegúrate de que u1 sea mayor que cero double u1 , u2 ; do { u1 = runif ( rng ); } while ( u1 == 0 ); u2 = runif ( rng );//calcula z0 y z1 auto mag = sigma * sqrt ( -2.0 * log ( u1 )); auto z0 = mag * cos ( two_pi * u2 ) + mu ; auto z1 = mag * sin ( dos_pi * u2 ) + mu ;return std :: make_pair ( z0 , z1 ); }

JavaScript

/* Sintaxis: * * [ x, y ] = rand_normal(); * x = rand_normal()[0]; * y = rand_normal()[1]; */ function rand_normal () { let theta = 2 * Math . PI * Math . random (); let R = Math . sqrt ( - 2 * Math . log ( Math . random ())); let x = R * Math . cos ( theta ); let y = R * Math . sin ( theta );devolver [ x , y ]; }

Julia

"""  muestra de Boxmuller(N)Genera `2N` muestras de la distribución normal estándar usando el método de Box-Muller. """ function boxmullersample ( N ) z = Array { Float64 }( undef , N , 2 ); for i in axes ( z , 1 ) z [ i , : ] .= sincospi ( 2 * rand ()); z [ i , : ] .*= sqrt ( - 2 * log ( rand ())); end vec ( z ) end"""  boxmullersample(n,μ,σ)Genera `n` muestras de la distribución normal con media `μ` y desviación estándar `σ` utilizando el método de Box-Muller. """ function boxmullersample ( n , μ , σ ) μ .+ σ * boxmullersample ( cld ( n , 2 ))[ 1 : n ]; end

Véase también

Referencias

  1. Box, GEP; Muller, Mervin E. (1958). "Una nota sobre la generación de desviaciones normales aleatorias" . The Annals of Mathematical Statistics . 29 (2): 610– 611. doi : 10.1214/aoms/1177706645 . JSTOR 2237361 . 
  2. Raymond EAC Paley y Norbert Wiener Transformadas de Fourier en el dominio complejo, Nueva York: American Mathematical Society (1934) §37.
  3. Kloeden y Platen , Soluciones numéricas de ecuaciones diferenciales estocásticas , págs. 11-12
  4. Howes, Lee; Thomas, David (2008). GPU Gems 3 - Generación eficiente de números aleatorios y su aplicación mediante CUDA . Pearson Education, Inc. ISBN 978-0-321-51526-1.
  5. Sheldon Ross, Un primer curso de probabilidad , (2002), págs. 279–281
  6. 1 2 Bell, James R. (1968). "Algoritmo 334: Desviaciones aleatorias normales" . Communications of the ACM . 11 (7): 498. doi : 10.1145/363397.363547 .
  7. Knop, R. (1969). "Comentario sobre el algoritmo 334 [ G5 ] : Desviaciones aleatorias normales" . Communications of the ACM . 12 (5): 281. doi : 10.1145/362946.362996 .
  8. Knuth, Donald (1998). El arte de la programación informática: Volumen 2: Algoritmos seminuméricos . Addison-Wesley. pág. 122. ISBN  0-201-89684-2.
  9. Everett F. Carter, Jr., La generación y aplicación de números aleatorios , Forth Dimensions (1994), Vol. 16, No. 1 y 2.
  10. La evaluación de 2 π U 1 se cuenta como una multiplicación porque el valor de 2 π se puede calcular de antemano y usar repetidamente.
  11. Goualard, F. (2020). "Generación de números aleatorios de punto flotante mediante la división de enteros: un estudio de caso". Ciencia Computacional – ICCS 2020. ICCS. Notas de clase en Ciencias de la Computación. Vol. 12138. pp. 15–28 . doi : 10.1007/978-3-030-50417-5_2 . ISBN   978-3-030-50416-8. PMC 7302591 . S2CID 219889587 .  
  12. Campbell, Taylor R. (2014). "Números de punto flotante aleatorios uniformes: Cómo generar un número de punto flotante de doble precisión en [ 0, 1 ] de forma uniforme y aleatoria a partir de una fuente aleatoria uniforme de bits" . Recuperado el 4 de septiembre de 2021 .
  • Weisstein, Eric W. "Transformación de Box-Muller" . MathWorld .
  • Cómo convertir una distribución uniforme en una distribución gaussiana (código C)