С чисто вероятностной точки зрения оба подхода верны и, следовательно, эквивалентны. С алгоритмической точки зрения сравнение должно учитывать как точность, так и стоимость вычислений.
Box-Muller полагается на равномерный генератор и стоит примерно столько же, сколько и этот равномерный генератор. Как упоминалось в моем комментарии, вы можете обойтись без синус или косинус, если не без логарифма:
- генерировать пока S = U 2 1 + U 2 2 ≤ 1
U1,U2∼iidU(−1,1)
S=U21+U22≤1
- принять и определить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` `
и с точки зрения посадки в хвост:
Следуя комментарию Рэдфорда Нила в моем блоге , я хочу отметить, что по умолчанию rnorm
в R используется метод инверсии, следовательно, приведенное выше сравнение отражает интерфейс, а не сам метод моделирования! Чтобы процитировать 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.