• 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.INTEGER_MANY_VALUES;
22 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_COUNT;
23 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_MAX;
24 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_MEAN;
25 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_MIN;
26 import static com.google.common.math.StatsTesting.INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS;
27 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES;
28 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_COUNT;
29 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_MAX;
30 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_MEAN;
31 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_MIN;
32 import static com.google.common.math.StatsTesting.LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS;
33 import static com.google.common.math.StatsTesting.MANY_VALUES;
34 import static com.google.common.math.StatsTesting.MANY_VALUES_COUNT;
35 import static com.google.common.math.StatsTesting.MANY_VALUES_MAX;
36 import static com.google.common.math.StatsTesting.MANY_VALUES_MEAN;
37 import static com.google.common.math.StatsTesting.MANY_VALUES_MIN;
38 import static com.google.common.math.StatsTesting.MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS;
39 import static com.google.common.math.StatsTesting.ONE_VALUE;
40 import static com.google.common.math.StatsTesting.OTHER_ONE_VALUE;
41 import static com.google.common.math.StatsTesting.TWO_VALUES;
42 import static com.google.common.math.StatsTesting.TWO_VALUES_MAX;
43 import static com.google.common.math.StatsTesting.TWO_VALUES_MEAN;
44 import static com.google.common.math.StatsTesting.TWO_VALUES_MIN;
45 import static com.google.common.math.StatsTesting.TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS;
46 import static com.google.common.truth.Truth.assertThat;
47 import static com.google.common.truth.Truth.assertWithMessage;
48 import static java.lang.Math.sqrt;
49 import static org.junit.Assert.assertThrows;
50 
51 import com.google.common.collect.ImmutableList;
52 import com.google.common.math.StatsTesting.ManyValues;
53 import com.google.common.primitives.Doubles;
54 import com.google.common.primitives.Longs;
55 import junit.framework.TestCase;
56 
57 /**
58  * Tests for {@link StatsAccumulator}. This tests the stats methods for instances built with {@link
59  * StatsAccumulator#add} and {@link StatsAccumulator#addAll}, and various error cases of the {@link
60  * StatsAccumulator#add} and {@link StatsAccumulator#addAll} methods. For tests of the {@link
61  * StatsAccumulator#snapshot} method which returns {@link Stats} instances, see {@link StatsTest}.
62  *
63  * @author Pete Gillin
64  */
65 public class StatsAccumulatorTest extends TestCase {
66 
67   private StatsAccumulator emptyAccumulator;
68   private StatsAccumulator emptyAccumulatorByAddAllEmptyIterable;
69   private StatsAccumulator emptyAccumulatorByAddAllEmptyStats;
70   private StatsAccumulator oneValueAccumulator;
71   private StatsAccumulator oneValueAccumulatorByAddAllEmptyStats;
72   private StatsAccumulator twoValuesAccumulator;
73   private StatsAccumulator twoValuesAccumulatorByAddAllStats;
74   private StatsAccumulator manyValuesAccumulatorByAddAllIterable;
75   private StatsAccumulator manyValuesAccumulatorByAddAllIterator;
76   private StatsAccumulator manyValuesAccumulatorByAddAllVarargs;
77   private StatsAccumulator manyValuesAccumulatorByRepeatedAdd;
78   private StatsAccumulator manyValuesAccumulatorByAddAndAddAll;
79   private StatsAccumulator manyValuesAccumulatorByAddAllStats;
80   private StatsAccumulator manyValuesAccumulatorByAddAllStatsAccumulator;
81   private StatsAccumulator integerManyValuesAccumulatorByAddAllIterable;
82   private StatsAccumulator longManyValuesAccumulatorByAddAllIterator;
83   private StatsAccumulator longManyValuesAccumulatorByAddAllVarargs;
84 
85   @Override
setUp()86   protected void setUp() throws Exception {
87     super.setUp();
88 
89     emptyAccumulator = new StatsAccumulator();
90 
91     emptyAccumulatorByAddAllEmptyIterable = new StatsAccumulator();
92     emptyAccumulatorByAddAllEmptyIterable.addAll(ImmutableList.<Double>of());
93 
94     emptyAccumulatorByAddAllEmptyStats = new StatsAccumulator();
95     emptyAccumulatorByAddAllEmptyStats.addAll(Stats.of());
96 
97     oneValueAccumulator = new StatsAccumulator();
98     oneValueAccumulator.add(ONE_VALUE);
99 
100     oneValueAccumulatorByAddAllEmptyStats = new StatsAccumulator();
101     oneValueAccumulatorByAddAllEmptyStats.add(ONE_VALUE);
102     oneValueAccumulatorByAddAllEmptyStats.addAll(Stats.of());
103 
104     twoValuesAccumulator = new StatsAccumulator();
105     twoValuesAccumulator.addAll(TWO_VALUES);
106 
107     twoValuesAccumulatorByAddAllStats = new StatsAccumulator();
108     twoValuesAccumulatorByAddAllStats.addAll(Stats.of(ONE_VALUE));
109     twoValuesAccumulatorByAddAllStats.addAll(Stats.of(OTHER_ONE_VALUE));
110 
111     manyValuesAccumulatorByAddAllIterable = new StatsAccumulator();
112     manyValuesAccumulatorByAddAllIterable.addAll(MANY_VALUES);
113 
114     manyValuesAccumulatorByAddAllIterator = new StatsAccumulator();
115     manyValuesAccumulatorByAddAllIterator.addAll(MANY_VALUES.iterator());
116 
117     manyValuesAccumulatorByAddAllVarargs = new StatsAccumulator();
118     manyValuesAccumulatorByAddAllVarargs.addAll(Doubles.toArray(MANY_VALUES));
119 
120     manyValuesAccumulatorByRepeatedAdd = new StatsAccumulator();
121     for (double value : MANY_VALUES) {
122       manyValuesAccumulatorByRepeatedAdd.add(value);
123     }
124 
125     manyValuesAccumulatorByAddAndAddAll = new StatsAccumulator();
126     manyValuesAccumulatorByAddAndAddAll.add(MANY_VALUES.get(0));
127     manyValuesAccumulatorByAddAndAddAll.addAll(MANY_VALUES.subList(1, MANY_VALUES.size()));
128 
129     manyValuesAccumulatorByAddAllStats = new StatsAccumulator();
130     manyValuesAccumulatorByAddAllStats.addAll(
131         Stats.of(MANY_VALUES.subList(0, MANY_VALUES.size() / 2)));
132     manyValuesAccumulatorByAddAllStats.addAll(
133         Stats.of(MANY_VALUES.subList(MANY_VALUES.size() / 2, MANY_VALUES.size())));
134 
135     manyValuesAccumulatorByAddAllStatsAccumulator = new StatsAccumulator();
136     manyValuesAccumulatorByAddAllStatsAccumulator.addAll(
137         statsAccumulatorOf(MANY_VALUES.subList(0, MANY_VALUES.size() / 2)));
138     manyValuesAccumulatorByAddAllStatsAccumulator.addAll(
139         statsAccumulatorOf(MANY_VALUES.subList(MANY_VALUES.size() / 2, MANY_VALUES.size())));
140 
141     integerManyValuesAccumulatorByAddAllIterable = new StatsAccumulator();
142     integerManyValuesAccumulatorByAddAllIterable.addAll(INTEGER_MANY_VALUES);
143 
144     longManyValuesAccumulatorByAddAllIterator = new StatsAccumulator();
145     longManyValuesAccumulatorByAddAllIterator.addAll(LONG_MANY_VALUES.iterator());
146 
147     longManyValuesAccumulatorByAddAllVarargs = new StatsAccumulator();
148     longManyValuesAccumulatorByAddAllVarargs.addAll(Longs.toArray(LONG_MANY_VALUES));
149   }
150 
statsAccumulatorOf(Iterable<? extends Number> values)151   private static StatsAccumulator statsAccumulatorOf(Iterable<? extends Number> values) {
152     StatsAccumulator accumulator = new StatsAccumulator();
153     accumulator.addAll(values);
154     return accumulator;
155   }
156 
testCount()157   public void testCount() {
158     assertThat(emptyAccumulator.count()).isEqualTo(0);
159     assertThat(emptyAccumulatorByAddAllEmptyIterable.count()).isEqualTo(0);
160     assertThat(emptyAccumulatorByAddAllEmptyStats.count()).isEqualTo(0);
161     assertThat(oneValueAccumulator.count()).isEqualTo(1);
162     assertThat(oneValueAccumulatorByAddAllEmptyStats.count()).isEqualTo(1);
163     assertThat(twoValuesAccumulator.count()).isEqualTo(2);
164     assertThat(twoValuesAccumulatorByAddAllStats.count()).isEqualTo(2);
165     assertThat(manyValuesAccumulatorByAddAllIterable.count()).isEqualTo(MANY_VALUES_COUNT);
166     assertThat(manyValuesAccumulatorByAddAllIterator.count()).isEqualTo(MANY_VALUES_COUNT);
167     assertThat(manyValuesAccumulatorByAddAllVarargs.count()).isEqualTo(MANY_VALUES_COUNT);
168     assertThat(manyValuesAccumulatorByRepeatedAdd.count()).isEqualTo(MANY_VALUES_COUNT);
169     assertThat(manyValuesAccumulatorByAddAndAddAll.count()).isEqualTo(MANY_VALUES_COUNT);
170     assertThat(manyValuesAccumulatorByAddAllStats.count()).isEqualTo(MANY_VALUES_COUNT);
171     assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.count()).isEqualTo(MANY_VALUES_COUNT);
172     assertThat(integerManyValuesAccumulatorByAddAllIterable.count())
173         .isEqualTo(StatsTesting.INTEGER_MANY_VALUES_COUNT);
174     assertThat(longManyValuesAccumulatorByAddAllIterator.count())
175         .isEqualTo(StatsTesting.LONG_MANY_VALUES_COUNT);
176     assertThat(longManyValuesAccumulatorByAddAllVarargs.count())
177         .isEqualTo(StatsTesting.LONG_MANY_VALUES_COUNT);
178   }
179 
testCountOverflow_doesNotThrow()180   public void testCountOverflow_doesNotThrow() {
181     StatsAccumulator accumulator = new StatsAccumulator();
182     accumulator.add(ONE_VALUE);
183     for (int power = 1; power < Long.SIZE - 1; power++) {
184       accumulator.addAll(accumulator.snapshot());
185     }
186     // Should overflow without throwing.
187     accumulator.addAll(accumulator.snapshot());
188     assertThat(accumulator.count()).isLessThan(0L);
189   }
190 
testMean()191   public void testMean() {
192     assertThrows(IllegalStateException.class, () -> emptyAccumulator.mean());
193     assertThrows(IllegalStateException.class, () -> emptyAccumulatorByAddAllEmptyIterable.mean());
194     assertThrows(IllegalStateException.class, () -> emptyAccumulatorByAddAllEmptyStats.mean());
195     assertThat(oneValueAccumulator.mean()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
196     assertThat(oneValueAccumulatorByAddAllEmptyStats.mean()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
197     assertThat(twoValuesAccumulator.mean()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MEAN);
198     assertThat(twoValuesAccumulatorByAddAllStats.mean())
199         .isWithin(ALLOWED_ERROR)
200         .of(TWO_VALUES_MEAN);
201     assertThat(manyValuesAccumulatorByAddAllIterable.mean())
202         .isWithin(ALLOWED_ERROR)
203         .of(MANY_VALUES_MEAN);
204     assertThat(manyValuesAccumulatorByAddAllIterator.mean())
205         .isWithin(ALLOWED_ERROR)
206         .of(MANY_VALUES_MEAN);
207     assertThat(manyValuesAccumulatorByAddAllVarargs.mean())
208         .isWithin(ALLOWED_ERROR)
209         .of(MANY_VALUES_MEAN);
210     assertThat(manyValuesAccumulatorByRepeatedAdd.mean())
211         .isWithin(ALLOWED_ERROR)
212         .of(MANY_VALUES_MEAN);
213     assertThat(manyValuesAccumulatorByAddAndAddAll.mean())
214         .isWithin(ALLOWED_ERROR)
215         .of(MANY_VALUES_MEAN);
216     assertThat(manyValuesAccumulatorByAddAllStats.mean())
217         .isWithin(ALLOWED_ERROR)
218         .of(MANY_VALUES_MEAN);
219     assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.mean())
220         .isWithin(ALLOWED_ERROR)
221         .of(MANY_VALUES_MEAN);
222     // For datasets of many double values created from an iterable, we test many combinations of
223     // finite and non-finite values:
224     for (ManyValues values : ALL_MANY_VALUES) {
225       StatsAccumulator accumulator = new StatsAccumulator();
226       StatsAccumulator accumulatorByAddAllStats = new StatsAccumulator();
227       accumulator.addAll(values.asIterable());
228       for (double value : values.asIterable()) {
229         accumulatorByAddAllStats.addAll(Stats.of(value));
230       }
231       double mean = accumulator.mean();
232       double meanByAddAllStats = accumulatorByAddAllStats.mean();
233       if (values.hasAnyNaN()) {
234         assertWithMessage("mean of " + values).that(mean).isNaN();
235         assertWithMessage("mean by addAll(Stats) of " + values).that(meanByAddAllStats).isNaN();
236       } else if (values.hasAnyPositiveInfinity() && values.hasAnyNegativeInfinity()) {
237         assertWithMessage("mean of " + values).that(mean).isNaN();
238         assertWithMessage("mean by addAll(Stats) of " + values).that(meanByAddAllStats).isNaN();
239       } else if (values.hasAnyPositiveInfinity()) {
240         assertWithMessage("mean of " + values).that(mean).isPositiveInfinity();
241         assertWithMessage("mean by addAll(Stats) of " + values)
242             .that(meanByAddAllStats)
243             .isPositiveInfinity();
244       } else if (values.hasAnyNegativeInfinity()) {
245         assertWithMessage("mean of " + values).that(mean).isNegativeInfinity();
246         assertWithMessage("mean by addAll(Stats) of " + values)
247             .that(meanByAddAllStats)
248             .isNegativeInfinity();
249       } else {
250         assertWithMessage("mean of " + values)
251             .that(mean)
252             .isWithin(ALLOWED_ERROR)
253             .of(MANY_VALUES_MEAN);
254         assertWithMessage("mean by addAll(Stats) of " + values)
255             .that(meanByAddAllStats)
256             .isWithin(ALLOWED_ERROR)
257             .of(MANY_VALUES_MEAN);
258       }
259     }
260     assertThat(integerManyValuesAccumulatorByAddAllIterable.mean())
261         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
262         .of(INTEGER_MANY_VALUES_MEAN);
263     assertThat(longManyValuesAccumulatorByAddAllIterator.mean())
264         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
265         .of(LONG_MANY_VALUES_MEAN);
266     assertThat(longManyValuesAccumulatorByAddAllVarargs.mean())
267         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
268         .of(LONG_MANY_VALUES_MEAN);
269   }
270 
testSum()271   public void testSum() {
272     assertThat(emptyAccumulator.sum()).isEqualTo(0.0);
273     assertThat(emptyAccumulatorByAddAllEmptyIterable.sum()).isEqualTo(0.0);
274     assertThat(emptyAccumulatorByAddAllEmptyStats.sum()).isEqualTo(0.0);
275     assertThat(oneValueAccumulator.sum()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
276     assertThat(oneValueAccumulatorByAddAllEmptyStats.sum()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
277     assertThat(twoValuesAccumulator.sum()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MEAN * 2);
278     assertThat(twoValuesAccumulatorByAddAllStats.sum())
279         .isWithin(ALLOWED_ERROR)
280         .of(TWO_VALUES_MEAN * 2);
281     assertThat(manyValuesAccumulatorByAddAllIterable.sum())
282         .isWithin(ALLOWED_ERROR)
283         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
284     assertThat(manyValuesAccumulatorByAddAllIterator.sum())
285         .isWithin(ALLOWED_ERROR)
286         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
287     assertThat(manyValuesAccumulatorByAddAllVarargs.sum())
288         .isWithin(ALLOWED_ERROR)
289         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
290     assertThat(manyValuesAccumulatorByRepeatedAdd.sum())
291         .isWithin(ALLOWED_ERROR)
292         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
293     assertThat(manyValuesAccumulatorByAddAndAddAll.sum())
294         .isWithin(ALLOWED_ERROR)
295         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
296     assertThat(manyValuesAccumulatorByAddAllStats.sum())
297         .isWithin(ALLOWED_ERROR)
298         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
299     assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.sum())
300         .isWithin(ALLOWED_ERROR)
301         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
302     assertThat(integerManyValuesAccumulatorByAddAllIterable.sum())
303         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
304         .of(INTEGER_MANY_VALUES_MEAN * INTEGER_MANY_VALUES_COUNT);
305     assertThat(longManyValuesAccumulatorByAddAllIterator.sum())
306         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
307         .of(LONG_MANY_VALUES_MEAN * LONG_MANY_VALUES_COUNT);
308     assertThat(longManyValuesAccumulatorByAddAllVarargs.sum())
309         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
310         .of(LONG_MANY_VALUES_MEAN * LONG_MANY_VALUES_COUNT);
311   }
312 
testPopulationVariance()313   public void testPopulationVariance() {
314     assertThrows(IllegalStateException.class, () -> emptyAccumulator.populationVariance());
315     assertThrows(
316         IllegalStateException.class,
317         () -> emptyAccumulatorByAddAllEmptyIterable.populationVariance());
318     assertThrows(
319         IllegalStateException.class, () -> emptyAccumulatorByAddAllEmptyStats.populationVariance());
320     assertThat(oneValueAccumulator.populationVariance()).isEqualTo(0.0);
321     assertThat(oneValueAccumulatorByAddAllEmptyStats.populationVariance()).isEqualTo(0.0);
322     assertThat(twoValuesAccumulator.populationVariance())
323         .isWithin(ALLOWED_ERROR)
324         .of(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS / 2);
325     assertThat(twoValuesAccumulatorByAddAllStats.populationVariance())
326         .isWithin(ALLOWED_ERROR)
327         .of(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS / 2);
328     assertThat(manyValuesAccumulatorByAddAllIterable.populationVariance())
329         .isWithin(ALLOWED_ERROR)
330         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
331     assertThat(manyValuesAccumulatorByAddAllIterator.populationVariance())
332         .isWithin(ALLOWED_ERROR)
333         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
334     assertThat(manyValuesAccumulatorByAddAllVarargs.populationVariance())
335         .isWithin(ALLOWED_ERROR)
336         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
337     assertThat(manyValuesAccumulatorByRepeatedAdd.populationVariance())
338         .isWithin(ALLOWED_ERROR)
339         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
340     assertThat(manyValuesAccumulatorByAddAndAddAll.populationVariance())
341         .isWithin(ALLOWED_ERROR)
342         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
343     assertThat(manyValuesAccumulatorByAddAllStats.populationVariance())
344         .isWithin(ALLOWED_ERROR)
345         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
346     assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.populationVariance())
347         .isWithin(ALLOWED_ERROR)
348         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
349     // For datasets of many double values created from an iterator, we test many combinations of
350     // finite and non-finite values:
351     for (ManyValues values : ALL_MANY_VALUES) {
352       StatsAccumulator accumulator = new StatsAccumulator();
353       StatsAccumulator accumulatorByAddAllStats = new StatsAccumulator();
354       accumulator.addAll(values.asIterable().iterator());
355       for (double value : values.asIterable()) {
356         accumulatorByAddAllStats.addAll(Stats.of(value));
357       }
358       double populationVariance = accumulator.populationVariance();
359       double populationVarianceByAddAllStats = accumulatorByAddAllStats.populationVariance();
360       if (values.hasAnyNonFinite()) {
361         assertWithMessage("population variance of " + values).that(populationVariance).isNaN();
362         assertWithMessage("population variance by addAll(Stats) of " + values)
363             .that(populationVarianceByAddAllStats)
364             .isNaN();
365       } else {
366         assertWithMessage("population variance of " + values)
367             .that(populationVariance)
368             .isWithin(ALLOWED_ERROR)
369             .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
370         assertWithMessage("population variance by addAll(Stats) of " + values)
371             .that(populationVarianceByAddAllStats)
372             .isWithin(ALLOWED_ERROR)
373             .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
374       }
375     }
376     assertThat(integerManyValuesAccumulatorByAddAllIterable.populationVariance())
377         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
378         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT);
379     assertThat(longManyValuesAccumulatorByAddAllIterator.populationVariance())
380         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
381         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT);
382     assertThat(longManyValuesAccumulatorByAddAllVarargs.populationVariance())
383         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
384         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT);
385   }
386 
testPopulationStandardDeviation()387   public void testPopulationStandardDeviation() {
388     assertThrows(IllegalStateException.class, () -> emptyAccumulator.populationStandardDeviation());
389     assertThrows(
390         IllegalStateException.class,
391         () -> emptyAccumulatorByAddAllEmptyIterable.populationStandardDeviation());
392     assertThrows(
393         IllegalStateException.class,
394         () -> emptyAccumulatorByAddAllEmptyStats.populationStandardDeviation());
395     assertThat(oneValueAccumulator.populationStandardDeviation()).isEqualTo(0.0);
396     assertThat(oneValueAccumulatorByAddAllEmptyStats.populationStandardDeviation()).isEqualTo(0.0);
397     assertThat(twoValuesAccumulator.populationStandardDeviation())
398         .isWithin(ALLOWED_ERROR)
399         .of(sqrt(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS / 2));
400     assertThat(twoValuesAccumulatorByAddAllStats.populationStandardDeviation())
401         .isWithin(ALLOWED_ERROR)
402         .of(sqrt(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS / 2));
403     assertThat(manyValuesAccumulatorByAddAllIterable.populationStandardDeviation())
404         .isWithin(ALLOWED_ERROR)
405         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
406     assertThat(manyValuesAccumulatorByAddAllIterator.populationStandardDeviation())
407         .isWithin(ALLOWED_ERROR)
408         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
409     assertThat(manyValuesAccumulatorByAddAllVarargs.populationStandardDeviation())
410         .isWithin(ALLOWED_ERROR)
411         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
412     assertThat(manyValuesAccumulatorByRepeatedAdd.populationStandardDeviation())
413         .isWithin(ALLOWED_ERROR)
414         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
415     assertThat(manyValuesAccumulatorByAddAndAddAll.populationStandardDeviation())
416         .isWithin(ALLOWED_ERROR)
417         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
418     assertThat(manyValuesAccumulatorByAddAllStats.populationStandardDeviation())
419         .isWithin(ALLOWED_ERROR)
420         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
421     assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.populationStandardDeviation())
422         .isWithin(ALLOWED_ERROR)
423         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
424     assertThat(integerManyValuesAccumulatorByAddAllIterable.populationStandardDeviation())
425         .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
426         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT));
427     assertThat(longManyValuesAccumulatorByAddAllIterator.populationStandardDeviation())
428         .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
429         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT));
430     assertThat(longManyValuesAccumulatorByAddAllVarargs.populationStandardDeviation())
431         .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
432         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT));
433   }
434 
testSampleVariance()435   public void testSampleVariance() {
436     assertThrows(IllegalStateException.class, () -> emptyAccumulator.sampleVariance());
437     assertThrows(
438         IllegalStateException.class, () -> emptyAccumulatorByAddAllEmptyIterable.sampleVariance());
439     assertThrows(
440         IllegalStateException.class, () -> emptyAccumulatorByAddAllEmptyStats.sampleVariance());
441     assertThrows(IllegalStateException.class, () -> oneValueAccumulator.sampleVariance());
442     assertThrows(
443         IllegalStateException.class, () -> oneValueAccumulatorByAddAllEmptyStats.sampleVariance());
444     assertThat(twoValuesAccumulator.sampleVariance())
445         .isWithin(ALLOWED_ERROR)
446         .of(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS);
447     assertThat(twoValuesAccumulatorByAddAllStats.sampleVariance())
448         .isWithin(ALLOWED_ERROR)
449         .of(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS);
450     assertThat(manyValuesAccumulatorByAddAllIterable.sampleVariance())
451         .isWithin(ALLOWED_ERROR)
452         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
453     assertThat(manyValuesAccumulatorByAddAllIterator.sampleVariance())
454         .isWithin(ALLOWED_ERROR)
455         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
456     assertThat(manyValuesAccumulatorByAddAllVarargs.sampleVariance())
457         .isWithin(ALLOWED_ERROR)
458         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
459     assertThat(manyValuesAccumulatorByRepeatedAdd.sampleVariance())
460         .isWithin(ALLOWED_ERROR)
461         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
462     assertThat(manyValuesAccumulatorByAddAndAddAll.sampleVariance())
463         .isWithin(ALLOWED_ERROR)
464         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
465     assertThat(manyValuesAccumulatorByAddAllStats.sampleVariance())
466         .isWithin(ALLOWED_ERROR)
467         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
468     assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.sampleVariance())
469         .isWithin(ALLOWED_ERROR)
470         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
471     assertThat(integerManyValuesAccumulatorByAddAllIterable.sampleVariance())
472         .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
473         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1));
474     assertThat(longManyValuesAccumulatorByAddAllIterator.sampleVariance())
475         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
476         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1));
477     assertThat(longManyValuesAccumulatorByAddAllVarargs.sampleVariance())
478         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
479         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1));
480   }
481 
testSampleStandardDeviation()482   public void testSampleStandardDeviation() {
483     assertThrows(IllegalStateException.class, () -> emptyAccumulator.sampleStandardDeviation());
484     assertThrows(
485         IllegalStateException.class,
486         () -> emptyAccumulatorByAddAllEmptyIterable.sampleStandardDeviation());
487     assertThrows(
488         IllegalStateException.class,
489         () -> emptyAccumulatorByAddAllEmptyStats.sampleStandardDeviation());
490     assertThrows(IllegalStateException.class, () -> oneValueAccumulator.sampleStandardDeviation());
491     assertThrows(
492         IllegalStateException.class,
493         () -> oneValueAccumulatorByAddAllEmptyStats.sampleStandardDeviation());
494     assertThat(twoValuesAccumulator.sampleStandardDeviation())
495         .isWithin(ALLOWED_ERROR)
496         .of(sqrt(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS));
497     assertThat(twoValuesAccumulatorByAddAllStats.sampleStandardDeviation())
498         .isWithin(ALLOWED_ERROR)
499         .of(sqrt(TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS));
500     assertThat(manyValuesAccumulatorByAddAllIterable.sampleStandardDeviation())
501         .isWithin(ALLOWED_ERROR)
502         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
503     assertThat(manyValuesAccumulatorByAddAllIterator.sampleStandardDeviation())
504         .isWithin(ALLOWED_ERROR)
505         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
506     assertThat(manyValuesAccumulatorByAddAllVarargs.sampleStandardDeviation())
507         .isWithin(ALLOWED_ERROR)
508         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
509     assertThat(manyValuesAccumulatorByRepeatedAdd.sampleStandardDeviation())
510         .isWithin(ALLOWED_ERROR)
511         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
512     assertThat(manyValuesAccumulatorByAddAndAddAll.sampleStandardDeviation())
513         .isWithin(ALLOWED_ERROR)
514         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
515     assertThat(manyValuesAccumulatorByAddAllStats.sampleStandardDeviation())
516         .isWithin(ALLOWED_ERROR)
517         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
518     assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.sampleStandardDeviation())
519         .isWithin(ALLOWED_ERROR)
520         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
521     assertThat(integerManyValuesAccumulatorByAddAllIterable.sampleStandardDeviation())
522         .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
523         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1)));
524     assertThat(longManyValuesAccumulatorByAddAllIterator.sampleStandardDeviation())
525         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
526         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1)));
527     assertThat(longManyValuesAccumulatorByAddAllVarargs.sampleStandardDeviation())
528         .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
529         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1)));
530   }
531 
testMax()532   public void testMax() {
533     assertThrows(IllegalStateException.class, () -> emptyAccumulator.max());
534     assertThrows(IllegalStateException.class, () -> emptyAccumulatorByAddAllEmptyIterable.max());
535     assertThrows(IllegalStateException.class, () -> emptyAccumulatorByAddAllEmptyStats.max());
536     assertThat(oneValueAccumulator.max()).isEqualTo(ONE_VALUE);
537     assertThat(oneValueAccumulatorByAddAllEmptyStats.max()).isEqualTo(ONE_VALUE);
538     assertThat(twoValuesAccumulator.max()).isEqualTo(TWO_VALUES_MAX);
539     assertThat(twoValuesAccumulatorByAddAllStats.max()).isEqualTo(TWO_VALUES_MAX);
540     assertThat(manyValuesAccumulatorByAddAllIterable.max()).isEqualTo(MANY_VALUES_MAX);
541     assertThat(manyValuesAccumulatorByAddAllIterator.max()).isEqualTo(MANY_VALUES_MAX);
542     assertThat(manyValuesAccumulatorByAddAllVarargs.max()).isEqualTo(MANY_VALUES_MAX);
543     assertThat(manyValuesAccumulatorByRepeatedAdd.max()).isEqualTo(MANY_VALUES_MAX);
544     assertThat(manyValuesAccumulatorByAddAndAddAll.max()).isEqualTo(MANY_VALUES_MAX);
545     assertThat(manyValuesAccumulatorByAddAllStats.max()).isEqualTo(MANY_VALUES_MAX);
546     assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.max()).isEqualTo(MANY_VALUES_MAX);
547     // For datasets of many double values created from an array, we test many combinations of
548     // finite and non-finite values:
549     for (ManyValues values : ALL_MANY_VALUES) {
550       StatsAccumulator accumulator = new StatsAccumulator();
551       StatsAccumulator accumulatorByAddAllStats = new StatsAccumulator();
552       accumulator.addAll(values.asArray());
553       for (double value : values.asIterable()) {
554         accumulatorByAddAllStats.addAll(Stats.of(value));
555       }
556       double max = accumulator.max();
557       double maxByAddAllStats = accumulatorByAddAllStats.max();
558       if (values.hasAnyNaN()) {
559         assertWithMessage("max of " + values).that(max).isNaN();
560         assertWithMessage("max by addAll(Stats) of " + values).that(maxByAddAllStats).isNaN();
561       } else if (values.hasAnyPositiveInfinity()) {
562         assertWithMessage("max of " + values).that(max).isPositiveInfinity();
563         assertWithMessage("max by addAll(Stats) of " + values)
564             .that(maxByAddAllStats)
565             .isPositiveInfinity();
566       } else {
567         assertWithMessage("max of " + values).that(max).isEqualTo(MANY_VALUES_MAX);
568         assertWithMessage("max by addAll(Stats) of " + values)
569             .that(maxByAddAllStats)
570             .isEqualTo(MANY_VALUES_MAX);
571       }
572     }
573     assertThat(integerManyValuesAccumulatorByAddAllIterable.max())
574         .isEqualTo(INTEGER_MANY_VALUES_MAX);
575     assertThat(longManyValuesAccumulatorByAddAllIterator.max()).isEqualTo(LONG_MANY_VALUES_MAX);
576     assertThat(longManyValuesAccumulatorByAddAllVarargs.max()).isEqualTo(LONG_MANY_VALUES_MAX);
577   }
578 
testMin()579   public void testMin() {
580     assertThrows(IllegalStateException.class, () -> emptyAccumulator.min());
581     assertThrows(IllegalStateException.class, () -> emptyAccumulatorByAddAllEmptyIterable.min());
582     assertThrows(IllegalStateException.class, () -> emptyAccumulatorByAddAllEmptyStats.min());
583     assertThat(oneValueAccumulator.min()).isEqualTo(ONE_VALUE);
584     assertThat(oneValueAccumulatorByAddAllEmptyStats.min()).isEqualTo(ONE_VALUE);
585     assertThat(twoValuesAccumulator.min()).isEqualTo(TWO_VALUES_MIN);
586     assertThat(twoValuesAccumulatorByAddAllStats.min()).isEqualTo(TWO_VALUES_MIN);
587     assertThat(manyValuesAccumulatorByAddAllIterable.min()).isEqualTo(MANY_VALUES_MIN);
588     assertThat(manyValuesAccumulatorByAddAllIterator.min()).isEqualTo(MANY_VALUES_MIN);
589     assertThat(manyValuesAccumulatorByAddAllVarargs.min()).isEqualTo(MANY_VALUES_MIN);
590     assertThat(manyValuesAccumulatorByRepeatedAdd.min()).isEqualTo(MANY_VALUES_MIN);
591     assertThat(manyValuesAccumulatorByAddAndAddAll.min()).isEqualTo(MANY_VALUES_MIN);
592     assertThat(manyValuesAccumulatorByAddAllStats.min()).isEqualTo(MANY_VALUES_MIN);
593     assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.min()).isEqualTo(MANY_VALUES_MIN);
594     // For datasets of many double values created by adding elements individually, we test many
595     // combinations of finite and non-finite values:
596     for (ManyValues values : ALL_MANY_VALUES) {
597       StatsAccumulator accumulator = new StatsAccumulator();
598       StatsAccumulator accumulatorByAddAllStats = new StatsAccumulator();
599       for (double value : values.asIterable()) {
600         accumulator.add(value);
601         accumulatorByAddAllStats.addAll(Stats.of(value));
602       }
603       double min = accumulator.min();
604       double minByAddAllStats = accumulatorByAddAllStats.min();
605       if (values.hasAnyNaN()) {
606         assertWithMessage("min of " + values).that(min).isNaN();
607         assertWithMessage("min by addAll(Stats) of " + values).that(minByAddAllStats).isNaN();
608       } else if (values.hasAnyNegativeInfinity()) {
609         assertWithMessage("min of " + values).that(min).isNegativeInfinity();
610         assertWithMessage("min by addAll(Stats) of " + values)
611             .that(minByAddAllStats)
612             .isNegativeInfinity();
613       } else {
614         assertWithMessage("min of " + values).that(min).isEqualTo(MANY_VALUES_MIN);
615         assertWithMessage("min by addAll(Stats) of " + values)
616             .that(minByAddAllStats)
617             .isEqualTo(MANY_VALUES_MIN);
618       }
619     }
620     assertThat(integerManyValuesAccumulatorByAddAllIterable.min())
621         .isEqualTo(INTEGER_MANY_VALUES_MIN);
622     assertThat(longManyValuesAccumulatorByAddAllIterator.min()).isEqualTo(LONG_MANY_VALUES_MIN);
623     assertThat(longManyValuesAccumulatorByAddAllVarargs.min()).isEqualTo(LONG_MANY_VALUES_MIN);
624   }
625 }
626