Box-Muller-Methode

Die Box-Muller-Methode (nach George Edward Pelham Box u​nd Mervin Edgar Muller 1958) i​st ein Verfahren z​ur Erzeugung normalverteilter Zufallszahlen.

Graphische Veranschaulichung der Box-Muller-Methode

Definition

Visualisierung der Box-Muller-Methode. Die farbigen Punkte des Einheitsquadrats (u1, u2), die als Kreise gezeichnet werden, werden einem Punkt in der komplexen Zahlenebene zugeordnet, das als Kreuze gezeichnet ist. Die Darstellungen an den Rändern sind die Wahrscheinlichkeitsverteilungen von z0 und z1.

Bei dieser Methode werden zunächst zwei unabhängige Standardzufallszahlen und benötigt. Diese lassen sich beispielsweise mit einem Zufallszahlengenerator erzeugen. Standardzufallszahlen unterliegen einer Rechteckverteilung mit den Parametern und .

Es lässt sich zeigen, dass man nach folgendem Transformationsschritt daraus zwei standardnormalverteilte (stochastisch) unabhängige Zufallszahlen und erhält:

und

.

Schreibt man das Paar mit Polarkoordinaten, also

und ,

dann gilt:

und .

Anwendung der Inversionsmethode zur Transformation von und in die Polarkoordinaten und zeigt, dass einer Rechteckverteilung mit den Parametern und unterliegt und einer Exponentialverteilung mit dem Parameter . Aus diesem Ergebnis lässt sich die gemeinsame Verteilung von und herleiten. Sie beruht auf der Beziehung:

Die bisherigen Transformationsschritte erzeugen zwei standardnormalverteilte Zufallszahlen. Eine Standardnormalverteilung ist ein Spezialfall der Normalverteilung, nämlich mit dem Erwartungswert und der Varianz .

Um mit der Box-Muller-Methode Normalverteilungen mit beliebigen Parametern zu erzeugen, lassen sich die erhaltenen nach dem Muster

transformieren. In der obigen Notation steht wie üblich für die Kreiszahl, für den Sinus, für den Kosinus und für den natürlichen Logarithmus.

Verwendet man zur Erzeugung der einen linearen Kongruenzgenerator, so liegen die Paare auf einer durch eine Spirale beschriebenen Kurve. Dieses Verhalten ist eng mit dem im Satz von Marsaglia beschriebenen Hyperebenenverhalten linearer Kongruenzgeneratoren verwandt.

Dieses Problem lässt s​ich umgehen, w​enn statt d​es linearen Kongruenzgenerators e​in inverser Kongruenzgenerator o​der die Polar-Methode verwendet wird.

Die Box-Muller-Methode erzeugt zunächst z​wei stochastisch unabhängige u​nd standardnormalverteilte Zufallszahlen, d​ie sich d​ann in e​ine Normalverteilung m​it beliebigen Parametern transformieren lassen. Die Box-Muller-Methode erfordert d​ie Auswertung v​on Logarithmen u​nd trigonometrischen Funktionen, w​as auf einigen Rechnern s​ehr zeitaufwendig s​ein kann.

Weitere Möglichkeiten z​ur Erzeugung normalverteilter Zufallszahlen s​ind im Artikel Normalverteilung beschrieben. Eine Alternative i​st z. B. d​ie Polar-Methode.[1]

Programmierung

Die Standard-Box-Muller-Methode erzeugt Werte aus der Standardnormalverteilung mit Erwartungswert 0 und Standardabweichung 1. Die folgende Implementierung in der Programmiersprache C++ generiert 10 Paare von standardnormalverteilten Zufallszahlen aus jeder Normalverteilung mit Erwartungswert μ und Varianz σ und gibt sie auf der Konsole aus.

#define _USE_MATH_DEFINES
#include <random>
#include <iostream>
using namespace std;

// Diese Funktion berechnet zwei standardnormalverteilte Zufallszahlen z0 und z1
pair<double, double> generateGaussianNoise(double mu, double sigma)
{
    constexpr double epsilon = numeric_limits<double>::epsilon();

    // Initialisiert den Zufallszahlengenerator im Bereich von 0 bis 1
    static mt19937 rng(random_device{}()); // Standard Mersenne-Twister
    static uniform_real_distribution<> runif(0, 1);

    double u1, u2; // Deklaration der lokalen Variablen für die Zufallszahlen u1 und u2
    do // Diese do-while-Schleife erzeugt solange Zufallszahlen bis u1 > epsilon ist
    {
        u1 = runif(rng);
        u2 = runif(rng);
    } while (u1 <= epsilon);

    // Berechnet z0 und z1
    auto magnitude = sigma * sqrt(-2.0 * log(u1));
    auto z0 = magnitude * cos(2.0 * M_PI * u2) + mu;
    auto z1 = magnitude * sin(2.0 * M_PI * u2) + mu;
    return make_pair(z0, z1);
}

// Hauptfunktion die das Programm ausführt
void main()
{
    double mu = 0; // Deklaration der lokalen Variablen
    double sigma = 1;
    for (int i = 0; i < 10; i++) // Diese for-Schleife berechnet 10 Paare von standardnormalverteilte Zufallszahlen und gibt sie auf der Konsole aus
    {
        pair<double, double> gaussianNoise = generateGaussianNoise(mu, sigma); // Aufruf der Funktion
        cout << gaussianNoise.first << "," << gaussianNoise.second << endl; // Ausgabe auf der Konsole
    }
}

Literatur

Einzelnachweise

  1. Vgl. Albert J. Kinderman und John G. Ramage: Computer Generation of Normal Random Numbers. In: Journal of the American Statistical Association, Jg. 71 (1976), Heft 356, S. 893–896.
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. The authors of the article are listed here. Additional terms may apply for the media files, click on images to show image meta data.