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 0
i RAND_MAX
. RAND_MAX
nie ma stałej wartości, ale gwarantuje się, że będzie to co najmniej . Jego plik PDF jest jednolity.
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ą.
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.
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_SUMS
to 100, a RAND_MAX
32767.
Chcę zmienić wariancję zmiennej losowej zgodnie z parametrem funkcji. Moje pytanie brzmi: jak mogę zmienić wariancję tej zmiennej losowej? Jak mogę to zrobić?
Odpowiedzi:
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_SUMS
przykłady tego wariancji, będzieNUM_GAUSSIAN_SUMS/12
. Aby uzyskać docelową wariancję,V
należy pomnożyć zsumowaną zmienną losową przezsqrt(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.
źródło
źródło
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
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.
źródło