2017-08-02 97 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; 
}