„Box-Muller-Methode“ – Versionsunterschied
[ungesichtete Version] | [gesichtete Version] |
Keine Bearbeitungszusammenfassung |
Keine Bearbeitungszusammenfassung |
||
(64 dazwischenliegende Versionen von 42 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
[[Datei:Box Muller.svg|mini|160px|Graphische Veranschaulichung der Box-Muller-Methode]] |
|||
{{Unverständlich}} |
|||
⚫ | |||
[[Image:Box_Muller.svg|thumb|160px]] |
|||
⚫ | |||
== |
== Definition == |
||
[[Datei:Box-Muller transform visualisation.svg|mini|Visualisierung der Box-Muller-Methode. Die farbigen Punkte des [[Einheitsquadrat]]s (u<sub>1</sub>, u<sub>2</sub>), die als Kreise gezeichnet werden, werden einem Punkt in der [[Komplexe Zahlenebene|komplexen Zahlenebene]] zugeordnet, das als Kreuze gezeichnet ist. Die Darstellungen an den Rändern sind die [[Wahrscheinlichkeitsverteilung]]en von z<sub>0</sub> und z<sub>1</sub>.]] |
|||
⚫ | Bei dieser Methode werden zunächst zwei unabhängige [[Standardzufallszahl]]en <math>u_1</math> und <math>u_2</math> benötigt. Diese lassen sich beispielsweise mit einem [[Zufallszahlengenerator]] erzeugen. Standardzufallszahlen unterliegen einer [[Rechteckverteilung]] mit den Parametern <math>0</math> und <math>1</math>. |
||
⚫ | |||
⚫ | Bei dieser Methode werden zunächst zwei [[Standardzufallszahl]]en <math>u_1</math> und <math>u_2</math> benötigt. Diese lassen sich beispielsweise mit einem [[Zufallszahlengenerator]] erzeugen. Standardzufallszahlen unterliegen einer [[Rechteckverteilung]] mit den Parametern <math>0</math> und <math>1</math>. |
||
⚫ | |||
=== Erzeugung standardnormalverteilter Zufallszahlen === |
|||
⚫ | |||
⚫ | |||
und |
und |
||
:<math> |
:<math>z_1 = \sqrt{-2 \ln u_1} \sin ( 2 \pi u_2 )</math>. |
||
Schreibt man das Paar <math>(z_ 0, z_1)</math> mit [[Polarkoordinate]]n, also |
|||
:<math> |
:<math>z_0 = r \cos \varphi</math> und <math>z_1 = r \sin \varphi</math>, |
||
dann gilt: |
|||
und |
|||
:<math> |
:<math>r = \sqrt{-2 \ln u_1}\ </math> und <math>\varphi = 2 \pi u_2</math>. |
||
Anwendung der [[Inversionsmethode]] zur Transformation von <math>u_1</math> und <math>u_2</math> in die Polarkoordinaten <math>r</math> und <math>\varphi</math> zeigt, dass <math>\varphi</math> einer [[Rechteckverteilung]] mit den Parametern <math>0</math> und <math>2 \pi</math> unterliegt und <math>r^2</math> einer [[Exponentialverteilung]] mit dem Parameter <math>\tfrac{1}{2}</math>. Aus diesem Ergebnis lässt sich die [[Gemeinsame Verteilung von Zufallsvariablen|gemeinsame Verteilung]] von <math>z_ 1</math> und <math>z_2</math> herleiten. Sie beruht auf der Beziehung: |
|||
:<math>\tfrac 12e^{-\frac 12 r^2}\mathrm{d}(r^2)\tfrac{1}{2\pi}\mathrm{d}\varphi=\tfrac{1}{2\pi}e^{-\frac 12 r^2}r\mathrm{d}r\mathrm{d}\varphi=\tfrac{1}{2\pi}e^{-\frac 12 (z_0^2+z_1^2)}\mathrm{d}z_0\mathrm{d}z_1</math> |
|||
⚫ | |||
⚫ | |||
Um mit der Box-Muller-Methode Normalverteilungen mit beliebigen Parametern zu erzeugen, lassen sich die erhaltenen <math>z_i</math> nach dem Muster |
Um mit der Box-Muller-Methode Normalverteilungen mit beliebigen Parametern zu erzeugen, lassen sich die erhaltenen <math>z_i</math> nach dem Muster |
||
:<math>x_i = \mu + \sigma |
:<math>x_i = \mu + \sigma\cdot z_i</math> |
||
transformieren. |
|||
⚫ | |||
⚫ | |||
==Probleme== |
|||
Verwendet man zur Erzeugung der <math>u_i</math> einen [[ |
Verwendet man zur Erzeugung der <math>u_i</math> einen [[Linearer Kongruenzgenerator|linearen Kongruenzgenerator]], so liegen die Paare <math>(z_0, z_1)</math> auf einer durch eine Spirale beschriebenen Kurve. Dieses Verhalten ist eng mit dem im [[Satz von Marsaglia]] beschriebenen [[Hyperebene]]nverhalten linearer Kongruenzgeneratoren verwandt. |
||
Dieses Problem lässt sich umgehen, wenn statt des linearen Kongruenzgenerators ein [[inverser Kongruenzgenerator]] verwendet wird. |
Dieses Problem lässt sich umgehen, wenn statt des linearen Kongruenzgenerators ein [[inverser Kongruenzgenerator]] oder die [[Polar-Methode]] verwendet wird. |
||
⚫ | Die Box-Muller-Methode erzeugt zunächst zwei stochastisch unabhängige und standardnormalverteilte [[Zufallszahl]]en, die sich dann in eine [[Normalverteilung]] mit beliebigen Parametern transformieren lassen. Die Box-Muller-Methode erfordert die Auswertung von [[Logarithmus|Logarithmen]] und [[Trigonometrische Funktion|trigonometrischen Funktionen]], was auf einigen Rechnern sehr zeitaufwendig sein kann. |
||
==Fazit== |
|||
Weitere Möglichkeiten zur Erzeugung normalverteilter [[Zufallszahl]]en sind im Artikel [[Normalverteilung]] beschrieben. Eine Alternative ist z. B. die [[Polar-Methode]].<ref>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.</ref> |
|||
⚫ | |||
== Programmierung == |
|||
Die Box-Muller-Methode erfordert die Auswertung von Logarithmen und trigonometrischen Funktionen, was auf einigen Rechnern sehr zeitaufwendig sein kann. |
|||
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 [[Zufallszahl]]en aus jeder [[Normalverteilung]] mit Erwartungswert μ und [[Varianz (Stochastik)|Varianz]] σ und gibt sie auf der Konsole aus. |
|||
<syntaxhighlight lang="c++"> |
|||
#define _USE_MATH_DEFINES |
|||
#include <random> |
|||
#include <iostream> |
|||
using namespace std; |
|||
// Diese Funktion berechnet zwei standardnormalverteilte Zufallszahlen z0 und z1 |
|||
==Alternativen== |
|||
pair<double, double> generateGaussianNoise(double mu, double sigma) |
|||
{ |
|||
constexpr double epsilon = numeric_limits<double>::epsilon(); |
|||
// Initialisiert den Zufallszahlengenerator im Bereich von 0 bis 1 |
|||
Weitere Möglichkeiten zur Erzeugung normalverteilter Zufallszahlen sind im Artikel [[Normalverteilung]] beschrieben. |
|||
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 |
|||
Eine Alternative ist z.B. die [[Polar-Methode]], siehe |
|||
do // Diese do-while-Schleife erzeugt solange Zufallszahlen bis u1 > epsilon ist |
|||
{ |
|||
u1 = runif(rng); |
|||
} while (u1 <= epsilon); |
|||
u2 = runif(rng); |
|||
// Berechnet z0 und z1 |
|||
* Kinderman, A.J. und J.R. Ramage: ''Computer Generation of Normal Random Numbers'', Jour. Amer. Stat. Assoc., 71(356), p. 893-896 (1976) |
|||
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 |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
⚫ | |||
* |
* George Edward Pelham Box, Mervin Edgar Muller: ''A note on the generation of random normal deviates.'' In: ''[[Annals of Mathematical Statistics]]'', Jg. 29 (1958), Heft 2, {{ISSN|0003-4851}}, S. 610–611. |
||
*[[Donald Ervin Knuth]]: ''The Art of Computer Programming'', Sec. 3.4.1, |
* [[Donald Ervin Knuth]]: ''[[The Art of Computer Programming]]'', Sec. 3.4.1, S. 117. |
||
*O. Moeschlin, O., E. Grycko, C. Pohl und F. Steinert: ''Experimental Stochastics''. Springer, 1998, ISBN 3-540-14619-9, Kapitel 1.4 ''Generating Sample Values'' |
|||
* Otto Moeschlin, Eugen Grycko, Claudia Pohl, Frank Steinert: Kapitel 1.4 ''Generating Sample Values''. In: Diess.: ''Experimental Stochastics.'' Springer, Berlin u. a. 1998, ISBN 3-540-14619-9. |
|||
== Einzelnachweise == |
|||
[[Kategorie:Statistik]] |
|||
<references /> |
|||
[[Kategorie:Pseudozufallszahlengenerator]] |
|||
[[en:Box-Muller transform]] |
|||
[[pl:Transformacja Boxa-Mullera]] |
|||
[[ru:Преобразование Бокса — Мюллера]] |
|||
[[uk:Перетворення Бокса-Мюллера]] |
Aktuelle Version vom 13. Mai 2022, 15:38 Uhr

Die Box-Muller-Methode (nach George Edward Pelham Box und Mervin Edgar Muller 1958) ist ein Verfahren zur Erzeugung normalverteilter Zufallszahlen.
Definition
[Bearbeiten | Quelltext bearbeiten]
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 sich umgehen, wenn statt des linearen Kongruenzgenerators ein inverser Kongruenzgenerator oder die Polar-Methode verwendet wird.
Die Box-Muller-Methode erzeugt zunächst zwei stochastisch unabhängige und standardnormalverteilte Zufallszahlen, die sich dann in eine Normalverteilung mit beliebigen Parametern transformieren lassen. Die Box-Muller-Methode erfordert die Auswertung von Logarithmen und trigonometrischen Funktionen, was auf einigen Rechnern sehr zeitaufwendig sein kann.
Weitere Möglichkeiten zur Erzeugung normalverteilter Zufallszahlen sind im Artikel Normalverteilung beschrieben. Eine Alternative ist z. B. die Polar-Methode.[1]
Programmierung
[Bearbeiten | Quelltext bearbeiten]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);
} while (u1 <= epsilon);
u2 = runif(rng);
// 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
[Bearbeiten | Quelltext bearbeiten]- George Edward Pelham Box, Mervin Edgar Muller: A note on the generation of random normal deviates. In: Annals of Mathematical Statistics, Jg. 29 (1958), Heft 2, ISSN 0003-4851, S. 610–611.
- Donald Ervin Knuth: The Art of Computer Programming, Sec. 3.4.1, S. 117.
- Otto Moeschlin, Eugen Grycko, Claudia Pohl, Frank Steinert: Kapitel 1.4 Generating Sample Values. In: Diess.: Experimental Stochastics. Springer, Berlin u. a. 1998, ISBN 3-540-14619-9.
Einzelnachweise
[Bearbeiten | Quelltext bearbeiten]- ↑ 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.