Переваги Box-Muller перед зворотним методом CDF для імітації нормального розподілу?


15

Для моделювання нормального розподілу з набору рівномірних змінних існує кілька методик:

  1. Алгоритм Box-Muller , в якому один відбирає дві незалежні рівномірні змінні на (0,1) і перетворює їх у два незалежні стандартні нормальні розподіли за допомогою:

    Z0=2lnU1cos(2πU0)Z1=2lnU1sin(2πU0)
  2. метод CDF , де можна прирівняти нормальний cdf (F(Z)) до уніфікованої змінної:

    F(Z)=U
    і вивести
    Z=F1(U)

Моє запитання: що обчислювально ефективніше? Я думаю, що останній метод - але більшість прочитаних робіт використовую Box-Muller - чому?

Додаткова інформація:

Зворотну сторону нормального CDF знають і задають:

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

Звідси:

Z=F1(U)=2erf1(2U1),U(0,1).

1
Що таке зворотний звичайний cdf? Його неможливо обчислити аналітично, лише якщо оригінальний CDF наближений з кусково-лінійною функцією.
Артем Соболєв

Чи не ті двоє тісно пов’язані між собою? Я вважаю, що Box Muller - це особливий випадок для двовимірної генерації.
ttnphns

Привіт, Бармалі, я додав більше інформації вище. Зворотний CDF має вираз - однак повинен бути обчислений обчислювально - так що, можливо, саме тому поле Muller є кращим? Я припускав erf1 буде обчислений у таблицях пошуку, як і значення гріха та косинуса ? Отже, чи не так набагато дорожче обчислювально? Я, можливо, помиляюся. erf1sincosine
користувач2350366

2
Існують версії Box-Muller без гріха та косинусів.
Сіань

2
@Dilip Для дуже низьких точних програм, таких як комп'ютерна графіка, синус і косинус, дійсно можна оптимізувати за допомогою відповідних таблиць пошуку. Однак для статистичних застосувань така оптимізація ніколи не використовується. Зрештою, обчислити ніж log або sqrt , насправді не важче , але в сучасних обчислювальних системах елементарні функції, пов'язані з exp - включаючи триггерні функції -, як правило, оптимізуються (erf1logsqrtexp і log були основними інструкціями ще на Intel Чіп 8087!), Тоді як erf або недоступний, або кодований на більш високому (= повільнішому) рівні. coslog
whuber

Відповіді:


16

З чисто імовірнісної точки зору обидва підходи є правильними і, отже, рівнозначними. З алгоритмічної точки зору порівняння повинно враховувати як точність, так і витрати на обчислення.

Box-Muller покладається на рівномірний генератор і коштує приблизно стільки ж, скільки і цей рівномірний генератор. Як згадувалося в моєму коментарі, ви можете піти без синусоїдальних або косинусних дзвінків, якщо не без логарифму:

  • генерують поки S = U 2 1 + U 2 21
    U1,U2iidU(1,1)
    S=U12+U221
  • взяти і визначимоX1=ZU1Z=2log(S)/S
    X1=ZU1, X2=ZU2

Загальний алгоритм інверсії вимагає виклику до зворотного нормального cdf, наприклад, qnorm(runif(N))у R, який може бути дорожчим, ніж зазначене вище, і, що ще важливіше, може бути невдалим у хвостах з точки зору точності, якщо тільки квантильна функція не кодується добре.

Слідкуйте за коментарями, зробленими whuber , порівнянням rnorm(N)та qnorm(runif(N))перевагою зворотного cdf, як у часі виконання:

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

і з точки зору прилягання до хвоста: введіть тут опис зображення

Після коментаря Radford Neal у своєму блозі , я хочу зазначити, що за замовчуванням rnormу R використовується метод інверсії, отже, вищезгадане порівняння відображається на інтерфейсі, а не на самому методі моделювання! Процитуйте документацію на 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.

3
logΦ1Φ1X1X2Ui1101

2
R 3.0.2rowSumsSqnorm(runif(N))InverseCDF[NormalDistribution[], #] &

1
Я згоден, qnorm(runif(N))навіть на 20% швидше, ніжrnorm(N)
Сіань

3
Φ1sincos

1
Для порівняння, використовуючи i7-3740QM @ 2.7Ghz та R 3.12, для таких дзвінків: 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)я отримую mean 11.38363 median 11.18718інверсію, а mean 13.00401 median 12.48802Box-Muller
Аврахам
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.