• 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 
73 import com.google.common.collect.ImmutableList;
74 import com.google.common.math.StatsTesting.ManyValues;
75 import com.google.common.primitives.Ints;
76 import com.google.common.primitives.Longs;
77 import com.google.common.testing.EqualsTester;
78 import com.google.common.testing.SerializableTester;
79 import java.nio.ByteBuffer;
80 import java.nio.ByteOrder;
81 import junit.framework.TestCase;
82 
83 /**
84  * Tests for {@link Stats}. This tests instances created by both {@link Stats#of} and {@link
85  * StatsAccumulator#snapshot}.
86  *
87  * @author Pete Gillin
88  */
89 public class StatsTest extends TestCase {
90 
testCount()91   public void testCount() {
92     assertThat(EMPTY_STATS_VARARGS.count()).isEqualTo(0);
93     assertThat(EMPTY_STATS_ITERABLE.count()).isEqualTo(0);
94     assertThat(ONE_VALUE_STATS.count()).isEqualTo(1);
95     assertThat(TWO_VALUES_STATS.count()).isEqualTo(2);
96     assertThat(MANY_VALUES_STATS_VARARGS.count()).isEqualTo(MANY_VALUES_COUNT);
97     assertThat(MANY_VALUES_STATS_ITERABLE.count()).isEqualTo(MANY_VALUES_COUNT);
98     assertThat(MANY_VALUES_STATS_ITERATOR.count()).isEqualTo(MANY_VALUES_COUNT);
99     assertThat(MANY_VALUES_STATS_SNAPSHOT.count()).isEqualTo(MANY_VALUES_COUNT);
100     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.count()).isEqualTo(INTEGER_MANY_VALUES_COUNT);
101     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.count()).isEqualTo(INTEGER_MANY_VALUES_COUNT);
102     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.count()).isEqualTo(LONG_MANY_VALUES_COUNT);
103     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.count()).isEqualTo(LONG_MANY_VALUES_COUNT);
104   }
105 
testMean()106   public void testMean() {
107     try {
108       EMPTY_STATS_VARARGS.mean();
109       fail("Expected IllegalStateException");
110     } catch (IllegalStateException expected) {
111     }
112     try {
113       EMPTY_STATS_ITERABLE.mean();
114       fail("Expected IllegalStateException");
115     } catch (IllegalStateException expected) {
116     }
117     assertThat(ONE_VALUE_STATS.mean()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
118     assertThat(Stats.of(POSITIVE_INFINITY).mean()).isPositiveInfinity();
119     assertThat(Stats.of(NEGATIVE_INFINITY).mean()).isNegativeInfinity();
120     assertThat(Stats.of(NaN).mean()).isNaN();
121     assertThat(TWO_VALUES_STATS.mean()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MEAN);
122     // For datasets of many double values created from an array, we test many combinations of finite
123     // and non-finite values:
124     for (ManyValues values : ALL_MANY_VALUES) {
125       double mean = Stats.of(values.asArray()).mean();
126       if (values.hasAnyNaN()) {
127         assertWithMessage("mean of " + values).that(mean).isNaN();
128       } else if (values.hasAnyPositiveInfinity() && values.hasAnyNegativeInfinity()) {
129         assertWithMessage("mean of " + values).that(mean).isNaN();
130       } else if (values.hasAnyPositiveInfinity()) {
131         assertWithMessage("mean of " + values).that(mean).isPositiveInfinity();
132       } else if (values.hasAnyNegativeInfinity()) {
133         assertWithMessage("mean of " + values).that(mean).isNegativeInfinity();
134       } else {
135         assertWithMessage("mean of " + values)
136             .that(mean)
137             .isWithin(ALLOWED_ERROR)
138             .of(MANY_VALUES_MEAN);
139       }
140     }
141     assertThat(MANY_VALUES_STATS_ITERABLE.mean()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
142     assertThat(MANY_VALUES_STATS_ITERATOR.mean()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
143     assertThat(MANY_VALUES_STATS_SNAPSHOT.mean()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
144     assertThat(LARGE_VALUES_STATS.mean())
145         .isWithin(ALLOWED_ERROR * Double.MAX_VALUE)
146         .of(LARGE_VALUES_MEAN);
147     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.mean())
148         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
149         .of(INTEGER_MANY_VALUES_MEAN);
150     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.mean())
151         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
152         .of(INTEGER_MANY_VALUES_MEAN);
153     assertThat(LARGE_INTEGER_VALUES_STATS.mean())
154         .isWithin(ALLOWED_ERROR * Integer.MAX_VALUE)
155         .of(LARGE_INTEGER_VALUES_MEAN);
156     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.mean())
157         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
158         .of(LONG_MANY_VALUES_MEAN);
159     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.mean())
160         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
161         .of(LONG_MANY_VALUES_MEAN);
162     assertThat(LARGE_LONG_VALUES_STATS.mean())
163         .isWithin(ALLOWED_ERROR * Long.MAX_VALUE)
164         .of(LARGE_LONG_VALUES_MEAN);
165   }
166 
testSum()167   public void testSum() {
168     assertThat(EMPTY_STATS_VARARGS.sum()).isEqualTo(0.0);
169     assertThat(EMPTY_STATS_ITERABLE.sum()).isEqualTo(0.0);
170     assertThat(ONE_VALUE_STATS.sum()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
171     assertThat(TWO_VALUES_STATS.sum()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MEAN * 2);
172     assertThat(MANY_VALUES_STATS_VARARGS.sum())
173         .isWithin(ALLOWED_ERROR)
174         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
175     assertThat(MANY_VALUES_STATS_ITERABLE.sum())
176         .isWithin(ALLOWED_ERROR)
177         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
178     assertThat(MANY_VALUES_STATS_ITERATOR.sum())
179         .isWithin(ALLOWED_ERROR)
180         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
181     assertThat(MANY_VALUES_STATS_SNAPSHOT.sum())
182         .isWithin(ALLOWED_ERROR)
183         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
184     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.sum())
185         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
186         .of(INTEGER_MANY_VALUES_MEAN * INTEGER_MANY_VALUES_COUNT);
187     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.sum())
188         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
189         .of(INTEGER_MANY_VALUES_MEAN * INTEGER_MANY_VALUES_COUNT);
190     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.sum())
191         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
192         .of(LONG_MANY_VALUES_MEAN * LONG_MANY_VALUES_COUNT);
193     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.sum())
194         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
195         .of(LONG_MANY_VALUES_MEAN * LONG_MANY_VALUES_COUNT);
196   }
197 
testPopulationVariance()198   public void testPopulationVariance() {
199     try {
200       EMPTY_STATS_VARARGS.populationVariance();
201       fail("Expected IllegalStateException");
202     } catch (IllegalStateException expected) {
203     }
204     try {
205       EMPTY_STATS_ITERABLE.populationVariance();
206       fail("Expected IllegalStateException");
207     } catch (IllegalStateException expected) {
208     }
209     assertThat(ONE_VALUE_STATS.populationVariance()).isWithin(0.0).of(0.0);
210     assertThat(Stats.of(POSITIVE_INFINITY).populationVariance()).isNaN();
211     assertThat(Stats.of(NEGATIVE_INFINITY).populationVariance()).isNaN();
212     assertThat(Stats.of(NaN).populationVariance()).isNaN();
213     assertThat(TWO_VALUES_STATS.populationVariance())
214         .isWithin(ALLOWED_ERROR)
215         .of(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS / 2);
216     assertThat(MANY_VALUES_STATS_VARARGS.populationVariance())
217         .isWithin(ALLOWED_ERROR)
218         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
219     // For datasets of many double values created from an iterable, we test many combinations of
220     // finite and non-finite values:
221     for (ManyValues values : ALL_MANY_VALUES) {
222       double populationVariance = Stats.of(values.asIterable()).populationVariance();
223       if (values.hasAnyNonFinite()) {
224         assertWithMessage("population variance of " + values).that(populationVariance).isNaN();
225       } else {
226         assertWithMessage("population variance of " + values)
227             .that(populationVariance)
228             .isWithin(ALLOWED_ERROR)
229             .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
230       }
231     }
232     assertThat(MANY_VALUES_STATS_ITERATOR.populationVariance())
233         .isWithin(ALLOWED_ERROR)
234         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
235     assertThat(MANY_VALUES_STATS_SNAPSHOT.populationVariance())
236         .isWithin(ALLOWED_ERROR)
237         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
238     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.populationVariance())
239         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
240         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT);
241     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.populationVariance())
242         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
243         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT);
244     assertThat(LARGE_INTEGER_VALUES_STATS.populationVariance())
245         .isWithin(ALLOWED_ERROR * Integer.MAX_VALUE * Integer.MAX_VALUE)
246         .of(LARGE_INTEGER_VALUES_POPULATION_VARIANCE);
247     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.populationVariance())
248         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
249         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT);
250     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.populationVariance())
251         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
252         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT);
253     assertThat(LARGE_LONG_VALUES_STATS.populationVariance())
254         .isWithin(ALLOWED_ERROR * Long.MAX_VALUE * Long.MAX_VALUE)
255         .of(LARGE_LONG_VALUES_POPULATION_VARIANCE);
256   }
257 
testPopulationStandardDeviation()258   public void testPopulationStandardDeviation() {
259     try {
260       EMPTY_STATS_VARARGS.populationStandardDeviation();
261       fail("Expected IllegalStateException");
262     } catch (IllegalStateException expected) {
263     }
264     try {
265       EMPTY_STATS_ITERABLE.populationStandardDeviation();
266       fail("Expected IllegalStateException");
267     } catch (IllegalStateException expected) {
268     }
269     assertThat(ONE_VALUE_STATS.populationStandardDeviation()).isWithin(0.0).of(0.0);
270     assertThat(TWO_VALUES_STATS.populationStandardDeviation())
271         .isWithin(ALLOWED_ERROR)
272         .of(sqrt(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS / 2));
273     assertThat(MANY_VALUES_STATS_VARARGS.populationStandardDeviation())
274         .isWithin(ALLOWED_ERROR)
275         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
276     assertThat(MANY_VALUES_STATS_ITERABLE.populationStandardDeviation())
277         .isWithin(ALLOWED_ERROR)
278         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
279     assertThat(MANY_VALUES_STATS_ITERATOR.populationStandardDeviation())
280         .isWithin(ALLOWED_ERROR)
281         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
282     assertThat(MANY_VALUES_STATS_SNAPSHOT.populationStandardDeviation())
283         .isWithin(ALLOWED_ERROR)
284         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
285     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.populationStandardDeviation())
286         .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
287         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT));
288     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.populationStandardDeviation())
289         .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
290         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT));
291     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.populationStandardDeviation())
292         .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
293         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT));
294     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.populationStandardDeviation())
295         .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
296         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT));
297   }
298 
testSampleVariance()299   public void testSampleVariance() {
300     try {
301       EMPTY_STATS_VARARGS.sampleVariance();
302       fail("Expected IllegalStateException");
303     } catch (IllegalStateException expected) {
304     }
305     try {
306       EMPTY_STATS_ITERABLE.sampleVariance();
307       fail("Expected IllegalStateException");
308     } catch (IllegalStateException expected) {
309     }
310     try {
311       ONE_VALUE_STATS.sampleVariance();
312       fail("Expected IllegalStateException");
313     } catch (IllegalStateException expected) {
314     }
315     assertThat(TWO_VALUES_STATS.sampleVariance())
316         .isWithin(ALLOWED_ERROR)
317         .of(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS);
318     assertThat(MANY_VALUES_STATS_VARARGS.sampleVariance())
319         .isWithin(ALLOWED_ERROR)
320         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
321     assertThat(MANY_VALUES_STATS_ITERABLE.sampleVariance())
322         .isWithin(ALLOWED_ERROR)
323         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
324     assertThat(MANY_VALUES_STATS_ITERATOR.sampleVariance())
325         .isWithin(ALLOWED_ERROR)
326         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
327     assertThat(MANY_VALUES_STATS_SNAPSHOT.sampleVariance())
328         .isWithin(ALLOWED_ERROR)
329         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
330     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.sampleVariance())
331         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
332         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1));
333     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.sampleVariance())
334         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
335         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1));
336     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.sampleVariance())
337         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
338         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1));
339     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.sampleVariance())
340         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
341         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1));
342   }
343 
testSampleStandardDeviation()344   public void testSampleStandardDeviation() {
345     try {
346       EMPTY_STATS_VARARGS.sampleStandardDeviation();
347       fail("Expected IllegalStateException");
348     } catch (IllegalStateException expected) {
349     }
350     try {
351       EMPTY_STATS_ITERABLE.sampleStandardDeviation();
352       fail("Expected IllegalStateException");
353     } catch (IllegalStateException expected) {
354     }
355     try {
356       ONE_VALUE_STATS.sampleStandardDeviation();
357       fail("Expected IllegalStateException");
358     } catch (IllegalStateException expected) {
359     }
360     assertThat(TWO_VALUES_STATS.sampleStandardDeviation())
361         .isWithin(ALLOWED_ERROR)
362         .of(sqrt(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS));
363     assertThat(MANY_VALUES_STATS_VARARGS.sampleStandardDeviation())
364         .isWithin(ALLOWED_ERROR)
365         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
366     assertThat(MANY_VALUES_STATS_ITERABLE.sampleStandardDeviation())
367         .isWithin(ALLOWED_ERROR)
368         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
369     assertThat(MANY_VALUES_STATS_ITERATOR.sampleStandardDeviation())
370         .isWithin(ALLOWED_ERROR)
371         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
372     assertThat(MANY_VALUES_STATS_SNAPSHOT.sampleStandardDeviation())
373         .isWithin(ALLOWED_ERROR)
374         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
375     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.sampleStandardDeviation())
376         .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
377         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1)));
378     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.sampleStandardDeviation())
379         .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
380         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1)));
381     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.sampleStandardDeviation())
382         .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
383         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1)));
384     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.sampleStandardDeviation())
385         .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
386         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1)));
387   }
388 
testMax()389   public void testMax() {
390     try {
391       EMPTY_STATS_VARARGS.max();
392       fail("Expected IllegalStateException");
393     } catch (IllegalStateException expected) {
394     }
395     try {
396       EMPTY_STATS_ITERABLE.max();
397       fail("Expected IllegalStateException");
398     } catch (IllegalStateException expected) {
399     }
400     assertThat(ONE_VALUE_STATS.max()).isEqualTo(ONE_VALUE);
401     assertThat(Stats.of(POSITIVE_INFINITY).max()).isPositiveInfinity();
402     assertThat(Stats.of(NEGATIVE_INFINITY).max()).isNegativeInfinity();
403     assertThat(Stats.of(NaN).max()).isNaN();
404     assertThat(TWO_VALUES_STATS.max()).isEqualTo(TWO_VALUES_MAX);
405     assertThat(MANY_VALUES_STATS_VARARGS.max()).isEqualTo(MANY_VALUES_MAX);
406     assertThat(MANY_VALUES_STATS_ITERABLE.max()).isEqualTo(MANY_VALUES_MAX);
407     // For datasets of many double values created from an iterator, we test many combinations of
408     // finite and non-finite values:
409     for (ManyValues values : ALL_MANY_VALUES) {
410       double max = Stats.of(values.asIterable().iterator()).max();
411       if (values.hasAnyNaN()) {
412         assertWithMessage("max of " + values).that(max).isNaN();
413       } else if (values.hasAnyPositiveInfinity()) {
414         assertWithMessage("max of " + values).that(max).isPositiveInfinity();
415       } else {
416         assertWithMessage("max of " + values).that(max).isEqualTo(MANY_VALUES_MAX);
417       }
418     }
419     assertThat(MANY_VALUES_STATS_SNAPSHOT.max()).isEqualTo(MANY_VALUES_MAX);
420     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.max()).isEqualTo(INTEGER_MANY_VALUES_MAX);
421     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.max()).isEqualTo(INTEGER_MANY_VALUES_MAX);
422     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.max()).isEqualTo(LONG_MANY_VALUES_MAX);
423     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.max()).isEqualTo(LONG_MANY_VALUES_MAX);
424   }
425 
testMin()426   public void testMin() {
427     try {
428       EMPTY_STATS_VARARGS.min();
429       fail("Expected IllegalStateException");
430     } catch (IllegalStateException expected) {
431     }
432     try {
433       EMPTY_STATS_ITERABLE.min();
434       fail("Expected IllegalStateException");
435     } catch (IllegalStateException expected) {
436     }
437     assertThat(ONE_VALUE_STATS.min()).isEqualTo(ONE_VALUE);
438     assertThat(Stats.of(POSITIVE_INFINITY).min()).isPositiveInfinity();
439     assertThat(Stats.of(NEGATIVE_INFINITY).min()).isNegativeInfinity();
440     assertThat(Stats.of(NaN).min()).isNaN();
441     assertThat(TWO_VALUES_STATS.min()).isEqualTo(TWO_VALUES_MIN);
442     assertThat(MANY_VALUES_STATS_VARARGS.min()).isEqualTo(MANY_VALUES_MIN);
443     assertThat(MANY_VALUES_STATS_ITERABLE.min()).isEqualTo(MANY_VALUES_MIN);
444     assertThat(MANY_VALUES_STATS_ITERATOR.min()).isEqualTo(MANY_VALUES_MIN);
445     // For datasets of many double values created from an accumulator snapshot, we test many
446     // combinations of finite and non-finite values:
447     for (ManyValues values : ALL_MANY_VALUES) {
448       StatsAccumulator accumulator = new StatsAccumulator();
449       accumulator.addAll(values.asIterable());
450       double min = accumulator.snapshot().min();
451       if (values.hasAnyNaN()) {
452         assertWithMessage("min of " + values).that(min).isNaN();
453       } else if (values.hasAnyNegativeInfinity()) {
454         assertWithMessage("min of " + values).that(min).isNegativeInfinity();
455       } else {
456         assertWithMessage("min of " + values).that(min).isEqualTo(MANY_VALUES_MIN);
457       }
458     }
459     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.min()).isEqualTo(INTEGER_MANY_VALUES_MIN);
460     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.min()).isEqualTo(INTEGER_MANY_VALUES_MIN);
461     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.min()).isEqualTo(LONG_MANY_VALUES_MIN);
462     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.min()).isEqualTo(LONG_MANY_VALUES_MIN);
463   }
464 
testEqualsAndHashCode()465   public void testEqualsAndHashCode() {
466     new EqualsTester()
467         .addEqualityGroup(
468             Stats.of(1.0, 1.0, 5.0, 5.0),
469             Stats.of(1.0, 1.0, 5.0, 5.0),
470             Stats.of(ImmutableList.of(1.0, 1.0, 5.0, 5.0)),
471             Stats.of(ImmutableList.of(1.0, 1.0, 5.0, 5.0).iterator()),
472             SerializableTester.reserialize(Stats.of(1.0, 1.0, 5.0, 5.0)))
473         .addEqualityGroup(Stats.of(1.0, 5.0))
474         .addEqualityGroup(Stats.of(1.0, 5.0, 1.0, 6.0))
475         .addEqualityGroup(Stats.of(2.0, 6.0, 2.0, 6.0))
476         .addEqualityGroup(
477             new Stats(5, -5.5, 55.5, -5.55, 5.55), new Stats(5, -5.5, 55.5, -5.55, 5.55))
478         .addEqualityGroup(new Stats(6, -5.5, 55.5, -5.55, 5.55))
479         .addEqualityGroup(new Stats(5, -5.6, 55.5, -5.55, 5.55))
480         .addEqualityGroup(new Stats(5, -5.5, 55.6, -5.55, 5.55))
481         .addEqualityGroup(new Stats(5, -5.5, 55.5, -5.56, 5.55))
482         .addEqualityGroup(new Stats(5, -5.5, 55.5, -5.55, 5.56))
483         .testEquals();
484   }
485 
testSerializable()486   public void testSerializable() {
487     SerializableTester.reserializeAndAssert(MANY_VALUES_STATS_ITERABLE);
488   }
489 
testToString()490   public void testToString() {
491     assertThat(EMPTY_STATS_VARARGS.toString()).isEqualTo("Stats{count=0}");
492     assertThat(MANY_VALUES_STATS_ITERABLE.toString())
493         .isEqualTo(
494             "Stats{count="
495                 + MANY_VALUES_STATS_ITERABLE.count()
496                 + ", mean="
497                 + MANY_VALUES_STATS_ITERABLE.mean()
498                 + ", populationStandardDeviation="
499                 + MANY_VALUES_STATS_ITERABLE.populationStandardDeviation()
500                 + ", min="
501                 + MANY_VALUES_STATS_ITERABLE.min()
502                 + ", max="
503                 + MANY_VALUES_STATS_ITERABLE.max()
504                 + "}");
505   }
506 
testMeanOf()507   public void testMeanOf() {
508     try {
509       Stats.meanOf();
510       fail("Expected IllegalArgumentException");
511     } catch (IllegalArgumentException expected) {
512     }
513     try {
514       Stats.meanOf(ImmutableList.<Number>of());
515       fail("Expected IllegalArgumentException");
516     } catch (IllegalArgumentException expected) {
517     }
518     assertThat(Stats.meanOf(ONE_VALUE)).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
519     assertThat(Stats.meanOf(POSITIVE_INFINITY)).isPositiveInfinity();
520     assertThat(Stats.meanOf(NEGATIVE_INFINITY)).isNegativeInfinity();
521     assertThat(Stats.meanOf(NaN)).isNaN();
522     assertThat(Stats.meanOf(TWO_VALUES)).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MEAN);
523     // For datasets of many double values created from an array, we test many combinations of finite
524     // and non-finite values:
525     for (ManyValues values : ALL_MANY_VALUES) {
526       double mean = Stats.meanOf(values.asArray());
527       if (values.hasAnyNaN()) {
528         assertWithMessage("mean of " + values).that(mean).isNaN();
529       } else if (values.hasAnyPositiveInfinity() && values.hasAnyNegativeInfinity()) {
530         assertWithMessage("mean of " + values).that(mean).isNaN();
531       } else if (values.hasAnyPositiveInfinity()) {
532         assertWithMessage("mean of " + values).that(mean).isPositiveInfinity();
533       } else if (values.hasAnyNegativeInfinity()) {
534         assertWithMessage("mean of " + values).that(mean).isNegativeInfinity();
535       } else {
536         assertWithMessage("mean of " + values)
537             .that(mean)
538             .isWithin(ALLOWED_ERROR)
539             .of(MANY_VALUES_MEAN);
540       }
541     }
542     assertThat(Stats.meanOf(MANY_VALUES)).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
543     assertThat(Stats.meanOf(MANY_VALUES.iterator())).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
544     assertThat(Stats.meanOf(INTEGER_MANY_VALUES))
545         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
546         .of(INTEGER_MANY_VALUES_MEAN);
547     assertThat(Stats.meanOf(Ints.toArray(INTEGER_MANY_VALUES)))
548         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
549         .of(INTEGER_MANY_VALUES_MEAN);
550     assertThat(Stats.meanOf(LONG_MANY_VALUES))
551         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
552         .of(LONG_MANY_VALUES_MEAN);
553     assertThat(Stats.meanOf(Longs.toArray(LONG_MANY_VALUES)))
554         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
555         .of(LONG_MANY_VALUES_MEAN);
556   }
557 
testToByteArrayAndFromByteArrayRoundTrip()558   public void testToByteArrayAndFromByteArrayRoundTrip() {
559     for (Stats stats : ALL_STATS) {
560       byte[] statsByteArray = stats.toByteArray();
561 
562       // Round trip to byte array and back
563       assertThat(Stats.fromByteArray(statsByteArray)).isEqualTo(stats);
564     }
565   }
566 
testFromByteArray_withNullInputThrowsNullPointerException()567   public void testFromByteArray_withNullInputThrowsNullPointerException() {
568     try {
569       Stats.fromByteArray(null);
570       fail("Expected NullPointerException");
571     } catch (NullPointerException expected) {
572     }
573   }
574 
testFromByteArray_withEmptyArrayInputThrowsIllegalArgumentException()575   public void testFromByteArray_withEmptyArrayInputThrowsIllegalArgumentException() {
576     try {
577       Stats.fromByteArray(new byte[0]);
578       fail("Expected IllegalArgumentException");
579     } catch (IllegalArgumentException expected) {
580     }
581   }
582 
testFromByteArray_withTooLongArrayInputThrowsIllegalArgumentException()583   public void testFromByteArray_withTooLongArrayInputThrowsIllegalArgumentException() {
584     byte[] buffer = MANY_VALUES_STATS_VARARGS.toByteArray();
585     byte[] tooLongByteArray =
586         ByteBuffer.allocate(buffer.length + 2)
587             .order(ByteOrder.LITTLE_ENDIAN)
588             .put(buffer)
589             .putChar('.')
590             .array();
591     try {
592       Stats.fromByteArray(tooLongByteArray);
593       fail("Expected IllegalArgumentException");
594     } catch (IllegalArgumentException expected) {
595     }
596   }
597 
testFromByteArrayWithTooShortArrayInputThrowsIllegalArgumentException()598   public void testFromByteArrayWithTooShortArrayInputThrowsIllegalArgumentException() {
599     byte[] buffer = MANY_VALUES_STATS_VARARGS.toByteArray();
600     byte[] tooShortByteArray =
601         ByteBuffer.allocate(buffer.length - 1)
602             .order(ByteOrder.LITTLE_ENDIAN)
603             .put(buffer, 0, Stats.BYTES - 1)
604             .array();
605     try {
606       Stats.fromByteArray(tooShortByteArray);
607       fail("Expected IllegalArgumentException");
608     } catch (IllegalArgumentException expected) {
609     }
610   }
611 }
612