Zalety Box-Mullera nad odwrotną metodą CDF do symulacji rozkładu normalnego?

15

Aby zasymulować rozkład normalny z zestawu zmiennych jednorodnych, istnieje kilka technik:

  1. Algorytm Boxa-Mullera , w którym jeden próbkuje dwa niezależne jednolite zmienia się na (0,1) i przekształca je w dwa niezależne standardowe rozkłady normalne poprzez:

    Z0=2lnU1cos(2πU0)Z1=2lnU1sin(2πU0)
  2. metoda CDF , w której można zrównać normalny cdf (F(Z)) do wariantu Uniform:

    F(Z)=U
    i wyprowadzić
    Z=F1(U)

Moje pytanie brzmi: która jest bardziej wydajna obliczeniowo? Myślałem, że to ta druga metoda - ale większość artykułów, które czytam, używa Box-Mullera - dlaczego?

Dodatkowe informacje:

Odwrotność normalnego CDF jest znana i podana przez:

F1(Z)=2erf1(2Z1),Z(0,1).

Stąd:

Z=F1(U)=2erf1(2U1),U(0,1).
użytkownik2350366
źródło
1
Jaka jest odwrotność normalnego cdf? Nie można tego obliczyć analitycznie, tylko jeśli oryginalny CDF jest aproksymowany za pomocą częściowej funkcji liniowej.
Artem Sobolev
Czy te dwa nie są ze sobą blisko powiązane? Uważam, że Box Muller to szczególny przypadek generacji 2-zmiennej.
ttnphns
Cześć Barmaley, powyżej dodałem więcej informacji. Inverse CDF ma wyrażenie - jednak musi być obliczony obliczeniowo - więc może dlatego preferowane jest pole Muller? Zakładałem, że erf 1 będzie obliczany w tabelach odnośników, podobnie jak wartości sin i cosinus ? Czy zatem nie jest to o wiele bardziej kosztowne obliczeniowo? Mogę się jednak mylić. erf1erf1sincosine
user2350366,
2
Istnieją wersje Box-Mullera bez grzechu i cosinusa.
Xi'an
2
@Dilip W przypadku aplikacji o bardzo niskiej precyzji, takich jak grafika komputerowa, sinus i cosinus można rzeczywiście zoptymalizować za pomocą odpowiednich tabel odnośników. Jednak w przypadku zastosowań statystycznych taka optymalizacja nigdy nie jest wykorzystywana. Ostatecznie nie jest tak naprawdę trudniej obliczyć niż log lub sqrt , ale w nowoczesnych systemach komputerowych elementarne funkcje związane z exp - w tym funkcje triggera - mają tendencję do optymalizacji ( cos i log były podstawowymi instrukcjami dawno temu na Intelie 8087 chip!), Podczas gdy erf jest niedostępny lub został zakodowany na wyższym (= wolniejszym) poziomie. erf1logsqrtexpcoslog
whuber

Odpowiedzi:

16

Z czysto probabilistycznego punktu widzenia oba podejścia są poprawne, a zatem równoważne. Z punktu widzenia algorytmu porównanie musi uwzględniać zarówno precyzję, jak i koszt obliczeniowy.

Box-Muller opiera się na jednolitym generatorze i kosztuje mniej więcej tyle samo, co ten jednolity generator. Jak wspomniano w moim komentarzu, możesz uciec bez połączeń sinusoidalnych lub cosinusowych, jeśli nie bez logarytmu:

  • generować S = U 2 1 + U 2 21
    U1,U2iidU(1,1)
    S=U12+U221
  • weź i zdefiniujX1=ZUZ=2log(S)/S
    X1=ZU1, X2=ZU2

Ogólny algorytm inwersji wymaga na przykład wywołania odwrotnego normalnego pliku cdf qnorm(runif(N)) w R, co może być bardziej kosztowne niż powyższe i, co ważniejsze, może zawieść w ogonach pod względem precyzji, chyba że funkcja kwantylu jest dobrze zakodowana.

Aby podążać za komentarzami Whubera , porównanie rnorm(N)i qnorm(runif(N))przewaga odwrotnego cdf, zarówno w czasie wykonania:

> 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` `

i pod względem dopasowania do ogona: enter image description here

Po komentarzu Radforda Neala na moim blogu , chcę zauważyć, że domyślna wartość rnormw R wykorzystuje metodę inwersji, stąd powyższe porównanie odzwierciedla interfejs, a nie samą metodę symulacji! Aby zacytować dokumentację R dotyczącą 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.
Xi'an
źródło
3
(1) Jak są i logΦ1Φ1X1X2Ui1101
2
R 3.0.2rowSumsSqnorm(runif(N))InverseCDF[NormalDistribution[], #] &
1
Zgadzam się, qnorm(runif(N))jest nawet o 20% szybszy niżrnorm(N)
Xi'an
3
Φ1sincos
1
Dla porównania za pomocą i7-3740QM @ 2,7 Ghz i R 3.12 dla następujących wywołań: 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) Dostaję mean 11.38363 median 11.18718inwersję i mean 13.00401 median 12.48802dla Box-Mullera
Avraham