-1

私は最近、注文統計の確率分布を扱っています。その領域では、実際の間隔 [0, 1] からの数値の累乗が大きい数式が多数見られるのはよくあることです。

a ~ b ~ 0 の数字を考えてみましょう。どちらも正です。a^n / b^m のようなものを計算したいのですが、n、m は巨大な数です。

私の質問は次のとおりです。次のようなCコードを使用する場合

double f(double a, double b, long m, long n)
{
    return( pow(a, n) / pow(b, m) );
}

これは安定しますか?ルールは、最初に a^n を評価し、次に b^m を評価してから除算する必要がありますが、a^n または b^m が十分に小さい場合、ゼロまたは NaN になります。代わりに、次のようなことができます

double g(double a, double b, long m, long n)
{
    double res;
    long i;
    res = 1;
    for (i = 0; i < min(m, n); ++i)
    {
        res = res * a / b;
    }
    if ( n > m )
    {
        res = res * pow(a, n - m);
    } else {
       res = res / pow(b, m - n);
    }
    return( res );
}

このような場合、1) が最適化の対象になるかどうか知っていますか? そうでない場合、迅速かつ安定した評価のためにそのようなケースをどのように処理しますか?

4

1 に答える 1

3

pow()乗算の繰り返しによる累乗を実装するかどうかを尋ねている場合、答えはノーです。最適化されていると想定できるため、分子がゼロであることを確認することで得られる節約はおそらく無視できます。膨大な数の浮動小数点計算を繰り返すループでこれを実装したくないことは間違いありません。for()

一方、0 で除算することは避けたほうがよいでしょう。

私はあなたの機能を次のように実装します:

double f(double a, double b, long m, long n) {
  if (b == 0) {
    // return error or infinity.
  }
  if (m >= n)
    return pow(a / b, n) * pow(a, m - n);
  else 
    return pow(a / b, m) / pow(b, n - m);
  }
}
于 2013-10-20T13:38:08.660 に答える