public static double logSum(double[] logInputs, int fromIndex, int toIndex) {
    if (logInputs.length == 0)
      throw new IllegalArgumentException();
    if(fromIndex >= 0 && toIndex < logInputs.length && fromIndex >= toIndex)
      return Double.NEGATIVE_INFINITY;
    int maxIdx = fromIndex;
    double max = logInputs[fromIndex];
    for (int i = fromIndex+1; i < toIndex; i++) {
      if (logInputs[i] > max) {
        maxIdx = i;
        max = logInputs[i];
      }
    }
    boolean haveTerms = false;
    double intermediate = 0.0;
    double cutoff = max - SloppyMath.LOGTOLERANCE;
    // we avoid rearranging the array and so test indices each time!
    for (int i = fromIndex; i < toIndex; i++) {
      if (i != maxIdx && logInputs[i] > cutoff) {
        haveTerms = true;
        intermediate += Math.exp(logInputs[i] - max);
      }
    }
    if (haveTerms) {
      return max + Math.log(1.0 + intermediate);
    } else {
      return max;
    }
  }
public static double logSum ( double [ ] logInputs , int fromIndex , int toIndex ) { if ( logInputs . length == 0 ) throw new IllegalArgumentException ( ) ; if ( fromIndex >= 0 && toIndex < logInputs . length && fromIndex >= toIndex ) return Double . NEGATIVE_INFINITY ; int maxIdx = fromIndex ; double max = logInputs [ fromIndex ] ; for ( int i = fromIndex + 1 ; i < toIndex ; i ++ ) { if ( logInputs [ i ] > max ) { maxIdx = i ; max = logInputs [ i ] ; } } boolean haveTerms = false ; double intermediate = 0.0 ; double cutoff = max - SloppyMath . LOGTOLERANCE ; for ( int i = fromIndex ; i < toIndex ; i ++ ) { if ( i != maxIdx && logInputs [ i ] > cutoff ) { haveTerms = true ; intermediate += Math . exp ( logInputs [ i ] - max ) ; } } if ( haveTerms ) { return max + Math . log ( 1.0 + intermediate ) ; } else { return max ; } }
Returns the log of the portion between <code>fromIndex</code>, inclusive, and
<code>toIndex</code>, exclusive, of an array of numbers, which are
themselves input in log form.  This is all natural logarithms.
Reasonable care is taken to do this as efficiently as possible
(under the assumption that the numbers might differ greatly in
magnitude), with high accuracy, and without numerical overflow.  Throws an
{@link IllegalArgumentException} if <code>logInputs</code> is of length zero.
Otherwise, returns Double.NEGATIVE_INFINITY if <code>fromIndex</code> &gt;=
<code>toIndex</code>.

@param logInputs An array of numbers [log(x1), ..., log(xn)]
@param fromIndex The array index to start the sum from
@param toIndex The array index after the last element to be summed
@return log(x1 + ... + xn)