Перетворення Бокса-Мюллера

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

Перетвóрення Боксу — Мюллераметод моделювання стандартних нормально розподілених випадкових величин. Має два варіанти. Метод є точним, на відміну, наприклад, від методів що ґрунтуються на центральній граничній теоремі.

Метод був опублікований в 1958 році Джорджем Боксом і Мервіном Мюллером.

Перший варіант

[ред. | ред. код]

Нехай і   — незалежні випадкові величини, рівномірно розподілені на інтервалі . Обчислимо і за формулами:

Тоді і будуть незалежні і розподілені нормально з математичним сподіванням 0 і дисперсією 1. При реалізації на комп'ютері зазвичай швидше не обчислювати обидві тригонометричні функції — і  — а розрахувати одну з них через іншу. Ще краще скористатися натомість другим варіантом перетворення Боксу — Мюллера.

Другий варіант

[ред. | ред. код]

Нехай і   — незалежні випадкові величини, рівномірно розподілені на відрізку . Обчислимо . Якщо виявиться, що чи , то значення і слід «викинути» і згенерувати наново. Як тільки виконається умова за формулами

і

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

Коефіцієнт використовування базових випадкових величин для першого варіанту, очевидно, дорівнює одиниці. Для другого варіанту це відношення площі кола одиничного радіусу до площі квадрата із стороною два, тобто . Проте, на практиці другий варіант зазвичай виявляється швидшим, за рахунок того, що в ньому використовується тільки одна трансцендентна функція . Ця перевага для більшості реалізацій переважує необхідність генерації більшого числа рівномірно розподілених випадкових величин.

Перехід до загального нормального розподілу

[ред. | ред. код]

Після отримання стандартної нормальної випадкової величини , можна легко перейти до величини , що є нормально розподіленою з математичним очікуванням і стандартним відхиленням за формулою:

Це вже не є частиною перетворення Боксу — Мюллера, але дозволяє завершити генерацію нормальної випадкової величини.

Реалізація

[ред. | ред. код]

Приклад реалізації на мові C# генерації нормально розподілених випадкових величин за допомогою другого варіанту перетворення.

//Об'єкт для генерації рівномірно-розподіленої величини
Random RND = new Random();
//Ця змінна зберігає друге прогенероване ще не використане значення, для прискорення послідовної генерації багатьох значень
double LastFreeValue = double.NaN;

/// <summary>
/// Нормально розподілена випадкова величина
/// </summary>
double RNDGauss_BoxMuller()
    {
        if(double.IsNaN(LastFreeValue))
        {
            //якщо невикористаного значення немає - генерується наступна пара
            double x = 0, y = 0, R = 2;
            while (R > 1)
            {
                //генеруються випадкові x та y, поки не буде виконана умова R <= 1
                x = RND.NextDouble() * 2 - 1;
                y = RND.NextDouble() * 2 - 1;
                R = x * x + y * y;
            }
            double t = Math.Sqrt(-2 * Math.Log(R) / R);
            //друге випадкове значення зберігається для подальшого використання
            LastFreeValue = y * t;
            //повертається перше прогенероване випадкове значення
            return x * t;
        }
        else
        {
            //якщо є невикористане значення - воно повертається і обнуляється
            double Z1 = LastFreeValue;
            LastFreeValue = double.NaN;
            return Z1;
        }
    }