• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.math;
18 
19 import static com.google.common.math.StatsTesting.ALLOWED_ERROR;
20 import static com.google.common.math.StatsTesting.ALL_MANY_VALUES;
21 import static com.google.common.math.StatsTesting.ALL_STATS;
22 import static com.google.common.math.StatsTesting.EMPTY_STATS_ITERABLE;
23 import static com.google.common.math.StatsTesting.EMPTY_STATS_VARARGS;
24 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES;
25 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_COUNT;
26 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_MAX;
27 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_MEAN;
28 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_MIN;
29 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_STATS_ITERABLE;
30 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_STATS_VARARGS;
31 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS;
32 import static com.google.common.math.StatsTesting.LARGE_INTEGER_VALUES_MEAN;
33 import static com.google.common.math.StatsTesting.LARGE_INTEGER_VALUES_POPULATION_VARIANCE;
34 import static com.google.common.math.StatsTesting.LARGE_INTEGER_VALUES_STATS;
35 import static com.google.common.math.StatsTesting.LARGE_LONG_VALUES_MEAN;
36 import static com.google.common.math.StatsTesting.LARGE_LONG_VALUES_POPULATION_VARIANCE;
37 import static com.google.common.math.StatsTesting.LARGE_LONG_VALUES_STATS;
38 import static com.google.common.math.StatsTesting.LARGE_VALUES_MEAN;
39 import static com.google.common.math.StatsTesting.LARGE_VALUES_STATS;
40 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES;
41 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_COUNT;
42 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_MAX;
43 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_MEAN;
44 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_MIN;
45 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_STATS_ITERATOR;
46 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_STATS_SNAPSHOT;
47 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS;
48 import static com.google.common.math.StatsTesting.MANY_VALUES;
49 import static com.google.common.math.StatsTesting.MANY_VALUES_COUNT;
50 import static com.google.common.math.StatsTesting.MANY_VALUES_MAX;
51 import static com.google.common.math.StatsTesting.MANY_VALUES_MEAN;
52 import static com.google.common.math.StatsTesting.MANY_VALUES_MIN;
53 import static com.google.common.math.StatsTesting.MANY_VALUES_STATS_ITERABLE;
54 import static com.google.common.math.StatsTesting.MANY_VALUES_STATS_ITERATOR;
55 import static com.google.common.math.StatsTesting.MANY_VALUES_STATS_SNAPSHOT;
56 import static com.google.common.math.StatsTesting.MANY_VALUES_STATS_VARARGS;
57 import static com.google.common.math.StatsTesting.MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS;
58 import static com.google.common.math.StatsTesting.ONE_VALUE;
59 import static com.google.common.math.StatsTesting.ONE_VALUE_STATS;
60 import static com.google.common.math.StatsTesting.TWO_VALUES;
61 import static com.google.common.math.StatsTesting.TWO_VALUES_MAX;
62 import static com.google.common.math.StatsTesting.TWO_VALUES_MEAN;
63 import static com.google.common.math.StatsTesting.TWO_VALUES_MIN;
64 import static com.google.common.math.StatsTesting.TWO_VALUES_STATS;
65 import static com.google.common.math.StatsTesting.TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS;
66 import static com.google.common.truth.Truth.assertThat;
67 import static com.google.common.truth.Truth.assertWithMessage;
68 import static java.lang.Double.NEGATIVE_INFINITY;
69 import static java.lang.Double.NaN;
70 import static java.lang.Double.POSITIVE_INFINITY;
71 import static java.lang.Math.sqrt;
72 import static org.junit.Assert.assertThrows;
73 
74 import com.google.common.collect.ImmutableList;
75 import com.google.common.math.StatsTesting.ManyValues;
76 import com.google.common.primitives.Ints;
77 import com.google.common.primitives.Longs;
78 import com.google.common.testing.EqualsTester;
79 import com.google.common.testing.SerializableTester;
80 import java.nio.ByteBuffer;
81 import java.nio.ByteOrder;
82 import junit.framework.TestCase;
83 
84 /**
85  * Tests for {@link Stats}. This tests instances created by both {@link Stats#of} and {@link
86  * StatsAccumulator#snapshot}.
87  *
88  * @author Pete Gillin
89  */
90 public class StatsTest extends TestCase {
91 
testCount()92   public void testCount() {
93     assertThat(EMPTY_STATS_VARARGS.count()).isEqualTo(0);
94     assertThat(EMPTY_STATS_ITERABLE.count()).isEqualTo(0);
95     assertThat(ONE_VALUE_STATS.count()).isEqualTo(1);
96     assertThat(TWO_VALUES_STATS.count()).isEqualTo(2);
97     assertThat(MANY_VALUES_STATS_VARARGS.count()).isEqualTo(MANY_VALUES_COUNT);
98     assertThat(MANY_VALUES_STATS_ITERABLE.count()).isEqualTo(MANY_VALUES_COUNT);
99     assertThat(MANY_VALUES_STATS_ITERATOR.count()).isEqualTo(MANY_VALUES_COUNT);
100     assertThat(MANY_VALUES_STATS_SNAPSHOT.count()).isEqualTo(MANY_VALUES_COUNT);
101     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.count()).isEqualTo(INTEGER_MANY_VALUES_COUNT);
102     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.count()).isEqualTo(INTEGER_MANY_VALUES_COUNT);
103     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.count()).isEqualTo(LONG_MANY_VALUES_COUNT);
104     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.count()).isEqualTo(LONG_MANY_VALUES_COUNT);
105   }
106 
testMean()107   public void testMean() {
108     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_VARARGS.mean());
109     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_ITERABLE.mean());
110     assertThat(ONE_VALUE_STATS.mean()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
111     assertThat(Stats.of(POSITIVE_INFINITY).mean()).isPositiveInfinity();
112     assertThat(Stats.of(NEGATIVE_INFINITY).mean()).isNegativeInfinity();
113     assertThat(Stats.of(NaN).mean()).isNaN();
114     assertThat(TWO_VALUES_STATS.mean()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MEAN);
115     // For datasets of many double values created from an array, we test many combinations of finite
116     // and non-finite values:
117     for (ManyValues values : ALL_MANY_VALUES) {
118       double mean = Stats.of(values.asArray()).mean();
119       if (values.hasAnyNaN()) {
120         assertWithMessage("mean of " + values).that(mean).isNaN();
121       } else if (values.hasAnyPositiveInfinity() && values.hasAnyNegativeInfinity()) {
122         assertWithMessage("mean of " + values).that(mean).isNaN();
123       } else if (values.hasAnyPositiveInfinity()) {
124         assertWithMessage("mean of " + values).that(mean).isPositiveInfinity();
125       } else if (values.hasAnyNegativeInfinity()) {
126         assertWithMessage("mean of " + values).that(mean).isNegativeInfinity();
127       } else {
128         assertWithMessage("mean of " + values)
129             .that(mean)
130             .isWithin(ALLOWED_ERROR)
131             .of(MANY_VALUES_MEAN);
132       }
133     }
134     assertThat(MANY_VALUES_STATS_ITERABLE.mean()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
135     assertThat(MANY_VALUES_STATS_ITERATOR.mean()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
136     assertThat(MANY_VALUES_STATS_SNAPSHOT.mean()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
137     assertThat(LARGE_VALUES_STATS.mean())
138         .isWithin(ALLOWED_ERROR * Double.MAX_VALUE)
139         .of(LARGE_VALUES_MEAN);
140     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.mean())
141         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
142         .of(INTEGER_MANY_VALUES_MEAN);
143     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.mean())
144         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
145         .of(INTEGER_MANY_VALUES_MEAN);
146     assertThat(LARGE_INTEGER_VALUES_STATS.mean())
147         .isWithin(ALLOWED_ERROR * Integer.MAX_VALUE)
148         .of(LARGE_INTEGER_VALUES_MEAN);
149     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.mean())
150         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
151         .of(LONG_MANY_VALUES_MEAN);
152     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.mean())
153         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
154         .of(LONG_MANY_VALUES_MEAN);
155     assertThat(LARGE_LONG_VALUES_STATS.mean())
156         .isWithin(ALLOWED_ERROR * Long.MAX_VALUE)
157         .of(LARGE_LONG_VALUES_MEAN);
158   }
159 
testSum()160   public void testSum() {
161     assertThat(EMPTY_STATS_VARARGS.sum()).isEqualTo(0.0);
162     assertThat(EMPTY_STATS_ITERABLE.sum()).isEqualTo(0.0);
163     assertThat(ONE_VALUE_STATS.sum()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
164     assertThat(TWO_VALUES_STATS.sum()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MEAN * 2);
165     assertThat(MANY_VALUES_STATS_VARARGS.sum())
166         .isWithin(ALLOWED_ERROR)
167         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
168     assertThat(MANY_VALUES_STATS_ITERABLE.sum())
169         .isWithin(ALLOWED_ERROR)
170         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
171     assertThat(MANY_VALUES_STATS_ITERATOR.sum())
172         .isWithin(ALLOWED_ERROR)
173         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
174     assertThat(MANY_VALUES_STATS_SNAPSHOT.sum())
175         .isWithin(ALLOWED_ERROR)
176         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
177     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.sum())
178         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
179         .of(INTEGER_MANY_VALUES_MEAN * INTEGER_MANY_VALUES_COUNT);
180     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.sum())
181         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
182         .of(INTEGER_MANY_VALUES_MEAN * INTEGER_MANY_VALUES_COUNT);
183     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.sum())
184         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
185         .of(LONG_MANY_VALUES_MEAN * LONG_MANY_VALUES_COUNT);
186     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.sum())
187         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
188         .of(LONG_MANY_VALUES_MEAN * LONG_MANY_VALUES_COUNT);
189   }
190 
testPopulationVariance()191   public void testPopulationVariance() {
192     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_VARARGS.populationVariance());
193     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_ITERABLE.populationVariance());
194     assertThat(ONE_VALUE_STATS.populationVariance()).isWithin(0.0).of(0.0);
195     assertThat(Stats.of(POSITIVE_INFINITY).populationVariance()).isNaN();
196     assertThat(Stats.of(NEGATIVE_INFINITY).populationVariance()).isNaN();
197     assertThat(Stats.of(NaN).populationVariance()).isNaN();
198     assertThat(TWO_VALUES_STATS.populationVariance())
199         .isWithin(ALLOWED_ERROR)
200         .of(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS / 2);
201     assertThat(MANY_VALUES_STATS_VARARGS.populationVariance())
202         .isWithin(ALLOWED_ERROR)
203         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
204     // For datasets of many double values created from an iterable, we test many combinations of
205     // finite and non-finite values:
206     for (ManyValues values : ALL_MANY_VALUES) {
207       double populationVariance = Stats.of(values.asIterable()).populationVariance();
208       if (values.hasAnyNonFinite()) {
209         assertWithMessage("population variance of " + values).that(populationVariance).isNaN();
210       } else {
211         assertWithMessage("population variance of " + values)
212             .that(populationVariance)
213             .isWithin(ALLOWED_ERROR)
214             .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
215       }
216     }
217     assertThat(MANY_VALUES_STATS_ITERATOR.populationVariance())
218         .isWithin(ALLOWED_ERROR)
219         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
220     assertThat(MANY_VALUES_STATS_SNAPSHOT.populationVariance())
221         .isWithin(ALLOWED_ERROR)
222         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
223     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.populationVariance())
224         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
225         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT);
226     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.populationVariance())
227         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
228         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT);
229     assertThat(LARGE_INTEGER_VALUES_STATS.populationVariance())
230         .isWithin(ALLOWED_ERROR * Integer.MAX_VALUE * Integer.MAX_VALUE)
231         .of(LARGE_INTEGER_VALUES_POPULATION_VARIANCE);
232     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.populationVariance())
233         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
234         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT);
235     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.populationVariance())
236         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
237         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT);
238     assertThat(LARGE_LONG_VALUES_STATS.populationVariance())
239         .isWithin(ALLOWED_ERROR * Long.MAX_VALUE * Long.MAX_VALUE)
240         .of(LARGE_LONG_VALUES_POPULATION_VARIANCE);
241   }
242 
testPopulationStandardDeviation()243   public void testPopulationStandardDeviation() {
244     assertThrows(
245         IllegalStateException.class, () -> EMPTY_STATS_VARARGS.populationStandardDeviation());
246     assertThrows(
247         IllegalStateException.class, () -> EMPTY_STATS_ITERABLE.populationStandardDeviation());
248     assertThat(ONE_VALUE_STATS.populationStandardDeviation()).isWithin(0.0).of(0.0);
249     assertThat(TWO_VALUES_STATS.populationStandardDeviation())
250         .isWithin(ALLOWED_ERROR)
251         .of(sqrt(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS / 2));
252     assertThat(MANY_VALUES_STATS_VARARGS.populationStandardDeviation())
253         .isWithin(ALLOWED_ERROR)
254         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
255     assertThat(MANY_VALUES_STATS_ITERABLE.populationStandardDeviation())
256         .isWithin(ALLOWED_ERROR)
257         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
258     assertThat(MANY_VALUES_STATS_ITERATOR.populationStandardDeviation())
259         .isWithin(ALLOWED_ERROR)
260         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
261     assertThat(MANY_VALUES_STATS_SNAPSHOT.populationStandardDeviation())
262         .isWithin(ALLOWED_ERROR)
263         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
264     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.populationStandardDeviation())
265         .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
266         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT));
267     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.populationStandardDeviation())
268         .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
269         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT));
270     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.populationStandardDeviation())
271         .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
272         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT));
273     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.populationStandardDeviation())
274         .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
275         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT));
276   }
277 
testSampleVariance()278   public void testSampleVariance() {
279     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_VARARGS.sampleVariance());
280     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_ITERABLE.sampleVariance());
281     assertThrows(IllegalStateException.class, () -> ONE_VALUE_STATS.sampleVariance());
282     assertThat(TWO_VALUES_STATS.sampleVariance())
283         .isWithin(ALLOWED_ERROR)
284         .of(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS);
285     assertThat(MANY_VALUES_STATS_VARARGS.sampleVariance())
286         .isWithin(ALLOWED_ERROR)
287         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
288     assertThat(MANY_VALUES_STATS_ITERABLE.sampleVariance())
289         .isWithin(ALLOWED_ERROR)
290         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
291     assertThat(MANY_VALUES_STATS_ITERATOR.sampleVariance())
292         .isWithin(ALLOWED_ERROR)
293         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
294     assertThat(MANY_VALUES_STATS_SNAPSHOT.sampleVariance())
295         .isWithin(ALLOWED_ERROR)
296         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
297     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.sampleVariance())
298         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
299         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1));
300     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.sampleVariance())
301         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
302         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1));
303     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.sampleVariance())
304         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
305         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1));
306     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.sampleVariance())
307         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
308         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1));
309   }
310 
testSampleStandardDeviation()311   public void testSampleStandardDeviation() {
312     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_VARARGS.sampleStandardDeviation());
313     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_ITERABLE.sampleStandardDeviation());
314     assertThrows(IllegalStateException.class, () -> ONE_VALUE_STATS.sampleStandardDeviation());
315     assertThat(TWO_VALUES_STATS.sampleStandardDeviation())
316         .isWithin(ALLOWED_ERROR)
317         .of(sqrt(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS));
318     assertThat(MANY_VALUES_STATS_VARARGS.sampleStandardDeviation())
319         .isWithin(ALLOWED_ERROR)
320         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
321     assertThat(MANY_VALUES_STATS_ITERABLE.sampleStandardDeviation())
322         .isWithin(ALLOWED_ERROR)
323         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
324     assertThat(MANY_VALUES_STATS_ITERATOR.sampleStandardDeviation())
325         .isWithin(ALLOWED_ERROR)
326         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
327     assertThat(MANY_VALUES_STATS_SNAPSHOT.sampleStandardDeviation())
328         .isWithin(ALLOWED_ERROR)
329         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
330     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.sampleStandardDeviation())
331         .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
332         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1)));
333     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.sampleStandardDeviation())
334         .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
335         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1)));
336     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.sampleStandardDeviation())
337         .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
338         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1)));
339     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.sampleStandardDeviation())
340         .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
341         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1)));
342   }
343 
testMax()344   public void testMax() {
345     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_VARARGS.max());
346     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_ITERABLE.max());
347     assertThat(ONE_VALUE_STATS.max()).isEqualTo(ONE_VALUE);
348     assertThat(Stats.of(POSITIVE_INFINITY).max()).isPositiveInfinity();
349     assertThat(Stats.of(NEGATIVE_INFINITY).max()).isNegativeInfinity();
350     assertThat(Stats.of(NaN).max()).isNaN();
351     assertThat(TWO_VALUES_STATS.max()).isEqualTo(TWO_VALUES_MAX);
352     assertThat(MANY_VALUES_STATS_VARARGS.max()).isEqualTo(MANY_VALUES_MAX);
353     assertThat(MANY_VALUES_STATS_ITERABLE.max()).isEqualTo(MANY_VALUES_MAX);
354     // For datasets of many double values created from an iterator, we test many combinations of
355     // finite and non-finite values:
356     for (ManyValues values : ALL_MANY_VALUES) {
357       double max = Stats.of(values.asIterable().iterator()).max();
358       if (values.hasAnyNaN()) {
359         assertWithMessage("max of " + values).that(max).isNaN();
360       } else if (values.hasAnyPositiveInfinity()) {
361         assertWithMessage("max of " + values).that(max).isPositiveInfinity();
362       } else {
363         assertWithMessage("max of " + values).that(max).isEqualTo(MANY_VALUES_MAX);
364       }
365     }
366     assertThat(MANY_VALUES_STATS_SNAPSHOT.max()).isEqualTo(MANY_VALUES_MAX);
367     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.max()).isEqualTo(INTEGER_MANY_VALUES_MAX);
368     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.max()).isEqualTo(INTEGER_MANY_VALUES_MAX);
369     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.max()).isEqualTo(LONG_MANY_VALUES_MAX);
370     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.max()).isEqualTo(LONG_MANY_VALUES_MAX);
371   }
372 
testMin()373   public void testMin() {
374     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_VARARGS.min());
375     assertThrows(IllegalStateException.class, () -> EMPTY_STATS_ITERABLE.min());
376     assertThat(ONE_VALUE_STATS.min()).isEqualTo(ONE_VALUE);
377     assertThat(Stats.of(POSITIVE_INFINITY).min()).isPositiveInfinity();
378     assertThat(Stats.of(NEGATIVE_INFINITY).min()).isNegativeInfinity();
379     assertThat(Stats.of(NaN).min()).isNaN();
380     assertThat(TWO_VALUES_STATS.min()).isEqualTo(TWO_VALUES_MIN);
381     assertThat(MANY_VALUES_STATS_VARARGS.min()).isEqualTo(MANY_VALUES_MIN);
382     assertThat(MANY_VALUES_STATS_ITERABLE.min()).isEqualTo(MANY_VALUES_MIN);
383     assertThat(MANY_VALUES_STATS_ITERATOR.min()).isEqualTo(MANY_VALUES_MIN);
384     // For datasets of many double values created from an accumulator snapshot, we test many
385     // combinations of finite and non-finite values:
386     for (ManyValues values : ALL_MANY_VALUES) {
387       StatsAccumulator accumulator = new StatsAccumulator();
388       accumulator.addAll(values.asIterable());
389       double min = accumulator.snapshot().min();
390       if (values.hasAnyNaN()) {
391         assertWithMessage("min of " + values).that(min).isNaN();
392       } else if (values.hasAnyNegativeInfinity()) {
393         assertWithMessage("min of " + values).that(min).isNegativeInfinity();
394       } else {
395         assertWithMessage("min of " + values).that(min).isEqualTo(MANY_VALUES_MIN);
396       }
397     }
398     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.min()).isEqualTo(INTEGER_MANY_VALUES_MIN);
399     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.min()).isEqualTo(INTEGER_MANY_VALUES_MIN);
400     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.min()).isEqualTo(LONG_MANY_VALUES_MIN);
401     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.min()).isEqualTo(LONG_MANY_VALUES_MIN);
402   }
403 
testEqualsAndHashCode()404   public void testEqualsAndHashCode() {
405     new EqualsTester()
406         .addEqualityGroup(
407             Stats.of(1.0, 1.0, 5.0, 5.0),
408             Stats.of(1.0, 1.0, 5.0, 5.0),
409             Stats.of(ImmutableList.of(1.0, 1.0, 5.0, 5.0)),
410             Stats.of(ImmutableList.of(1.0, 1.0, 5.0, 5.0).iterator()),
411             SerializableTester.reserialize(Stats.of(1.0, 1.0, 5.0, 5.0)))
412         .addEqualityGroup(Stats.of(1.0, 5.0))
413         .addEqualityGroup(Stats.of(1.0, 5.0, 1.0, 6.0))
414         .addEqualityGroup(Stats.of(2.0, 6.0, 2.0, 6.0))
415         .addEqualityGroup(
416             new Stats(5, -5.5, 55.5, -5.55, 5.55), new Stats(5, -5.5, 55.5, -5.55, 5.55))
417         .addEqualityGroup(new Stats(6, -5.5, 55.5, -5.55, 5.55))
418         .addEqualityGroup(new Stats(5, -5.6, 55.5, -5.55, 5.55))
419         .addEqualityGroup(new Stats(5, -5.5, 55.6, -5.55, 5.55))
420         .addEqualityGroup(new Stats(5, -5.5, 55.5, -5.56, 5.55))
421         .addEqualityGroup(new Stats(5, -5.5, 55.5, -5.55, 5.56))
422         .testEquals();
423   }
424 
testSerializable()425   public void testSerializable() {
426     SerializableTester.reserializeAndAssert(MANY_VALUES_STATS_ITERABLE);
427   }
428 
testToString()429   public void testToString() {
430     assertThat(EMPTY_STATS_VARARGS.toString()).isEqualTo("Stats{count=0}");
431     assertThat(MANY_VALUES_STATS_ITERABLE.toString())
432         .isEqualTo(
433             "Stats{count="
434                 + MANY_VALUES_STATS_ITERABLE.count()
435                 + ", mean="
436                 + MANY_VALUES_STATS_ITERABLE.mean()
437                 + ", populationStandardDeviation="
438                 + MANY_VALUES_STATS_ITERABLE.populationStandardDeviation()
439                 + ", min="
440                 + MANY_VALUES_STATS_ITERABLE.min()
441                 + ", max="
442                 + MANY_VALUES_STATS_ITERABLE.max()
443                 + "}");
444   }
445 
testMeanOf()446   public void testMeanOf() {
447     assertThrows(IllegalArgumentException.class, () -> Stats.meanOf());
448     assertThrows(IllegalArgumentException.class, () -> Stats.meanOf(ImmutableList.<Number>of()));
449     assertThat(Stats.meanOf(ONE_VALUE)).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
450     assertThat(Stats.meanOf(POSITIVE_INFINITY)).isPositiveInfinity();
451     assertThat(Stats.meanOf(NEGATIVE_INFINITY)).isNegativeInfinity();
452     assertThat(Stats.meanOf(NaN)).isNaN();
453     assertThat(Stats.meanOf(TWO_VALUES)).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MEAN);
454     // For datasets of many double values created from an array, we test many combinations of finite
455     // and non-finite values:
456     for (ManyValues values : ALL_MANY_VALUES) {
457       double mean = Stats.meanOf(values.asArray());
458       if (values.hasAnyNaN()) {
459         assertWithMessage("mean of " + values).that(mean).isNaN();
460       } else if (values.hasAnyPositiveInfinity() && values.hasAnyNegativeInfinity()) {
461         assertWithMessage("mean of " + values).that(mean).isNaN();
462       } else if (values.hasAnyPositiveInfinity()) {
463         assertWithMessage("mean of " + values).that(mean).isPositiveInfinity();
464       } else if (values.hasAnyNegativeInfinity()) {
465         assertWithMessage("mean of " + values).that(mean).isNegativeInfinity();
466       } else {
467         assertWithMessage("mean of " + values)
468             .that(mean)
469             .isWithin(ALLOWED_ERROR)
470             .of(MANY_VALUES_MEAN);
471       }
472     }
473     assertThat(Stats.meanOf(MANY_VALUES)).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
474     assertThat(Stats.meanOf(MANY_VALUES.iterator())).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
475     assertThat(Stats.meanOf(INTEGER_MANY_VALUES))
476         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
477         .of(INTEGER_MANY_VALUES_MEAN);
478     assertThat(Stats.meanOf(Ints.toArray(INTEGER_MANY_VALUES)))
479         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
480         .of(INTEGER_MANY_VALUES_MEAN);
481     assertThat(Stats.meanOf(LONG_MANY_VALUES))
482         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
483         .of(LONG_MANY_VALUES_MEAN);
484     assertThat(Stats.meanOf(Longs.toArray(LONG_MANY_VALUES)))
485         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
486         .of(LONG_MANY_VALUES_MEAN);
487   }
488 
testToByteArrayAndFromByteArrayRoundTrip()489   public void testToByteArrayAndFromByteArrayRoundTrip() {
490     for (Stats stats : ALL_STATS) {
491       byte[] statsByteArray = stats.toByteArray();
492 
493       // Round trip to byte array and back
494       assertThat(Stats.fromByteArray(statsByteArray)).isEqualTo(stats);
495     }
496   }
497 
testFromByteArray_withNullInputThrowsNullPointerException()498   public void testFromByteArray_withNullInputThrowsNullPointerException() {
499     assertThrows(NullPointerException.class, () -> Stats.fromByteArray(null));
500   }
501 
testFromByteArray_withEmptyArrayInputThrowsIllegalArgumentException()502   public void testFromByteArray_withEmptyArrayInputThrowsIllegalArgumentException() {
503     assertThrows(IllegalArgumentException.class, () -> Stats.fromByteArray(new byte[0]));
504   }
505 
testFromByteArray_withTooLongArrayInputThrowsIllegalArgumentException()506   public void testFromByteArray_withTooLongArrayInputThrowsIllegalArgumentException() {
507     byte[] buffer = MANY_VALUES_STATS_VARARGS.toByteArray();
508     byte[] tooLongByteArray =
509         ByteBuffer.allocate(buffer.length + 2)
510             .order(ByteOrder.LITTLE_ENDIAN)
511             .put(buffer)
512             .putChar('.')
513             .array();
514     assertThrows(IllegalArgumentException.class, () -> Stats.fromByteArray(tooLongByteArray));
515   }
516 
testFromByteArrayWithTooShortArrayInputThrowsIllegalArgumentException()517   public void testFromByteArrayWithTooShortArrayInputThrowsIllegalArgumentException() {
518     byte[] buffer = MANY_VALUES_STATS_VARARGS.toByteArray();
519     byte[] tooShortByteArray =
520         ByteBuffer.allocate(buffer.length - 1)
521             .order(ByteOrder.LITTLE_ENDIAN)
522             .put(buffer, 0, Stats.BYTES - 1)
523             .array();
524     assertThrows(IllegalArgumentException.class, () -> Stats.fromByteArray(tooShortByteArray));
525   }
526 }
527