Para simular una distribución normal a partir de un conjunto de variables uniformes, existen varias técnicas:
El algoritmo Box-Muller , en el que se toman muestras de dos variables uniformes independientes en y se transforman en dos distribuciones normales estándar independientes a través de:
El método CDF , donde se puede equiparar el cdf normal a una variante uniforme: F ( Z ) = U y derivar Z = F - 1 ( U )
Mi pregunta es: ¿cuál es computacionalmente más eficiente? Creo que es el último método, pero la mayoría de los documentos que leo usan Box-Muller, ¿por qué?
Información Adicional:
El inverso del CDF normal es conocido y dado por:
Por lo tanto:
normal-distribution
simulation
uniform
usuario2350366
fuente
fuente
Respuestas:
Desde una perspectiva puramente probabilística, ambos enfoques son correctos y, por lo tanto, equivalentes. Desde una perspectiva algorítmica, la comparación debe considerar tanto la precisión como el costo informático.
Box-Muller depende de un generador uniforme y cuesta casi lo mismo que este generador uniforme. Como se mencionó en mi comentario, puede escapar sin llamadas de seno o coseno, si no sin el logaritmo:
El algoritmo de inversión genérico requiere la llamada al cdf normal inverso, por ejemplo
qnorm(runif(N))
en R, que puede ser más costoso que el anterior y, lo que es más importante, puede fallar en las colas en términos de precisión, a menos que la función cuantil esté bien codificada.Para seguir los comentarios hechos por whuber , la comparación de
rnorm(N)
yqnorm(runif(N))
es una ventaja del cdf inverso, tanto en tiempo de ejecución:y en términos de ajuste en la cola:
Después de un comentario de Radford Neal en mi blog , quiero señalar que el valor predeterminado
rnorm
en R utiliza el método de inversión, por lo tanto, la comparación anterior se refleja en la interfaz y no en el método de simulación en sí. Para citar la documentación de R en RNG:fuente
R 3.0.2
rowSums
qnorm(runif(N))
InverseCDF[NormalDistribution[], #] &
qnorm(runif(N))
es incluso un 20% más rápido quernorm(N)
RNGkind(kind = NULL, normal.kind = 'Inversion');At <- microbenchmark(A <- rnorm(1e5, 0, 1), times = 100L);RNGkind(kind = NULL, normal.kind = 'Box-Muller');Bt <- microbenchmark(B <- rnorm(1e5, 0, 1), times = 100L)
obtengomean 11.38363 median 11.18718
por inversión ymean 13.00401 median 12.48802
por Box-Muller