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