Implementowanie losowej zmiennej Gaussa za pomocą jednolitej zmiennej losowej

11

Próbuję napisać funkcję C ++, która zwróci losowe wartości Gaussa, biorąc pod uwagę ich środki i wariancje.

Istnieje funkcja biblioteczna rand(), która zwraca liczby losowe między 0i RAND_MAX. RAND_MAXnie ma stałej wartości, ale gwarantuje się, że będzie to co najmniej . Jego plik PDF jest jednolity.2)15-1

Korzystam z centralnego twierdzenia granicznego, aby przekształcić to rand()w zmienną Gaussa. Dokładnie robię to, aby zadzwonić rand()do użytkownika podanego czasu, a następnie dodać jego zwracane wartości, a następnie przenieść jego średnią na podaną przez użytkownika średnią.

Gaussowski PDF
W kreślenia powyżej, zadzwoniłem do mojego generatora liczb losowych Gaussa dla razy, i wykreślone częstotliwości jego wartości zwracanych. Jak widać, jego wariancja jest ogromna, ponieważ jest tworzona przez sumę wielu innych losowych wartości.107

Z powodzeniem zwraca zmienną Gaussa z Gaussowskim plikiem PDF i określoną wartością średnią. Problemem jest jednak jej wariancja. Utknąłem w tym momencie, ponieważ nie wiem, jak zmienić jego wariancję na wartość określoną przez użytkownika.

To jest mój kod (na razie niekompletny; parametr „Wariancja” jest ignorowany):

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);
}

Załóżmy, że NUM_GAUSSIAN_SUMSto 100, a RAND_MAX32767.

Chcę zmienić wariancję zmiennej losowej zgodnie z parametrem funkcji. Moje pytanie brzmi: jak mogę zmienić wariancję tej zmiennej losowej? Jak mogę to zrobić?

hkBattousai
źródło
3
Istnieją lepsze i szybsze sposoby niż centralne twierdzenie graniczne do generowania losowych zmiennych Gaussa. Wyszukaj metodę Box-Mullera dla jednego; mówi się, że metoda ziggurat jest jeszcze lepsza.
Dilip Sarwate
3
12 U(0,1)1006N.(0,1)Y=σX+μN.(μ,σ2))(μ-6σ,μ+6σ)
@DilipSarwate być może powinieneś zamieścić te alternatywy jako odpowiedź z uzasadnieniem, dlaczego wolimy
Ivo Flipse
@IvoFlipse Odpowiedź na pytanie „Jak naprawić wariancję po ustaleniu średniej?” jest zasadniczo tym, co mówi zaakceptowana odpowiedź Hilmara, zmodyfikowana komentarzami: napraw wariancję poprzez skalowanie, a następnie ponownie ustal średnią, albo jeszcze lepiej, nie zaczynaj od ustalenia średniej, ponieważ będziesz musiał ją naprawić to później; napraw wariancję najpierw poprzez skalowanie, a następnie ustal średnią. OP nie oznacza, że ​​w ogóle interesują go lepsze metody i nawet nie ocenił linku nibota, który ma nawet kod metody Box-Muller. Więc zostawię rzeczy takimi, jakie są.
Dilip Sarwate

Odpowiedzi:

6

Twój początkowy algorytm tworzy losową zmienną, która jest równomiernie rozłożona między 0 a 1. Ta wariancja wynosi 1/12. Jeśli zsumujesz NUM_GAUSSIAN_SUMSprzykłady tego wariancji, będzie NUM_GAUSSIAN_SUMS/12. Aby uzyskać docelową wariancję, Vnależy pomnożyć zsumowaną zmienną losową przez sqrt(V*12/NUM_GAUSSIAN_SUMS).

Na marginesie, szablon będzie działał dobrze w przypadku liczb zmiennoprzecinkowych i podwójnych, ale wystąpią znaczące problemy numeryczne z dowolnym typem punktu stałego.

Hilmar
źródło
5

jak mogę zmienić wariancję tej zmiennej losowej?

doXdoXdo2)X

Emre
źródło
doXdoX
1
Wyśrodkuj, przeskaluj, a następnie przywróć średnią. Skalowanie wyśrodkowanej zmiennej losowej nie wpłynie na (zero) średnią.
Emre
1

Jest jeszcze inny sposób!

Pomyśl o tym, co jeśli chcesz innej dystrybucji zamiast Gaussa? W takim przypadku nie można tak naprawdę użyć twierdzenia o limicie centralnym; jak to rozwiązać?

Istnieje sposób na konwersję jednolitej zmiennej losowej na dowolny plik PDF. Ta metoda nazywa się metodą transformacji odwrotnej

U[0-1]

X=faX-1(U)

faX(x) .

Dlatego wszystko, co musisz zrobić, to zastosować odwrotną funkcję CDF do zmiennej, którą pobrałeś z próbki jednolitego rv.

Ponadto, w przeciwieństwie do wcześniejszych metod - nie będzie to wymagało żadnej iteracji i nie będzie zależeć od liczby iteracji, które zostaną wykonane, aby wyniki były zbliżone do Gaussa.

Oto jedno z odniesień, które tego dowodzi.

Dipan Mehta
źródło
3
> Jest jeszcze inny sposób! To prawda, ale nie ma znaczenia dla rozważanego pytania, które dotyczy konkretnie zmiennych losowych Gaussa. Ani gaussowskiego CDF, ani jego odwrotności nie można wyrazić w kategoriach elementarnych przy użyciu skończonej liczby operacji, więc sugerowana metoda nie może być użyta.
Dilip Sarwate,