2017-08-02 10 views
2

私はJavaでプログラムを書くので、確率を計算する必要があり、大きな入力に対しては確率は非常に小さくなる可能性があります。したがって、アンダーフローの問題を防ぐために、代わりにログの確率をとっておきたいと思います。確率は非常に小さい

しかし、これを実装する際に問題があります。計算の各段階では、確率を割り当てる必要があるオプション数と、最大1を加算する必要がある各段階があります。その確率は、いくつかの異なる変数に基づいています。私は、次の式を使用して、すべての可能性の上に合計を取る:これは私の変数、totalを与える

Math.pow(d[i], a) * Math.pow(1/c[i], b) 

。その後、確率P_Iを確立するために、

p_i = (Math.pow(d[i], a) * Math.pow(1/c[i], b))/total 

私の質問は、私は「無限」と「NaNの」値を取得しないように、これらは私が取得されたものであるため、どのように私は、この使用してログ確率を実装することができ、ありますこれまでのところ。

+0

和のログだから – meowgoesthedog

+0

を簡素化することが可能であることを考えてはいけない、とということですここでログ確率を実装することはできないと言いますか? – swingballchamp42

+1

なぜBigDecimalを使用しないのですか? –

答えて

0

あなたが試してみるべきことは、Kahan Summationを使用することです。精度を失うことなく適切に合計することができます。

いくつかのCのような擬似コードで

(私のJavaはさびで申し訳ありませんが、コードがテストされていない)

double total(int N, double[] d, double[] c, double a, double b) { 

    double sum   = 0.0; 
    double running_error = 0.0; 

    for (int i = 0; i != N; ++i) { 
     if (d[i] == 0.0) 
      continue; 

     if (c[i] == 0.0) 
      throw "XXX"; // some error reporting 

     double v = 0.0; 
     if (d[i] > 0.0 && c[i] > 0.0) { 
      // using log trick, if you want 
      double lpi = a*Math.log(d[i]) - b*Math.log(c[i]); 
      v = Math.exp(lpi); 
     } 
     else { 
      v = Math.pow(d[i], a) * Math.pow(1.0/c[i], b); 
     } 

     double difference = v - running_error; 
     double temp = sum + difference; 
     running_error = (temp - sum) - difference; 
     sum = temp; 
    } 
    return sum; 
} 
関連する問題