2

I writing a program in Java which requires me to compute some probabilities, and for larger inputs, the probabilities can eventually become very small. Therefore, to prevent underflow issues, I would like to take the log probabilities instead.

I am, however, having trouble implementing this. At each stage of computation there can be a different number of options, to which probabilities need to be assigned, and each stage they need to add up to 1. The probabilities are based on a number of different variables. I take a sum over all possibilities using the following formula:

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

This gives me a variable, total. To then establish the probability p_i,

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

My question is, how can I implement this using log probabilities, so that I do not get 'Infinity' and 'NaN' values, since these are what I have been getting so far.

1 Answers1

0

What I think you should try is to use Kahan Summation. It will allow to sum properly not loosing precision.

In some C-like pseudo-code (sorry, my Java is rusty, code is untested)

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;
}
Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64