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