2 Replies Latest reply on Jan 9, 2010 3:42 PM by 843853

    Dealing with very small numbers, and logarithms


      I'm interested in computing a sum which looks like:

      ln( e^-1000 + e^-10000 e^-100000 ... + e^-k )

      where the sequence inside the braces is finite and decreasing, but does not necessarily have a pattern.

      When calculating en exponent such as e^-1000, if I use the standard Math library methods like:

      double d = Math.pow(Math.E,-1000)

      d becomes zero, and its base e logirthm becomes -INFINITY. However, if you observe the above example, the answer will actually be something that's pretty close to -1000.
      I'm aware that the reason of this error is the precision boundaries, and how doubles are represented in computer's memory. However, I'm wondering if I could use a good approximation to calculate this.
      Right now, I'm just picking the first element which is the largest, and returning its exponent as the result. For the example above, I return -1000.

      I tried to use an arbitrary precision library for java called Apfloat, and I was satisfied with the results. The problem is however, the time it takes to compute the series. I've got billions of series like that above and Apfloat seems to be 100s of times slower, which is expected because it creates new objects and does huge computations for each such element in the series.

      I'd be glad if anyone has any recommendations, or thoughts on this.

      Thanks in advance.
        • 1. Re: Dealing with very small numbers, and logarithms
          Find an implementation of Java that supports extended exponents. That gives you exponents up to 16383 or so. Sable VM may be one of those.
          • 2. Re: Dealing with very small numbers, and logarithms
            First of all, any solution requires some amount of numerical analysis to understand the accuracy of any approximation you decide on. Now your particular complaint about 'd' becoming zero and the log going to -INFINITY doesn't make sense because you should be computing the sum of the exponentials first, then taking the log of the sum. If you did this you would not get -INFINITY you would get something around -1000.

            If you're inner sum is finite and small, I would concentrate on an accurate approximation of that. You might consider purely algebraic manipulations such as computing a common denominator for the inner sum so that the problem is transformed into ln (numer / denom) = ln(numer) - ln(denom). This approach might just make things harder, I don't know. Eventually you might use a tool like the Taylor series approximation for ln (1+x) or ln(1-x) or e^x to simplify the expression. In any event, always analyze the error of your approximation. Again, this analysis may have you using the Taylor series so keep that handy.