Преимущества метода Бокса-Мюллера по сравнению с обратным методом CDF для моделирования нормального распределения?

15

Чтобы моделировать нормальное распределение из набора однородных переменных, есть несколько методов:

  1. Алгоритм Бокса-Мюллера , в котором производится выборка двух независимых равномерных переменных в (0,1) и преобразование их в два независимых стандартных нормальных распределения с помощью:

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

    F(Z)=U
    и получить
    Z=F1(U)

Мой вопрос: что вычислительно более эффективно? Я бы подумал, что это последний метод - но большинство статей, которые я читаю, используют Бокса-Мюллера - почему?

Дополнительная информация:

Обратное значение нормального CDF известно и определяется как:

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

Следовательно:

Z=F1(U)=2erf1(2U1),U(0,1).
user2350366
источник
1
Что такое обратное нормальному cdf? Он не может быть вычислен аналитически, только если исходный CDF аппроксимируется кусочно-линейной функцией.
Артём Соболев
Разве два не тесно связаны? Ящик Мюллера, я считаю, является частным случаем для 2-х вариативного поколения.
ttnphns
Привет, Бармалей, я добавил больше информации выше. У Inverse CDF есть выражение - однако должен быть вычислен вычислительно - так что может быть поэтому предпочтительным является ящик Мюллера? Я предполагал, что erf 1 будет вычисляться в таблицах поиска, так же, как значения sin и cosine ? Значит, не намного дороже в вычислительном отношении? Однако я могу ошибаться. erf1erf1sincosine
user2350366
2
Существуют версии Бокса-Мюллера без греха и косинуса.
Сиань
2
@Dilip Для приложений с очень низкой точностью, таких как компьютерная графика, синус и косинус действительно могут быть оптимизированы с помощью подходящих справочных таблиц. Однако для статистических приложений такая оптимизация никогда не используется. В конечном счете это не совсем любой труднее вычислительном , чем бревна или SQRT , но на современных вычислительных систем элементарных функций , связанных с ехр --including функции тригонометрические - как правило , должны быть оптимизированы ( потому и журнала были основные инструкции пути назад на Intel Чип 8087!), Тогда как erf либо недоступен, либо закодирован на более высоком (= более медленном) уровне. erf1logsqrtexpcoslog
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` `

и с точки зрения посадки в хвост: enter image description here

Следуя комментарию Рэдфорда Нила в моем блоге , я хочу отметить, что по умолчанию 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.
Сиань
источник
3
logΦ1Φ1X1X2Ui1101
2
R 3.0.2rowSumsSqnorm(runif(N))InverseCDF[NormalDistribution[], #] &
1
Я согласен, qnorm(runif(N))даже на 20% быстрее, чемrnorm(N)
Сиань
3
+1 за новую информацию. (На самом деле, ваш оригинальный пост заслуживал отдельного голосования.) Я хотел бы еще раз подчеркнуть, что выводы могут измениться на другой платформе. Например, я бы определенно использовал Box-Mueller при кодировании на C, Fortran или ассемблере, где у меня был бы доступ к чрезвычайно быстрым реализациям алгебраических и элементарных трансцендентных функций, которые были бы намного быстрее, чем любая реализацияΦ1sincos
1
Для сравнения, используя i7-3740QM при 2,7 ГГц и 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.48802для Бокса-Мюллера
Авраама