Collections Data Structure Java

/* Copyright (C) 2003 Univ. of Massachusetts Amherst, Computer Science Dept.
   This file is part of "MALLET" (MAchine Learning for LanguagE Toolkit).
   http://www.cs.umass.edu/~mccallum/mallet
   This software is provided under the terms of the Common Public License,
   version 1.0, as published by http://www.opensource.org.  For further
   information, see the file `LICENSE' included with this distribution. */
//package cc.mallet.util;
/**
 * 
 * 
 * @author Charles Sutton
 * @version $Id: ArrayUtils.java,v 1.1 2007/10/22 21:37:40 mccallum Exp $
 */
public class Util {
    private static final double LOGTOLERANCE = 30.0;
    /**
     * Sums an array of numbers log(x1)...log(xn).  This saves some of
     *  the unnecessary calls to Math.log in the two-argument version.
     * 


     * Note that this implementation IGNORES elements of the input
     *  array that are more than LOGTOLERANCE (currently 30.0) less
     *  than the maximum element.
     * 


     * Cursory testing makes me wonder if this is actually much faster than
     *  repeated use of the 2-argument version, however -cas.
     * @param vals An array log(x1), log(x2), ..., log(xn)
     * @return log(x1+x2+...+xn)
     */
    public static double sumLogProb (double[] vals)
    {
      double max = Double.NEGATIVE_INFINITY;
      int len = vals.length;
      int maxidx = 0;
      for (int i = 0; i < len; i++) {
        if (vals[i] > max) {
          max = vals[i];
          maxidx = i;
        }
      }
      boolean anyAdded = false;
      double intermediate = 0.0;
      double cutoff = max - LOGTOLERANCE;
      for (int i = 0; i < maxidx; i++) {
        if (vals[i] >= cutoff) {
          anyAdded = true;
          intermediate += Math.exp(vals[i] - max);
        }
      }
      for (int i = maxidx + 1; i < len; i++) {
        if (vals[i] >= cutoff) {
          anyAdded = true;
          intermediate += Math.exp(vals[i] - max);
        }
      }
      if (anyAdded) {
        return max + Math.log(1.0 + intermediate);
      } else {
        return max;
      }
    }
}