3

これは、ティアドロップシェイプを定義し、その領域内にあるポイントを(均一なジェネレーターから)受け入れることで実行できることを理解しています。

C ++でこれを行うには、2つの均一な乱数xとyを生成して点(x、y)を特定し、この点が領域内にあるかどうかを確認します。

コード自体に問題はありませんが、ここのロジックに欠陥はありますか?これが真の正規分布であるかどうかを確認するための適切なグラフィカルな方法はまだ見つかりません。

動作するはずのコードは次のとおりです。

typedef unsigned long long int Ullong;
typedef double Doub;

struct Normaldev : Ran {
    Doub mu,sig;

    Normaldev (Doub mmu, Doub ssig, Ullong i)
        : Ran (i), mu(mmu), sig(ssig){}

    Doub dev() {

      Doub u, v, x, y, q;
        do {
          u=Doub();
          v=1.7156*(Doub()-0.5);
          x=u-0.449871;
          y=abs(v)+0.386595;
          q=x*x+y*(0.19600*y-0.25472*x);
        } while(q>0.27597 && (q>0.27846 || v*v>-4*log(u)*u*u));

        return mu+sig*v/u;
     }
};

Numerical Recipesの本で提案されているコードを、C ++の基本的な知識を使ってできる限り変更しましたが、Ranは正確には何であると考えられていますか?

4

2 に答える 2

1

Numerical Recipesの本で提案されているコードを、C ++の基本的な知識を使ってできる限り変更しましたが、Ranは正確には何であると考えられていますか?

RanはNormalDevの親クラスです。あなたが与えたコードでは定義されていません。unsigned long long intコードに基づくと、コンストラクターでシードを受け取る、かなり一般的な乱数クラスのようです。

于 2012-10-22T13:32:11.593 に答える
-2

「Cの数値レシピ」の第3版、364〜369ページをご覧ください。Box-Mullerは、2つの正規分布確率変数、つまり「u」と「v」を返すことがわかります。したがって、関数が最初に呼び出されるときは、両方の変数を計算しますが、「u」だけを返します。関数の2番目の呼び出しは、「v」を返すだけです。

double  u, v;
double  sigma = 1.0
double  mean  = 0.0;
int     flag  = 0;

double boxMuller()
{
    if (flag == 1) {
        flag  = 0;
        return v * sigma + mean;
    }
    double help;
    do {
        u = Doub() - 0.5;
        v = Doub() - 0.5;
        help      = u * u + v * v;
    } while (help >= 0.25);
    help = sqrt( log( help * 4.0 ) / help * -2.0 );
    u   *= help;
    v   *= help;
    flag = 1;
    return u * sigma + mean;
}

対照的に、Ratio-of-Uniformsメソッドは、呼び出しごとに(1秒ごとではなく)新しい確率変数を計算する必要があります。

だから私は時間を測定し、上記のボックスミュラーコードを使用することを好みます。

于 2013-04-20T16:58:09.650 に答える