Metrics { public static ImmutableSortedMultiset<Double> computeHistogram( Iterable<Double> input, double binSize) { final ImmutableSortedMultiset.Builder<Double> builder = ImmutableSortedMultiset .naturalOrder(); for (final double d : input) { checkArgument(!Double.isInfinite(d) && !Double.isNaN(d), "Only finite numbers are accepted, found %s.", d); builder.add(Math.floor(d / binSize) * binSize); } return builder.build(); } private  Metrics(); static double getVehicleSpeed(Scenario s); static ImmutableMultiset<Class<?>> getEventTypeCounts(Scenario s); static void checkTimeWindowStrictness(Scenario s); static ImmutableList<Long> getArrivalTimes(Scenario s); static ImmutableSortedMultiset<Double> computeHistogram(
      Iterable<Double> input, double binSize); static StatisticalSummary measureUrgency(Scenario s); static double measureDynamism(Scenario s); static double measureDynamism(Scenario s, long lengthOfDay); static double measureDynamism(Iterable<Double> arrivalTimes,
      double lengthOfDay); static ImmutableList<Point> getServicePoints(Scenario s);  }
@Test public void testHistogram() { assertEquals(ImmutableSortedMultiset.of(), Metrics.computeHistogram(Arrays.<Double>asList(), .2)); final List<Double> list = Arrays.asList(1d, 2d, 2d, 1.99999, 3d, 4d); assertEquals(ImmutableSortedMultiset.of(0d, 0d, 2d, 2d, 2d, 4d), Metrics.computeHistogram(list, 2)); final List<Double> list2 = Arrays.asList(1d, 2d, 2d, 1.99999, 3d, 4d); assertEquals(ImmutableSortedMultiset.of(1d, 1.5d, 2d, 2d, 3d, 4d), Metrics.computeHistogram(list2, .5)); }
@Test(expected = IllegalArgumentException.class) public void testHistogramInvalidInput1() { Metrics.computeHistogram(asList(0d, Double.NaN), 3); }
@Test(expected = IllegalArgumentException.class) public void testHistogramInvalidInput2() { Metrics.computeHistogram(asList(0d, Double.POSITIVE_INFINITY), 3); }