2017-08-02 61 views
2

我用Java编写一个程序需要我计算一些概率,对于较大的输入,概率最终可能会变得非常小。因此,为了防止下溢问题,我想取而代之的是日志概率。准确性很小概率

但是,我很难实现这一点。在计算的每个阶段,可以有不同数量的选项,需要分配概率以及他们需要加起来的每个阶段1.概率基于许多不同的变量。我拿一个求和使用下列公式所有可能性:

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

这给了我一个变量,total。然后,为了建立概率P_I,

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

我的问题是,我怎么能实现这个使用数概率,所以,我不明白“无限”和'南的值,因为这些都是我已经越来越至今。

+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; 
}