Реалізація випадкової змінної Гаусса за допомогою рівномірної випадкової величини


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_MAXце 32767.

Я хочу змінити дисперсію випадкової величини відповідно до параметра функції. Моє запитання: як я можу змінити дисперсію цієї випадкової величини? Як я можу це зробити?


3
Існують кращі та швидші способи, ніж центральна гранична теорема для генерації Гауссових випадкових величин. Пошук методу Box-Muller для одного; Кажуть, що метод зиггурат ще кращий.
Діліп Сарват


3
За старих часів, коли час виконання був важливим фактором, люди підсумували б випадкових змінних (не ) і відняли щоб отримати просте наближення до стандартної випадкової величини, а потім масштабувати щоб отримати випадкову змінну. (Чому це працює, див. Відповідь @ Гільмара). Для багатьох застосувань цей простий метод спрацював дуже добре, але значення були обмежені діапазоном і ця проста ідея була відкинута убік, коли Six-Sigma стала модною мовою. U ( 0 , 1 ) 100 6 N ( 0 , 1 ) Y = σ X + μ N ( μ , σ 2 ) ( μ - 6 σ , μ + 6 σ )12 U(0,1)1006N(0,1)Y=σX+μN(μ,σ2)(μ6σ,μ+6σ)
Діліп Сарват

@DilipSarwate, можливо, ви повинні опублікувати ці варіанти як відповідь з обґрунтуванням того, чому ми хотіли б це зробити
Іво Фліпс,

@IvoFlipse Відповідь на запитання "Як виправити дисперсію після того, як я виправив середню?" по суті те, що говорить прийнята відповідь Гільмара, як змінено коментарями: виправити дисперсію за допомогою масштабування, а потім повторно виправити середнє значення, а ще краще, не починайте спочатку з виправлення середнього, оскільки вам доведеться повторно виправити пізніше; виправте спочатку дисперсію шляхом масштабування, а потім зафіксуйте середнє значення. ОП не вказує, що він / вона взагалі зацікавлений у кращих методах і навіть не підтримує посилання нібота, яке навіть має код методу Box-Muller. Тож я залишу речі такими, якими вони є.
Діліп Сарват

Відповіді:


6

Ваш початковий алгоритм створює випадкову змінну, рівномірно розподілену між 0 і 1. Варіантність якої становить 1/12. Якщо ви підсумуєте NUM_GAUSSIAN_SUMSекземпляри, це буде дисперсія NUM_GAUSSIAN_SUMS/12. Для того, щоб дійти до цільової дисперсії V, вам потрібно помножити підсумкову випадкову змінну на sqrt(V*12/NUM_GAUSSIAN_SUMS).

Як бічна примітка, шаблон буде добре працювати для поплавців і парних пар, але виникнуть значні числові проблеми з будь-яким типом фіксованої точки.


5

як я можу змінити дисперсію цієї випадкової величини?

За множенням, звичайно. Дисперсія , де є мультипликативной константою і є вашою випадковою величиною, є дисперсії .c X c 2 XcXcXc2X


На жаль, середнє значення - це перевищує середнє значення , і тому один з параметрів, які ОП встановлює перед спробою виправити дисперсію, повинен бути скинутий до потрібного значення. c XcXcX
Діліп Сарват

1
Відцентруйте, масштабуйте, потім відновіть середню. Масштабування по центру центральної випадкової величини не вплине на значення (нуль).
Емре

1

Є ще один спосіб!

Подумайте, що, якби ви хотіли іншого розповсюдження на відміну від Гаусса? У такому випадку ви не можете реально використовувати теорему про центральний межа; як ви потім це вирішите?

Існує спосіб перетворення єдиної випадкової змінної у довільну PDF. Цей метод називається методом зворотного перетворення

Якщо рівномірно розподілений через інтервал (0, 1), тоU[01]

X=FX1(U)

має cdf .FX(x)

Отже, все, що вам потрібно зробити, це застосувати зворотну функцію CDF до змінної, яку ви отримали з єдиного зразка rv.

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

Ось одна з посилань, яка дає доказ цього.


3
> Є ще один спосіб! Це правда, але не має значення для розглянутого питання, який стосується конкретно випадкових змінних Гаусса. Ні гауссовий CDF, ні його зворотна не можуть бути виражені елементарно з використанням кінцевої кількості операцій, тому запропонований метод не може бути використаний.
Діліп Сарват
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.