MathUtils { public static double weightedLogSumExp(double[] weights, double[] scores) { if(scores.length == 0){ throw new RuntimeException( "weightedLogSumExp was called with a zero length array of scores." ); } double max = Double.NEGATIVE_INFINITY; for (double score : scores) { max = Math.max(score, max); } double sum = 0; for (int i = 0; i < scores.length; i++) { sum += weights[i] * Math.exp(scores[i] - max); } sum = max + Math.log(sum); return sum; } private  MathUtils(); static long binomialCoeff(int n, int k); static double logSumExp(double[] scores); static double logWeightedGeometricMean(double[] weights, double[] logScores); static double weightedArithmeticMean(double[] weights, double[] scores); static double weightedGeometricMean(double[] weights, double[] scores); static double weightedLogSumExp(double[] weights, double[] scores); static double logprob(double input); static double clamp(double input, double min, double max); static double sigmoid(double t);  }
@Test public void testWeightedLogSumExp() throws Exception { assertEquals(Math.log(11), MathUtils.weightedLogSumExp( new double[] {2, 1, 1}, new double[] { Math.log(2), Math.log(3), Math.log(4) }), 0.1); }