連続分散ランダムゞェネレヌタヌ

乱数ゞェネレヌタヌはセックスによく䌌おいたす。良いずきは矎しく、悪いずきはただいいですGeorge Marsaglia、1984

確率的アルゎリズムの人気は高たっおいたす。 それらの倚くは、倚数の異なるランダム倉数の生成に基づいおいたす。 垞に均䞀に分垃しおいるずは皋遠い。 ここでは、既知の分垃を持぀高速で正確なランダム倀ゞェネレヌタヌに関する情報を収集しようずしたした。 タスクは異なる堎合があり、基準は異なる堎合がありたす。 ある人にずっおは、生成時間は重芁です。他の人にずっおは-粟床、他の人にずっお-暗号の安定性、他の人にずっお-収束の速床です。 個人的には、0から特定のRAND_MAXたで均䞀に分垃した擬䌌乱数敎数を返す特定の基本的なゞェネレヌタヌがあるずいう前提から進めたした。

unsigned long long BasicRandGenerator() { unsigned long long randomVariable; // some magic here ... return randomVariable; } 

そしお、このゞェネレヌタヌは十分に高速です。 ぀たり、察数を蚈算したり、それらの1぀を环乗したりするよりも、数十個の乱数を生成する方が安䟡です。 これらは暙準のゞェネレヌタヌですstd :: rand、MATLABのrand、Java.util.Randomなど。 ただし、このようなゞェネレヌタヌは深刻な䜜業に適しおいるこずはほずんどありたせん。 倚くの堎合、異なる統蚈テストに倱敗したす。 たた、それらに完党に䟝存しおいるこずを忘れないでください。独自のゞェネレヌタヌを䜿甚しお、その動䜜を把握するこずをお勧めしたす。

この蚘事では、アルゎリズムに぀いお説明したす。アルゎリズムの本質は、少なくずも確率理論に出くわすこずがある人には明らかなはずです。 蚈枬の理論に粟通する必芁はありたせん。原則ずしお、分垃関数ず分垃密床関数がどのようなものかを倧たかに理解すれば十分です。


各アルゎリズムには、コヌド、少量の数孊、および生成された数千䞇のランダム倉数のヒストグラムを添付したす。

均䞀な分垃






非垞にシンプルで普遍的な逆倉換サンプリング方法があるため、均䞀分垃を䜿甚しおほがすべおのランダム倉数を生成できたす.0から1に均䞀に分垃するランダム倉数Uを生成し、パラメヌタヌUで逆分垃関数分䜍点を返したす。確かに


問題は、分析的に可胜な限り、逆分垃関数のカりントが長くなる可胜性があるこずです。

䞀様分垃ゞェネレヌタヌを䜿甚するず、長時間停止する必芁はありたせん倚数のランダム倉数が生成されるため、b-a/ RAND_MAXを1回だけカりントするこずをお勧めしたす。

 double Uniform(double a, double b) { return a + BasicRandGenerator() * (b - a) / RAND_MAX; } 

もちろん、継続性は単なる抜象化です。 珟実の䞖界では、この堎合、具䜓的にはこれはかなり小さなサンプリングステップを意味したす。 重芁なこずは泚目に倀したす。 0から1に均等に分垃する乱数を生成する堎合、32ビットでは、doubleがこの範囲で取るこずができるすべおの倀をカバヌするには䞍十分ですただし、floatには十分です。 品質を向䞊させるには、64ビット敎数を生成するか、2぀の32ビット敎数を結合する必芁がありたす。

正芏分垃





反転法では、逆誀差関数の蚈算が必芁になりたす。 特別な近䌌関数を䜿甚しない堎合、それは難しく、信じられないほど長くなりたす。 通垞の倀の堎合、Box-Mullerメ゜ッドが存圚したす。 それは非垞にシンプルで普及しおいたす。 その明らかな欠点は、超越関数の蚈算です。 Habréでは、 ポヌラヌ法がすでに蚀及されおおり、サむンずコサむンの蚈算を避けるのに圹立ちたした。 ただし、察数ずその根を数える必芁がありたす。 同じ極法の䜜者であるゞョヌゞ・マルサグリアによっお発明された矎しい名前のゞグラット法は、はるかに高速です。
極座暙法は、 受入拒吊サンプリングの䟋です。 文字通り、倀を生成し、適合する堎合はそれを受け入れたす。それ以倖の堎合は、拒吊しお再床生成したす。 䞻な䟋密床fxのランダム倉数を生成する必芁がありたすが、単玔な反転法で行うのは非垞に困難です。 しかし、fxずそれほど倉わらない密床gxのランダム倉数を生成できたす。 この堎合、M> 1およびほがすべおの堎所でfx<Mgxずなる最小の定数Mを取埗し、次のアルゎリズムを実行したす。


ランダム倉数を取る確率


Mの遞択が少ないほど、この確率は高くなりたすが、ゞェネレヌタヌの動䜜は速くなりたす。

アルゎリズムの蚌明
2぀のむベントAおよびBの発生確率は


分垃密床関数gxず分垃関数Gxを䜿甚しおランダム倉数Xをずる確率を蚈算したすが、䞎えられたパラメヌタヌxよりも小さい堎合を想定したす。


そしお、ベむズの定理により




たずえば、暙準の暙準倀のモゞュヌルを生成したす。 正芏分垃の察称性により、埗られた倀は、等しい確率で倀+1および-1をずるランダム倉数で乗算され、暙準正芏分垃倀Xを取埗できたす。正芏倀は、シグマによる暙準乗算ずmuによるシフトから取埗されたす。 分垃密床関数| X |


暙準の指数分垃の密床関数で近䌌しおみたしょう。 指数分垃に぀いおはただ話しおいないので、少し先に進んでいたす。 単玔に悪名高い反転法によっお生成されたす-[0、1]に均䞀に分垃した量Uを取り、-lnUを返したす。


条件fx<Mgxを満たすMの最小倀は、x = 1で達成されたす。


次に


たた、通垞のランダム倉数を生成するためのアルゎリズムは次のずおりです。

  1. U-[0、1]に均䞀に分垃するランダム倉数を生成したす。
  2. 指数関数的に分垃するランダム倉数Eを生成したす-lnUをカりントするよりも高速なアルゎリズムに぀いお、以䞋で説明したす。
  3. U <exp-E-1 2 の堎合| X | = E、それ以倖の堎合は最初のステップに戻りたす。
  4. 新しいUを生成したす。U<0.5の堎合、-| X |たたは| X |を返したす。 別の堎合。

それは簡単にわかりたす


そしおこれは、Uの代わりに、指数関数的に考慮されない別の指数分垃量を生成できるこずを意味したす。 新しいアルゎリズムは次のようになりたす。

  1. 暙準の指数分垃ランダム倉数E 1およびE 2を生成したす。
  2. E 2 >E 1-12/2の堎合、| X | = E 1 、それ以倖の堎合は戻りたす。
  3. Uを生成したす。U<0.5の堎合、-| X |たたは| X |を返したす。 別の堎合。

別のポむント倀E 1が受け入れられるず、差E 2- E 1-12/2も指数関数的にか぀E 1ずは独立しお分垃したす。 したがっお、次回はE 1の代わりに蚘憶しお䜿甚できたす。

蚌明
指数分垃には、メモリ䞍足の特性がありたす。


これは、差分垃関数が次のこずを意味したす。



偏差のあるサンプリングの䞀般的な問題は、偏差が可胜な限り小さくなるように分垃密床gxのランダム倉数を遞択するこずです。 この問題を解決する倚くの拡匵機胜がありたす。 メ゜ッド自䜓は、Zigguratを含むほずんどすべおの埌続アルゎリズムの基瀎です。 埌者の本質は䟝然ずしお同じです。正芏分垃の密床関数を同様の単玔な関数でカバヌし、曲線の䞋にある倀を返すようにしたす。 この関数は独特であり、倚段構成に䌌おいたすが、実際はアルゎリズムの名前です。


ゞグラットは次のように構成されおいたす。 関数fxのふもずで、点x 1およびy 0 = fx 1 が遞択されたす。 長方圢の䞋の領域は0,0からx 1 、y 0 +関数fの尟の䞋の領域x> x 1 = Aです。したがっお、ベヌスレむダヌを構築したした。 その䞊郚には別の長方圢があり、その幅はx 1 、高さはy 1 = A / y 0であり、したがっお面積はAず等しくなりたす。この長方圢には、関数fxの䞊にある点が既に含たれおいたす。䟋x 1 、y 1 。 2番目の長方圢は、ポむントx 2 、y 1 で関数fxず亀差したす-これは、3番目の長方圢の右䞋点の座暙になりたす。関数の最䞊郚にZigguratを構築したせん。 各ステップの面積はAに等しくなりたす。さらなるアルゎリズムベヌスレむダヌに入る凊理なし 

  1. 長方圢iがランダムか぀均等に遞択され、均䞀に分垃した倀Xが0からx iたで生成されたす
  2. X <x i + 1の堎合、間違いなく曲線の䞋に萜ちたす-Xを返したす。
  3. y iからy i + 1たでのYの新しい䞀様分垃倀を生成したす。 座暙X、Yを持぀ポむントが曲線の䞋にある堎合、぀たりY <fXの堎合、Xを返したす。それ以倖の堎合、最初のステップに戻りたす。

ベヌスレむダヌにいる堎合はどうしたすか 想像䞊の点x 0 = A / y 0を入力するこずにより、そこから面積Aの長方圢を䜜成するこずもできたす 。 次に、0,0からx 0 、y 0 たでの長方圢の面積もAに等しくなりたす。ベヌスレむダヌの違いは、新しい想像䞊の長方圢の曲線に該圓しない堎合、xを拒吊しおはならないこずです。ただ尟を打ちたす。 尟に぀いおは、ゞョヌゞ・マルサグリアは、以前に怜蚎したのず同じ方法を䜿甚するこずを提案したす-偏差のあるサンプリング。 いく぀かの倉曎のみ

  1. 密床x 1の暙準的な指数分垃ランダム倉数E 1ず単䜍密床のE 2を生成したす。
  2. E 2 > E 1 2/2の堎合、| X | = E 1 + x 1 、それ以倖の堎合は戻りたす。
  3. Uを生成したす。U<0.5の堎合、-| X |たたは| X |を返したす。 別の堎合。

尟の蚌明
ランダム倉数| X | > x 1 E 1 + x 1を䜿甚しお、そのための偏差サンプリングアルゎリズムを構築しようずしたす。ここで、E 1は、密床x 1の指数分垃ランダム倉数です。 分垃密床関数E 1 + x 1 


Mの倀を知るには、関数の最倧比を芋぀ける必芁がありたす。


分数の最倧倀に察応するポむントxは、最倧指数を提䟛したす。 次数の導関数をれロに等しくするず、察応するxが芋぀かりたす。


䞀様なランダム倉数の境界を取埗したす。


そしお、ランダム倉数を取るための条件は次のようになりたす。



するず、アルゎリズム党䜓は次のようになりたす。

  1. 長方圢iはランダムか぀均等に遞択され、0からx iたでの䞀様分垃倀Xが生成されたす。
  2. X <x i + 1の堎合、間違いなく曲線の䞋に萜ちたす-Xを返したす。
  3. ベヌスレむダヌ、぀たりi = 0にヒットした堎合、テヌルに察しおアルゎリズムを実行し、その結果を返したす。
  4. y Iからy i + 1たでYの新しい䞀様分垃倀を生成したす。 座暙X、Yを持぀ポむントが曲線の䞋にある堎合、぀たりY <fXの堎合、Xを返したす。それ以倖の堎合、最初のステップに戻りたす。

問題は、長方圢の数に応じお定数Aずx 1を芋぀ける方法ですか それらは通垞の数倀的方法で芋぀けるこずができたす。 最初の仮定x 1を取埗し、ベヌスレむダヌを構築し、Aを蚈算しお、必芁な数の四角圢を構築するたでゞグラットを構築したす。 関数よりも高い堎合-぀たり、x 1の倀が小さすぎお、Aの倀が倧きすぎる堎合-新しい倀で再構築しようずしおいたす。

アルゎリズム自䜓は、32ビット敎数を䜿甚しお䞍芁な乗算を削陀するさたざたなトリックによっお高速化できたす。 詳现に぀いおは、George MarsagliaおよびWai Wan TsangのThe Ziggurat Method for Generation Random Variablesを参照しおください。 ここでは、完党に最適化されおいるわけではありたせんが、理解可胜なコヌドを瀺したす指数分垃を生成できる堎合。

 static double stairWidth[257], stairHeight[256]; const double x1 = 3.6541528853610088; const double A = 4.92867323399e-3; /// area under rectangle void setupNormalTables() { // coordinates of the implicit rectangle in base layer stairHeight[0] = exp(-.5 * x1 * x1); stairWidth[0] = A / stairHeight[0]; // implicit value for the top layer stairWidth[256] = 0; for (unsigned i = 1; i <= 255; ++i) { // such x_i that f(x_i) = y_{i-1} stairWidth[i] = sqrt(-2 * log(stairHeight[i - 1])); stairHeight[i] = stairHeight[i - 1] + A / stairWidth[i]; } } double NormalZiggurat() { int iter = 0; do { unsigned long long B = BasicRandGenerator(); int stairId = B & 255; double x = Uniform(0, stairWidth[stairId]); // get horizontal coordinate if (x < stairWidth[stairId + 1]) return ((signed)B > 0) ? x : -x; if (stairId == 0) // handle the base layer { static double z = -1; double y; if (z > 0) // we don't have to generate another exponential variable as we already have one { x = Exponential(x1); z -= 0.5 * x * x; } if (z <= 0) // if previous generation wasn't successful { do { x = Exponential(x1); y = Exponential(1); z = y - 0.5 * x * x; // we storage this value as after acceptance it becomes exponentially distributed } while (z <= 0); } x += x1; return ((signed)B > 0) ? x : -x; } // handle the wedges of other stairs if (Uniform(stairHeight[stairId - 1], stairHeight[stairId]) < exp(-.5 * x * x)) return ((signed)B > 0) ? x : -x; } while (++iter <= 1e9); /// one billion should be enough return NAN; /// fail due to some error } double Normal(double mu, double sigma) { return mu + NormalZiggurat() * sigma; } 


指数分垃





指数分垃の堎合、均䞀に分垃した量の察数をずるこずができ、生成を高速化できるずすでに蚀われおいたす。 任意の指数倀は密床による暙準的な陀算から取埗されるため、生成は悪名高いゞグラットにするこずができたす。 末尟に到達した堎合、アルゎリズムを新しい方法で実行し、取埗した倀にx 1を远加できたす。

蚌明
E> x 1の堎合 、分垃関数E-x 1も指数関数的に分垃するこずを蚌明する必芁がありたす。 これは、前述の指数分垃のメモリ䞍足により可胜です。



さらに2぀の事実255個の長方圢のテヌブルを䜿甚する堎合、指数分垃の最初の受け入れ確率は0.989で、通垞の分垃では0.993です。 MATLABでは、バヌゞョン5以降、正芏分垃にZigguratが䜿甚されおいたす極法が䜿甚されおいたした。 Rでは、通垞の量に぀いおは、私の知る限り、逆誀差関数を倚項匏で近䌌し、反転法を䜿甚したす。

 static double stairWidth[257], stairHeight[256]; const double x1 = 7.69711747013104972; const double A = 3.9496598225815571993e-3; /// area under rectangle void setupExpTables() { // coordinates of the implicit rectangle in base layer stairHeight[0] = exp(-x1); stairWidth[0] = A / stairHeight[0]; // implicit value for the top layer stairWidth[256] = 0; for (unsigned i = 1; i <= 255; ++i) { // such x_i that f(x_i) = y_{i-1} stairWidth[i] = -log(stairHeight[i - 1]); stairHeight[i] = stairHeight[i - 1] + A / stairWidth[i]; } } double ExpZiggurat() { int iter = 0; do { int stairId = BasicRandGenerator() & 255; double x = Uniform(0, stairWidth[stairId]); // get horizontal coordinate if (x < stairWidth[stairId + 1]) /// if we are under the upper stair - accept return x; if (stairId == 0) // if we catch the tail return x1 + ExpZiggurat(); if (Uniform(stairHeight[stairId - 1], stairHeight[stairId]) < exp(-x)) // if we are under the curve - accept return x; // rejection - go back } while (++iter <= 1e9); // one billion should be enough to be sure there is a bug return NAN; // fail due to some error } double Exponential(double rate) { return ExpZiggurat() / rate; } 


ガンマ分垃





生成のためのアルゎリズムはここではすでに耇雑であるため、ここではそれらの蚌拠を説明したせん。䟋のみを瀺したす。 暙準倀シヌタ= 1を生成するには、それぞれkに䟝存する4぀のアルゎリズムが䜿甚されたす。

非暙準のガンマ確率倉数は、シヌタによる暙準の乗算から取埗されたす。

GAアルゎリズム

パラメヌタヌk1ずk2のガンマ分垃を持぀2぀のランダム倉数を远加するず、パラメヌタヌk1 + k2のガンマ分垃を持぀ランダム倉数が埗られたす。 別の特性ずしお、シヌタ= k = 1の堎合、分垃が指数関数的であるこずを簡単に怜蚌できたす。 したがっお、kが敎数の堎合、単玔に暙準の指数分垃でk個のランダム倉数を加算できたす。

 double GA1(int k) { double x = 0; for (int i = 0; i < k; ++i) x += Exponential(1); return x; } 

kが敎数ではなく、2kが敎数の堎合、合蚈で指数ランダム倉数の1぀ではなく、通垞倀の2乗の半分を䜿甚できたす。 なぜこれが可胜かは、埌で明らかになりたす。

 double GA2(double k) { double x = Normal(0, 1); x *= 0.5 * x; for (int i = 1; i < k; ++i) x += Exponential(1); return x; } 


GSアルゎリズム

  1. 0から1 + k / eたで䞀様に分垃するEの暙準的な指数分垃倀ずUの倀を生成したす。 U <= 1の堎合、手順2に進みたす。それ以倖の堎合、手順3に進みたす。
  2. x = U 1 / kを蚭定したす。 x <= Eの堎合はxを返し、そうでない堎合は手順1に戻りたす。
  3. x = -ln1-U/ k + 1 / eを蚭定したす。 1-k* lnx<= Eの堎合、xを返したす。それ以倖の堎合、手順1に戻りたす。

 double GS(double k) { // Assume that k < 1 double x = 0; int iter = 0; do { // M_E is base of natural logarithm double U = Uniform(0, 1 + k / M_E) double W = Exponential(1) if (U <= 1) { x = pow(U, 1.0 / k); if (x <= W) return x; } else { x = -log((1 - U) / k + 1.0 / M_E); if ((1 - k) * log(x) <= W) return x; } } while (++iter < 1e9); // excessive maximum number of rejections return NAN; // shouldn't end up here } 


GFアルゎリズム

私の知る限り、このアルゎリズムの著者であるノヌスカロラむナ倧孊のJ. S.フィッシュマン教授は、圌の業瞟を発衚しおいたせん。 アルゎリズム自䜓はk> 1で機胜したすが、その平均実行時間はsqrtkに比䟋しお増加するため、k <3に察しおのみ有効です。
  1. 暙準的な指数分垃を持぀2぀の独立したランダム倉数E 1およびE 2を生成したす。
  2. E 2 <k-1*E 1 -lnE 1 -1の堎合、手順1に戻りたす。
  3. x = k * E 1を返したす

蚌明
定理 Uを[0、1]䞊の䞀様分垃のランダム倉数ずし、Wを1 /ラムダの密床の指数分垃ランダム倉数ずしたす。 させおください


gW> = Uの堎合、Wはパラメヌタヌlambdaのガンマ分垃を持ちたす。


蚌明。 分垃密床関数W


このように


Uには䞀様な分垃があるため、


0 <gx<1の堎合、無条件の確率


結果ずしお、条件付き確率密床


qed
ゞェネレヌタヌの効率は、U <= gWであり、Cラムダに等しい確率によるものです。 スタヌリング近䌌を䜿甚しお、\ lambdaパラメヌタヌの倀が倧きい堎合、確率を倧たかに蚈算できたす。


アルゎリズムはラムダの増加ずずもに無効になりたす。


 double GF(double k) { // Assume that 1 < k < 3 double E1, E2; do { E1 = Exponential(1); E2 = Exponential(1); } while (E2 < (k - 1) * (E1 - log(E1) - 1)); return k * E1; } 


GOアルゎリズム

Dieter and Ahrensアルゎリズムは、パラメヌタヌの増加に䌎う分垃の挞近正芏性に基づいおいるため、kが倧きいほど高速です。 k> 2.533で機胜したすが、k <3のフィッシャヌアルゎリズムほど効果的ではありたせん最初に、いく぀かの定数を蚭定する必芁がありたすkのみに䟝存。

 void setupConstants(double k) { m = k - 1; s_2 = sqrt(8.0 * k / 3) + k; s = sqrt(s_2); d = M_SQRT2 * M_SQRT3 * s_2; b = d + m; w = s_2 / (m - 1); v = (s_2 + s_2) / (m * sqrt(k)); c = b + log(s * d / b) - m - m - 3.7203285; } double GO(double k) { // Assume that k > 3 double x = 0; int iter = 0; do { double U = Uniform(0, 1); if (U <= 0.0095722652) { double E1 = Exponential(1); double E2 = Exponential(1); x = b * (1 + E1 / d); if (m * (x / b - log(x / m)) + c <= E2) return x; } else { double N; do { N = Normal(0, 1); x = s * N + m; // ~ Normal(m, s) } while (x < 0 || x > b); U = Uniform(0, 1); double S = 0.5 * N * N; if (N > 0) { if (U < 1 - w * S) return x; } else if (U < 1 + S * (v * N - w)) return x; if (log(U) < m * log(x / m) + m - x + S) return x; } } while (++iter < 1e9); return NAN; // shouldn't end up here; } 


以前の分垃の堎合ず同様に、ガンマ倀はシヌタパラメヌタによる暙準の乗算から生成されたす。 䞀様分垃、正芏分垃、指数分垃、ガンマ分垃を生成できれば、他の分垃のほずんどを簡単に取埗できたす。これらは䞊蚘で簡単に衚珟できるためです。

コヌシヌ分垃




コヌシヌ分垃で確率倉数をすばやく取埗する1぀の方法は、2぀の正芏確率倉数を取埗し、それらを互いに分割するこずです。 もっず速くできたすか通垞の反転方法を䜿甚できたすが、接線の蚈算が必芁になりたす。これはさらに遅いです。

かどうか

ゞョヌゞ・マルサグリアの極法を芚えおいたすか圌は、Box-Muller倉換で、均䞀に分垃したランダム倉数のサむンたたはコサむンをすばやく取埗するこずを蚱可したした。接線を取埗する方法ずたったく同じです。正方圢[-1、1] x [-1、1]に2぀の均等に分垃したランダム座暙xおよびyを生成したす。0、0を䞭心ずする円ず単䜍半埄に到達した堎合-x / yを返したす。それ以倖の堎合-xずyを再床生成したす。たずえば、3回目はすでに0.01未満であるため、円に陥らない確率。

 double Cauchy(double x0, double gamma) { double x, y; do { x = Uniform(-1,1); y = Uniform(-1,1); } while (x * x + y * y > 1.0 || y == 0.0); return x0 + gamma * x / y; } 


ラプラス分垃




ラプラス分垃は同じ指数ですが、ランダムな笊号を持ちたす。

 double Laplace(double mu, double b) { double E = Exponential(1.0 / b); return mu + (((signed)BasicRandGenerator() > 0) ? E : -E); } 


課皎分配





分垃密床関数がどれほどひどいものであっおも、ランダム倉数自䜓は非垞に簡単か぀迅速に生成されたす。

 double Levy(double mu, double c) { double N = Normal(0, 1); return mu + c / (N * N); } 


カむ二乗分垃




ご存知のように、パラメヌタkのカむ2乗分垃を持぀確率倉数は、k個の暙準正芏確率倉数の平方和です。kでさえ、これがk / 2指数確率倉数たたはアヌラン分垃の2倍和であるこずはあたり知られおいたせん。この関係から、前述のGA2アルゎリズムは以䞋を導き出したす。

蚌明
, — :


:


E — :


:


:


-, :


. , :


, :


qed

 double ChiSquared(int k) { // ~ Gamma(k / 2, 2) if (k >= 10) // too big parameter return GO(0.5 * k); double x = ((k & 1) ? GA2(0.5 * k) : GA1(k >> 1)); return x + x; } 

このプロパティから泚目すべき事実がありたす。平面䞊の点をランダム座暙ず法線座暙x、yで遞択するず、0,0からこの点たでの距離は指数関数的に分垃したす。

察数正芏分垃




金融垂堎で数孊モデルを扱う人は、察数正芏分垃を盎接知っおいたす。察数正芏分垃、察数コヌチ分垃、察数ロゞスティック分垃の堎合、簡単な方法が1぀ありたす。指数を取るこずです。残念ながら、より高速な方法はわかりたせんが、レノィ分垃やカむ二乗分垃を䜿甚しお同様の量を生成する方法があるかもしれたせん。それらがどれほど䌌おいるかを芋おください。それたでの間、このように

 double LogNormal(double mu, double sigma) { return exp(Normal(mu, sigma)); } 


ロゞスティック分垃




ロゞスティック分垃は正芏分垃ず非垞に䌌おいたすが、テヌルが倧きく、暙準の均䞀分垃を介しお非垞に簡単に生成されたす。

 double Logistic(double mu, double s) { return mu + s * log(1.0 / Uniform(0, 1) - 1); } 


最埌に、垞に高速ずいうわけではありたせんが、他の䞀般的なディストリビュヌション甚の非垞に単玔なアルゎリズムに぀いお簡単に説明したす。

 double Erlang(int k, double l) { return GA1(k) / l; } double Weibull(double l, double k) { return l * pow(Exponential(1), 1.0 / k); } double Rayleigh(double sigma) { return sigma * sqrt(Exponential(0.5)); } double Pareto(double xm, double alpha) { return xm / pow(Uniform(0, 1), 1.0 / alpha); } double StudentT(int v) { if (v == 1) return Cauchy(0, 1); return Normal(0, 1) / sqrt(ChiSquared(v) / v); } double FisherSnedecor(int d1, int d2) { double numerator = d2 * ChiSquared(d1); double denominator = d1 * ChiSquared(d2); return numerator / denominator; } double Beta(double a, double b) { double x = Gamma(a); return x / (x + Gamma(b)); } 


C ++ 17でこれらおよび他のゞェネレヌタヌを実装する

Source: https://habr.com/ru/post/J263993/


All Articles