Implementierung einer Gaußschen Zufallsvariablen unter Verwendung einer einheitlichen Zufallsvariablen

11

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 0und zurückgibt RAND_MAX. RAND_MAXhat keinen festen Wert, aber es wird garantiert, dass er mindestens beträgt . Das PDF ist einheitlich.2151

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.

Gaußsches PDF
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.107

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_SUMSist 100 und RAND_MAX32767.

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?

hkBattousai
quelle
3
Es gibt bessere und schnellere Wege als den zentralen Grenzwertsatz zur Erzeugung von Gaußschen Zufallsvariablen. Suche nach der Box-Muller-Methode für eine; Eine Zikkurat-Methode soll sogar noch besser sein.
Dilip Sarwate
3
In alten Tagen, in denen die Ausführungszeit eine wichtige Überlegung war, summierten die Leute U ( 0 , 1 ) Zufallsvariablen (nicht 100 ) und subtrahierten 6 , um eine einfache Annäherung an eine Standard- N ( 0 , 1 ) Zufallsvariable zu erhalten, und skalierten dann Y = σ X + μ , um eine N ( μ , σ 2 ) Zufallsvariable zu erhalten. (Warum dies funktioniert, finden Sie in der Antwort von @ Hilmar). Für viele Anwendungen funktionierte diese einfache Methode sehr gut, aber die Werte waren auf den Bereich beschränkt12 U(0,1)1006N(0,1)Y=σX+μN(μ,σ2) und diese einfache Idee blieb auf der Strecke, als Six-Sigma zum Schlagwort wurde. (μ6σ,μ+6σ)
Dilip Sarwate
@ DilipSarwate vielleicht sollten Sie diese Alternativen als Antwort mit einer Begründung dafür posten, warum wir es bevorzugen würden
Ivo Flipse
@IvoFlipse Die Antwort auf die Frage "Wie kann ich die Varianz korrigieren, nachdem ich den Mittelwert festgelegt habe?" Dies ist im Wesentlichen das, was die von Hilmar akzeptierte Antwort in der durch die Kommentare geänderten Fassung sagt: Korrigieren Sie die Varianz durch Skalieren und dann den Mittelwert neu, oder noch besser, beginnen Sie nicht damit, den Mittelwert zuerst festzulegen, da Sie ihn erneut korrigieren müssen es später; Korrigieren Sie zuerst die Varianz durch Skalieren und dann den Mittelwert. Das OP gibt nicht an, dass er / sie überhaupt an besseren Methoden interessiert ist und hat nicht einmal den Link von nibot hochgestuft, der sogar den Code für die Box-Muller-Methode enthält. Also werde ich die Dinge so lassen, wie sie sind.
Dilip Sarwate

Antworten:

6

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_SUMSInstanzen davon summieren , ist die Varianz NUM_GAUSSIAN_SUMS/12. Um zu einer Zielvarianz zu gelangen, Vmüssen Sie die summierte Zufallsvariable mit multiplizieren sqrt(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.

Hilmar
quelle
5

Wie kann ich die Varianz dieser Zufallsvariablen ändern?

cXcXc2X

Emre
quelle
cXcX
1
Zentrieren, neu skalieren und dann den Mittelwert wiederherstellen. Das Skalieren einer zentrierten Zufallsvariablen wirkt sich nicht auf den Mittelwert (Null) aus.
Emre
1

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

U[01]

X=FX1(U)

FX(x)

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.

Dipan Mehta
quelle
3
> Es gibt noch einen anderen Weg! Richtig, aber irrelevant für die betrachtete Frage, die sich speziell mit Gaußschen Zufallsvariablen befasst. Weder die Gaußsche CDF noch ihre Umkehrung können mit einer endlichen Anzahl von Operationen in elementaren Begriffen ausgedrückt werden, so dass die vorgeschlagene Methode nicht verwendet werden kann.
Dilip Sarwate