オリジナルリンク:https://www.alanzucconi.com/2015/09/16/how-to-sample-from-a-gaussian-distribution/
-
最初のステップ:平均分布からガウス分布に
2つの独立した確率変数X、Yのガウス分布があると仮定します。
2次元平面上のサンプル水平および垂直座標(X、Y)点である場合、得られた写真。
平面上の同時確率密度関数の点(X、Y)です。
極座標系を直交座標系平面を変換します。
点の水平および垂直座標を表すことができます。
同時確率密度関数は次のように書くことができます。
これは、順番に二つの別々の同時確率分布として見ることができます。
ここでは、均一な分布を有する素数の分布の定義を思い出します。
Rはまた、一様に見出さ分配されます。
したがって、2つの変数は一様に分布しているので、ガウス分布が均一に分布2で生成されてもよいです。
-
第二のステップ
プロセスの最初のステップは、今ガウス分布を生成するには、getアルゴリズム、リバーサを推力:
(1)被験者均一U [0、1]の分散2つの変数を生成します
二つの変数によって生成された(2)は、Rと:、
(3)直交座標への極座標から変換
これは、変換ボックス-ミュラー。ボックスミュラー有するガウス分布にマッピングされ、次の図に示すが均一単位正方形に分布する点を変換します。
-
第三段階:Marsaglia極性方法
ボックス・ミュラー質問を変換である:それ自体は動作速度に影響を及ぼしている複雑な三角関数を使用しています。この問題を解決するために、Marsaglia極地法は、登場します。等間隔の点を生じ、それは2次元の対象である(-1,1)です。この点は、単位円内に存在しなければならない、原点(0,0)とすることができません。条件が満たされない場合は、次の点が選択されています。コードは以下の通りであります:
public static float NextGaussian() {
float v1, v2, s;
do {
v1 = 2.0f * Random.Range(0f,1f) - 1.0f;
v2 = 2.0f * Random.Range(0f,1f) - 1.0f;
s = v1 * v1 + v2 * v2;
} while (s >= 1.0f || s == 0f);
s = Mathf.Sqrt((-2.0f * Mathf.Log(s)) / s);
return v1 * s;
}
この方法では約21%の点が除外されます。
-
ステップ4:任意のガウス曲線にマッピングすること
アルゴリズムの第3のステップは、提供されるサンプリングの方法。私たちは、正規分布のいずれかにそれを変換するには、次のメソッドを使用することができます:
public static float NextGaussian(float mean, float standard_deviation)
{
return mean + NextGaussian() * standard_deviation;
}
もう一つの問題は、ガウス分布は平均非常に遠くの極端な値を生成すること、それは私たちが望む結果ではないということです。制限、ガウスランダム関数で最も値を生成するには?コードは次の通り:
public static float NextGaussian (float mean, float standard_deviation, float min, float max) {
float x;
do {
x = NextGaussian(mean, standard_deviation);
} while (x < min || x > max);
retun x;
}