Afin de simuler une distribution normale à partir d'un ensemble de variables uniformes, il existe plusieurs techniques:
L'algorithme de Box-Muller , dans lequel on échantillonne deux variables uniformes indépendantes sur et les transforme en deux distributions normales standard indépendantes via:
la méthode CDF , où l'on peut assimiler le cdf normal à une variable uniforme: et dériver
Ma question est la suivante: lequel est le plus efficace sur le plan informatique? Je pense que c'est la dernière méthode - mais la plupart des articles que je lis utilisent Box-Muller - pourquoi?
Information additionnelle:
L'inverse du CDF normal est connu et donné par:
D'où:
normal-distribution
simulation
uniform
user2350366
la source
la source
Réponses:
D'un point de vue purement probabiliste, les deux approches sont correctes et donc équivalentes. D'un point de vue algorithmique, la comparaison doit considérer à la fois la précision et le coût de calcul.
Box-Muller s'appuie sur un générateur uniforme et coûte environ le même prix que ce générateur uniforme. Comme mentionné dans mon commentaire, vous pouvez vous en sortir sans appels sinus ou cosinus, sinon sans le logarithme:
L'algorithme d'inversion générique nécessite l'appel au cdf normal inverse, par exemple
qnorm(runif(N))
dans R, qui peut être plus coûteux que ce qui précède et plus important peut échouer dans les queues en termes de précision, à moins que la fonction quantile ne soit bien codée.Pour suivre les commentaires de whuber , la comparaison
rnorm(N)
etqnorm(runif(N))
l'avantage de l'inverse du cdf, tant en temps d'exécution:et en termes d'ajustement dans la queue:
Suite à un commentaire de Radford Neal sur mon blog , je tiens à souligner que la valeur
rnorm
par défaut dans R utilise la méthode d'inversion, d'où que la comparaison ci-dessus se reflète sur l'interface et non sur la méthode de simulation elle-même! Pour citer la documentation R sur RNG:la source
R 3.0.2
rowSums
qnorm(runif(N))
InverseCDF[NormalDistribution[], #] &
qnorm(runif(N))
est même 20% plus rapide 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)
Je reçoismean 11.38363 median 11.18718
pour l'inversion etmean 13.00401 median 12.48802
pour Box-Muller