De uma perspectiva puramente probabilística, ambas as abordagens são corretas e, portanto, equivalentes. De uma perspectiva algorítmica, a comparação deve considerar a precisão e o custo da computação.
O Box-Muller conta com um gerador uniforme e custa aproximadamente o mesmo que este gerador uniforme. Como mencionado no meu comentário, você pode sair sem chamadas seno ou cosseno, se não sem o logaritmo:
- gerar até S = U 2 1 + U 2 2 ≤ 1
U1,U2∼iidU(−1,1)
S=U21+U22≤1
- toma e definaX1=ZU1Z=−2log(S)/S−−−−−−−−−−√
X1=ZU1, X2=ZU2
O algoritmo de inversão genérico requer a chamada para o cdf normal inverso, por exemplo qnorm(runif(N))
em R, que pode ser mais caro do que o descrito acima e, o que é mais importante, pode falhar nas caudas em termos de precisão, a menos que a função quantil seja bem codificada.
Para acompanhar os comentários feitos pela whuber , a comparação rnorm(N)
e qnorm(runif(N))
está na vantagem do cdf inverso, ambos em tempo de execução:
> system.time(qnorm(runif(10^8)))
sutilisateur système écoulé
10.137 0.120 10.251
> system.time(rnorm(10^8))
utilisateur système écoulé
13.417 0.060 13.472` `
e em termos de ajuste na cauda:
Após um comentário de Radford Neal no meu blog , quero salientar que o padrão rnorm
em R faz uso do método de inversão, portanto a comparação acima está refletindo na interface e não no próprio método de simulação! Para citar a documentação R no RNG:
‘normal.kind’ can be ‘"Kinderman-Ramage"’, ‘"Buggy
Kinderman-Ramage"’ (not for ‘set.seed’), ‘"Ahrens-Dieter"’,
‘"Box-Muller"’, ‘"Inversion"’ (the default), or ‘"user-supplied"’.
(For inversion, see the reference in ‘qnorm’.) The
Kinderman-Ramage generator used in versions prior to 1.7.1 (now
called ‘"Buggy"’) had several approximation errors and should only
be used for reproduction of old results. The ‘"Box-Muller"’
generator is stateful as pairs of normals are generated and
returned sequentially. The state is reset whenever it is selected
(even if it is the current normal generator) and when ‘kind’ is
changed.