私はモンテカルロアルゴリズムを書いています。このアルゴリズムでは、ある時点で確率変数で除算する必要があります。より正確には、確率変数は差分商のステップ幅として使用されるため、実際には最初に変数を乗算してから、この式の局所的な線形関数から再度除算します。好き
double f(double);
std::tr1::variate_generator<std::tr1::mt19937, std::tr1::normal_distribution<> >
r( std::tr1::mt19937(time(NULL)),
std::tr1::normal_distribution<>(0) );
double h = r();
double a = ( f(x+h) - f(x) ) / h;
これはほとんどの場合正常に機能しますが、。の場合は失敗しh=0
ます。数学的には、これは問題ではありません。正規分布の確率変数の有限(または実際には可算)選択では、すべてが確率1で非ゼロになるためです。しかし、デジタル実装では、h==0
約2³²の関数呼び出しが発生します。 (宇宙よりも周期が長いメルセンヌツイスターに関係なく、通常long
のsを出力します!)。
この問題を回避するのは非常に簡単です。
double h = r();
while (h==0) h=r();
しかし、私はこれを特にエレガントだとは思いません。より良い方法はありますか?
私が評価している関数は、実際には単純なℝ->ℝのようなもの
f
ではなく、ℝⁿ変数を数値積分しながらℝᵐ変数の勾配を計算するℝᵐxℝⁿ->ℝです。関数全体に、予測できない(しかし「コヒーレントな」)ノイズが重なっており、特定の(しかし未知の)優れた周波数がある場合もあります。これを固定値で試してみると、問題が発生しますh
。