Píšem program v jazyku Java, ktorý vyžadujevypočítajte niektoré pravdepodobnosti a pri väčších vstupoch sa pravdepodobnosť nakoniec môže veľmi zmenšiť. Preto by som chcel namiesto toho vziať pravdepodobnosti denníka, aby sa predišlo problémom s nedostatočným tokom.
Mám však problémy s jeho implementáciou. V každej fáze výpočtu môže byť rôzny počet možností, ktorým je potrebné priradiť pravdepodobnosti, a každú fázu musia pridať až 1. Pravdepodobnosti sú založené na množstve rôznych premenných. Beriem súčet všetkých možností pomocou nasledujúceho vzorca:
Math.pow(d[i], a) * Math.pow(1/c[i], b)
Toto mi dáva premennú, total
, Ak chcete zistiť pravdepodobnosť p_i,
p_i = (Math.pow(d[i], a) * Math.pow(1/c[i], b)) / total
Moja otázka znie, ako to môžem implementovať pomocou pravdepodobností protokolov, aby som nedostal hodnoty „Nekonečno“ a „NaN“, pretože to sú to, čo som sa doteraz dostal.
odpovede:
0 pre odpoveď č. 1Myslím, že by ste sa mali pokúsiť použiť Summit Kahana, Umožní to správne sčítanie a nestratenie presnosti.
V niektorých pseudokódoch typu C (prepáčte, moja Java je hrdzavá, kód nie je testovaný)
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;
}