/ Presnosť s veľmi malými pravdepodobnosťami - java, matematika, pravdepodobnosť

Presnosť s veľmi malými pravdepodobnosťami - java, matematika, pravdepodobnosť

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ď č. 1

Myslí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;
}