Реализация гауссовской случайной величины с использованием равномерной случайной величины

11

Я пытаюсь написать функцию C ++, которая будет возвращать гауссовские случайные значения, учитывая их средние значения и дисперсии.

Есть библиотечная функция rand(), которая возвращает случайные числа между 0и RAND_MAX. RAND_MAXне имеет фиксированного значения, но гарантируется, что оно будет не менее . Его PDF является единообразным.2151

Я использую Центральную предельную теорему, чтобы преобразовать это rand()в гауссовскую переменную. То, что я точно делаю, это вызов rand()времени, указанного пользователем, затем сложение его возвращаемых значений, а затем смещение его среднего значения на указанное пользователем среднее.

Гауссовский PDF
На графике выше я вызывал мой генератор гауссовских случайных чисел раз и наносил на график частоты его возвращаемых значений. Как видите, его дисперсия огромна, поскольку она создается суммой множества других случайных значений.107

Он успешно возвращает гауссову переменную с гауссовым PDF и указанным средним значением. Однако проблема заключается в его дисперсии. Я застрял на этом этапе, потому что я не знаю, как изменить его дисперсию на указанное пользователем значение.

Это мой код (пока неполный; параметр "Дисперсия" игнорируется):

template <class T>
T Random::GetGaussian(T Mean /*= 0*/, T Variance /*= 1*/)
{
    T MeanOfSum = NUM_GAUSSIAN_SUMS / static_cast<T>(2);
    T Rand = 0;
    for (uint64_t i=0; i<NUM_GAUSSIAN_SUMS; i++)
    {
        Rand += static_cast<T>(rand()) / RAND_MAX;
    }
    return Rand - (MeanOfSum - Mean);
}

Предположим, что NUM_GAUSSIAN_SUMSэто 100 и RAND_MAX32767.

Я хочу изменить дисперсию случайной величины в соответствии с параметром функции. У меня вопрос, как я могу изменить дисперсию этой случайной величины? Как мне это сделать?

hkBattousai
источник
3
Существуют лучшие и более быстрые способы, чем центральная предельная теорема для генерации гауссовских случайных величин. Поиск метода Бокса-Мюллера для одного; метод зиккурата, как говорят, еще лучше.
Дилип Сарватэ
3
12 U(0,1)1006N(0,1)Y=σX+μ( μ - 6 σ , μ + 6 σ )N(μ,σ2)(μ6σ,μ+6σ)и эта простая идея была отброшена на второй план, когда Six-Sigma стала модным словом.
Дилип Сарватэ
@DilipSarwate, возможно, вы должны опубликовать эти альтернативы в качестве ответа с обоснованием того, почему мы бы предпочли его
Ivo Flipse
@IvoFlipse Ответ на вопрос «Как мне исправить дисперсию после того, как я установил среднее значение?» По сути, это то, что говорит принятый Хилмаром ответ, измененный комментариями: исправьте дисперсию путем масштабирования, а затем исправьте среднее значение, или, что еще лучше, не начинайте сначала с исправления среднего, поскольку вам придется заново исправлять это позже; сначала исправьте дисперсию путем масштабирования, а затем установите среднее значение. OP не указывает, что он / она вообще заинтересован в лучших методах и даже не имеет ссылки nibot, которая даже имеет код для метода Бокса-Мюллера. Поэтому я оставлю вещи такими, какие они есть.
Dilip Sarwate

Ответы:

6

Ваш первоначальный алгоритм создает случайную переменную, которая равномерно распределена между 0 и 1. Разница составляет 1/12. Если вы суммируете NUM_GAUSSIAN_SUMSслучаи этого отклонения NUM_GAUSSIAN_SUMS/12. Чтобы получить целевую дисперсию, Vвам нужно умножить суммированную случайную величину на sqrt(V*12/NUM_GAUSSIAN_SUMS).

Как примечание, шаблон будет работать достаточно хорошо для чисел с плавающей запятой и двойных чисел, но с любым типом с фиксированной запятой возникнут значительные численные проблемы.

Hilmar
источник
5

Как я могу изменить дисперсию этой случайной величины?

cXcXc2X

Эмре
источник
cXcX
1
Сосредоточьте, измените масштаб, затем восстановите среднее. Масштабирование центрированной случайной величины не повлияет на (нулевое) среднее.
Эмре
1

Есть еще один способ!

Подумайте об этом, что, если вы хотите какой-то другой дистрибутив в отличие от гауссовского? В этом случае вы не могли бы использовать теорему о центральном пределе; как ты тогда решаешь это?

Есть способ конвертировать равномерную случайную величину в произвольный PDF. Этот метод называется методом обратного преобразования

U[01]

X=FX1(U)

FX(x)

Следовательно, все, что вам нужно сделать, это применить обратную функцию CDF к переменной, которую вы извлекли из выборки универсального rv.

Кроме того, в отличие от более ранних методов - это не потребует какой-либо итерации и не будет зависеть от того, сколько итераций будет сделано, чтобы сделать результаты ближе к гауссовскому.

Вот одна из ссылок, которая дает доказательство этого.

Дипан Мехта
источник
3
> Есть еще один способ! Верно, но не имеет отношения к рассматриваемому вопросу, который конкретно касается гауссовых случайных величин. Ни CDF Гаусса, ни его обратное не могут быть выражены в элементарных терминах с использованием конечного числа операций, и поэтому предлагаемый метод не может быть использован.
Дилип Сарвате