Ich versuche, eine C ++ - Funktion zu schreiben, die aufgrund ihrer Mittelwerte und Varianzen Gaußsche Zufallswerte zurückgibt.
Es gibt eine Bibliotheksfunktion rand()
, die Zufallszahlen zwischen 0
und zurückgibt RAND_MAX
. RAND_MAX
hat keinen festen Wert, aber es wird garantiert, dass er mindestens beträgt . Das PDF ist einheitlich.
Ich verwende den zentralen Grenzwertsatz, um dies rand()
in eine Gaußsche Variable umzuwandeln . Was ich genau tue, ist, rand()
einen Benutzer nach bestimmten Zeiten aufzurufen , dann dessen Rückgabewerte zu addieren und dann seinen Mittelwert auf den vom Benutzer angegebenen Mittelwert zu verschieben.
In der obigen Darstellung habe ich meinen Gaußschen Zufallsgenerator Mal aufgerufen und die Frequenzen seiner Rückgabewerte aufgezeichnet. Wie Sie sehen, ist seine Varianz enorm, da er durch die Summe vieler anderer Zufallswerte erzeugt wird.
Es wird erfolgreich eine Gaußsche Variable mit einem Gaußschen PDF und dem angegebenen Mittelwert zurückgegeben. Das Problem ist jedoch seine Varianz. Ich stecke an dieser Stelle fest, weil ich nicht weiß, wie ich die Varianz auf den benutzerdefinierten Wert ändern soll.
Dies ist mein Code (vorerst unvollständig; der Parameter "Varianz" wird ignoriert):
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);
}
Angenommen, das NUM_GAUSSIAN_SUMS
ist 100 und RAND_MAX
32767.
Ich möchte die Varianz der Zufallsvariablen entsprechend dem Parameter der Funktion ändern. Meine Frage ist, wie kann ich die Varianz dieser Zufallsvariablen ändern? Wie kann ich es tun?
Antworten:
Ihr anfänglicher Algorithmus erstellt eine Zufallsvariable, die gleichmäßig zwischen 0 und 1 verteilt ist. Die Varianz davon beträgt 1/12. Wenn Sie
NUM_GAUSSIAN_SUMS
Instanzen davon summieren , ist die VarianzNUM_GAUSSIAN_SUMS/12
. Um zu einer Zielvarianz zu gelangen,V
müssen Sie die summierte Zufallsvariable mit multiplizierensqrt(V*12/NUM_GAUSSIAN_SUMS)
.Nebenbei bemerkt, eine Vorlage funktioniert gut für Floats und Doubles, aber es gibt erhebliche numerische Probleme mit jedem Festkommatyp.
quelle
quelle
Es gibt noch einen anderen Weg!
Denken Sie daran, was wäre, wenn Sie eine andere Distribution als Gauß wollen? In diesem Fall könnten Sie den Satz des zentralen Grenzwerts nicht wirklich verwenden. wie löst du es dann
Es gibt eine Möglichkeit, eine einheitliche Zufallsvariable in eine beliebige PDF-Datei zu konvertieren. Diese Methode wird als inverse Transformationsmethode bezeichnet
Alles, was Sie tun müssen, ist, die inverse CDF-Funktion auf die Variable anzuwenden, die Sie aus der Stichprobe des einheitlichen RV abgerufen haben.
Im Gegensatz zu den früheren Methoden erfordert dies keine Iteration und hängt nicht davon ab, wie viele Iterationen erforderlich sind, um die Ergebnisse für Gauß zu schließen.
Hier ist eine der Referenzen , die einen Beweis dafür liefert.
quelle