001/* 002 * Copyright (C) 2012 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 */ 014 015package com.google.common.math; 016 017import static com.google.common.base.Preconditions.checkArgument; 018import static com.google.common.base.Preconditions.checkNotNull; 019import static com.google.common.base.Preconditions.checkState; 020import static com.google.common.math.DoubleUtils.ensureNonNegative; 021import static com.google.common.math.StatsAccumulator.calculateNewMeanNonFinite; 022import static com.google.common.primitives.Doubles.isFinite; 023import static java.lang.Double.NaN; 024import static java.lang.Double.doubleToLongBits; 025import static java.lang.Double.isNaN; 026 027import com.google.common.annotations.Beta; 028import com.google.common.annotations.GwtIncompatible; 029import com.google.common.base.MoreObjects; 030import com.google.common.base.Objects; 031import java.io.Serializable; 032import java.nio.ByteBuffer; 033import java.nio.ByteOrder; 034import java.util.Iterator; 035import org.checkerframework.checker.nullness.compatqual.NullableDecl; 036 037/** 038 * A bundle of statistical summary values -- sum, count, mean/average, min and max, and several 039 * forms of variance -- that were computed from a single set of zero or more floating-point values. 040 * 041 * <p>There are two ways to obtain a {@code Stats} instance: 042 * 043 * <ul> 044 * <li>If all the values you want to summarize are already known, use the appropriate {@code 045 * Stats.of} factory method below. Primitive arrays, iterables and iterators of any kind of 046 * {@code Number}, and primitive varargs are supported. 047 * <li>Or, to avoid storing up all the data first, create a {@link StatsAccumulator} instance, 048 * feed values to it as you get them, then call {@link StatsAccumulator#snapshot}. 049 * </ul> 050 * 051 * <p>Static convenience methods called {@code meanOf} are also provided for users who wish to 052 * calculate <i>only</i> the mean. 053 * 054 * <p><b>Java 8 users:</b> If you are not using any of the variance statistics, you may wish to use 055 * built-in JDK libraries instead of this class. 056 * 057 * @author Pete Gillin 058 * @author Kevin Bourrillion 059 * @since 20.0 060 */ 061@Beta 062@GwtIncompatible 063public final class Stats implements Serializable { 064 065 private final long count; 066 private final double mean; 067 private final double sumOfSquaresOfDeltas; 068 private final double min; 069 private final double max; 070 071 /** 072 * Internal constructor. Users should use {@link #of} or {@link StatsAccumulator#snapshot}. 073 * 074 * <p>To ensure that the created instance obeys its contract, the parameters should satisfy the 075 * following constraints. This is the callers responsibility and is not enforced here. 076 * 077 * <ul> 078 * <li>If {@code count} is 0, {@code mean} may have any finite value (its only usage will be to 079 * get multiplied by 0 to calculate the sum), and the other parameters may have any values 080 * (they will not be used). 081 * <li>If {@code count} is 1, {@code sumOfSquaresOfDeltas} must be exactly 0.0 or {@link 082 * Double#NaN}. 083 * </ul> 084 */ 085 Stats(long count, double mean, double sumOfSquaresOfDeltas, double min, double max) { 086 this.count = count; 087 this.mean = mean; 088 this.sumOfSquaresOfDeltas = sumOfSquaresOfDeltas; 089 this.min = min; 090 this.max = max; 091 } 092 093 /** 094 * Returns statistics over a dataset containing the given values. 095 * 096 * @param values a series of values, which will be converted to {@code double} values (this may 097 * cause loss of precision) 098 */ 099 public static Stats of(Iterable<? extends Number> values) { 100 StatsAccumulator accumulator = new StatsAccumulator(); 101 accumulator.addAll(values); 102 return accumulator.snapshot(); 103 } 104 105 /** 106 * Returns statistics over a dataset containing the given values. The iterator will be completely 107 * consumed by this method. 108 * 109 * @param values a series of values, which will be converted to {@code double} values (this may 110 * cause loss of precision) 111 */ 112 public static Stats of(Iterator<? extends Number> values) { 113 StatsAccumulator accumulator = new StatsAccumulator(); 114 accumulator.addAll(values); 115 return accumulator.snapshot(); 116 } 117 118 /** 119 * Returns statistics over a dataset containing the given values. 120 * 121 * @param values a series of values 122 */ 123 public static Stats of(double... values) { 124 StatsAccumulator acummulator = new StatsAccumulator(); 125 acummulator.addAll(values); 126 return acummulator.snapshot(); 127 } 128 129 /** 130 * Returns statistics over a dataset containing the given values. 131 * 132 * @param values a series of values 133 */ 134 public static Stats of(int... values) { 135 StatsAccumulator acummulator = new StatsAccumulator(); 136 acummulator.addAll(values); 137 return acummulator.snapshot(); 138 } 139 140 /** 141 * Returns statistics over a dataset containing the given values. 142 * 143 * @param values a series of values, which will be converted to {@code double} values (this may 144 * cause loss of precision for longs of magnitude over 2^53 (slightly over 9e15)) 145 */ 146 public static Stats of(long... values) { 147 StatsAccumulator acummulator = new StatsAccumulator(); 148 acummulator.addAll(values); 149 return acummulator.snapshot(); 150 } 151 152 /** Returns the number of values. */ 153 public long count() { 154 return count; 155 } 156 157 /** 158 * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the 159 * values. The count must be non-zero. 160 * 161 * <p>If these values are a sample drawn from a population, this is also an unbiased estimator of 162 * the arithmetic mean of the population. 163 * 164 * <h3>Non-finite values</h3> 165 * 166 * <p>If the dataset contains {@link Double#NaN} then the result is {@link Double#NaN}. If it 167 * contains both {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} then the 168 * result is {@link Double#NaN}. If it contains {@link Double#POSITIVE_INFINITY} and finite values 169 * only or {@link Double#POSITIVE_INFINITY} only, the result is {@link Double#POSITIVE_INFINITY}. 170 * If it contains {@link Double#NEGATIVE_INFINITY} and finite values only or {@link 171 * Double#NEGATIVE_INFINITY} only, the result is {@link Double#NEGATIVE_INFINITY}. 172 * 173 * <p>If you only want to calculate the mean, use {@link #meanOf} instead of creating a {@link 174 * Stats} instance. 175 * 176 * @throws IllegalStateException if the dataset is empty 177 */ 178 public double mean() { 179 checkState(count != 0); 180 return mean; 181 } 182 183 /** 184 * Returns the sum of the values. 185 * 186 * <h3>Non-finite values</h3> 187 * 188 * <p>If the dataset contains {@link Double#NaN} then the result is {@link Double#NaN}. If it 189 * contains both {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} then the 190 * result is {@link Double#NaN}. If it contains {@link Double#POSITIVE_INFINITY} and finite values 191 * only or {@link Double#POSITIVE_INFINITY} only, the result is {@link Double#POSITIVE_INFINITY}. 192 * If it contains {@link Double#NEGATIVE_INFINITY} and finite values only or {@link 193 * Double#NEGATIVE_INFINITY} only, the result is {@link Double#NEGATIVE_INFINITY}. 194 */ 195 public double sum() { 196 return mean * count; 197 } 198 199 /** 200 * Returns the <a href="http://en.wikipedia.org/wiki/Variance#Population_variance">population 201 * variance</a> of the values. The count must be non-zero. 202 * 203 * <p>This is guaranteed to return zero if the dataset contains only exactly one finite value. It 204 * is not guaranteed to return zero when the dataset consists of the same value multiple times, 205 * due to numerical errors. However, it is guaranteed never to return a negative result. 206 * 207 * <h3>Non-finite values</h3> 208 * 209 * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link 210 * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link Double#NaN}. 211 * 212 * @throws IllegalStateException if the dataset is empty 213 */ 214 public double populationVariance() { 215 checkState(count > 0); 216 if (isNaN(sumOfSquaresOfDeltas)) { 217 return NaN; 218 } 219 if (count == 1) { 220 return 0.0; 221 } 222 return ensureNonNegative(sumOfSquaresOfDeltas) / count(); 223 } 224 225 /** 226 * Returns the <a 227 * href="http://en.wikipedia.org/wiki/Standard_deviation#Definition_of_population_values"> 228 * population standard deviation</a> of the values. The count must be non-zero. 229 * 230 * <p>This is guaranteed to return zero if the dataset contains only exactly one finite value. It 231 * is not guaranteed to return zero when the dataset consists of the same value multiple times, 232 * due to numerical errors. However, it is guaranteed never to return a negative result. 233 * 234 * <h3>Non-finite values</h3> 235 * 236 * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link 237 * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link Double#NaN}. 238 * 239 * @throws IllegalStateException if the dataset is empty 240 */ 241 public double populationStandardDeviation() { 242 return Math.sqrt(populationVariance()); 243 } 244 245 /** 246 * Returns the <a href="http://en.wikipedia.org/wiki/Variance#Sample_variance">unbiased sample 247 * variance</a> of the values. If this dataset is a sample drawn from a population, this is an 248 * unbiased estimator of the population variance of the population. The count must be greater than 249 * one. 250 * 251 * <p>This is not guaranteed to return zero when the dataset consists of the same value multiple 252 * times, due to numerical errors. However, it is guaranteed never to return a negative result. 253 * 254 * <h3>Non-finite values</h3> 255 * 256 * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link 257 * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link Double#NaN}. 258 * 259 * @throws IllegalStateException if the dataset is empty or contains a single value 260 */ 261 public double sampleVariance() { 262 checkState(count > 1); 263 if (isNaN(sumOfSquaresOfDeltas)) { 264 return NaN; 265 } 266 return ensureNonNegative(sumOfSquaresOfDeltas) / (count - 1); 267 } 268 269 /** 270 * Returns the <a 271 * href="http://en.wikipedia.org/wiki/Standard_deviation#Corrected_sample_standard_deviation"> 272 * corrected sample standard deviation</a> of the values. If this dataset is a sample drawn from a 273 * population, this is an estimator of the population standard deviation of the population which 274 * is less biased than {@link #populationStandardDeviation()} (the unbiased estimator depends on 275 * the distribution). The count must be greater than one. 276 * 277 * <p>This is not guaranteed to return zero when the dataset consists of the same value multiple 278 * times, due to numerical errors. However, it is guaranteed never to return a negative result. 279 * 280 * <h3>Non-finite values</h3> 281 * 282 * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link 283 * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link Double#NaN}. 284 * 285 * @throws IllegalStateException if the dataset is empty or contains a single value 286 */ 287 public double sampleStandardDeviation() { 288 return Math.sqrt(sampleVariance()); 289 } 290 291 /** 292 * Returns the lowest value in the dataset. The count must be non-zero. 293 * 294 * <h3>Non-finite values</h3> 295 * 296 * <p>If the dataset contains {@link Double#NaN} then the result is {@link Double#NaN}. If it 297 * contains {@link Double#NEGATIVE_INFINITY} and not {@link Double#NaN} then the result is {@link 298 * Double#NEGATIVE_INFINITY}. If it contains {@link Double#POSITIVE_INFINITY} and finite values 299 * only then the result is the lowest finite value. If it contains {@link 300 * Double#POSITIVE_INFINITY} only then the result is {@link Double#POSITIVE_INFINITY}. 301 * 302 * @throws IllegalStateException if the dataset is empty 303 */ 304 public double min() { 305 checkState(count != 0); 306 return min; 307 } 308 309 /** 310 * Returns the highest value in the dataset. The count must be non-zero. 311 * 312 * <h3>Non-finite values</h3> 313 * 314 * <p>If the dataset contains {@link Double#NaN} then the result is {@link Double#NaN}. If it 315 * contains {@link Double#POSITIVE_INFINITY} and not {@link Double#NaN} then the result is {@link 316 * Double#POSITIVE_INFINITY}. If it contains {@link Double#NEGATIVE_INFINITY} and finite values 317 * only then the result is the highest finite value. If it contains {@link 318 * Double#NEGATIVE_INFINITY} only then the result is {@link Double#NEGATIVE_INFINITY}. 319 * 320 * @throws IllegalStateException if the dataset is empty 321 */ 322 public double max() { 323 checkState(count != 0); 324 return max; 325 } 326 327 /** 328 * {@inheritDoc} 329 * 330 * <p><b>Note:</b> This tests exact equality of the calculated statistics, including the floating 331 * point values. Two instances are guaranteed to be considered equal if one is copied from the 332 * other using {@code second = new StatsAccumulator().addAll(first).snapshot()}, if both were 333 * obtained by calling {@code snapshot()} on the same {@link StatsAccumulator} without adding any 334 * values in between the two calls, or if one is obtained from the other after round-tripping 335 * through java serialization. However, floating point rounding errors mean that it may be false 336 * for some instances where the statistics are mathematically equal, including instances 337 * constructed from the same values in a different order... or (in the general case) even in the 338 * same order. (It is guaranteed to return true for instances constructed from the same values in 339 * the same order if {@code strictfp} is in effect, or if the system architecture guarantees 340 * {@code strictfp}-like semantics.) 341 */ 342 @Override 343 public boolean equals(@NullableDecl Object obj) { 344 if (obj == null) { 345 return false; 346 } 347 if (getClass() != obj.getClass()) { 348 return false; 349 } 350 Stats other = (Stats) obj; 351 return count == other.count 352 && doubleToLongBits(mean) == doubleToLongBits(other.mean) 353 && doubleToLongBits(sumOfSquaresOfDeltas) == doubleToLongBits(other.sumOfSquaresOfDeltas) 354 && doubleToLongBits(min) == doubleToLongBits(other.min) 355 && doubleToLongBits(max) == doubleToLongBits(other.max); 356 } 357 358 /** 359 * {@inheritDoc} 360 * 361 * <p><b>Note:</b> This hash code is consistent with exact equality of the calculated statistics, 362 * including the floating point values. See the note on {@link #equals} for details. 363 */ 364 @Override 365 public int hashCode() { 366 return Objects.hashCode(count, mean, sumOfSquaresOfDeltas, min, max); 367 } 368 369 @Override 370 public String toString() { 371 if (count() > 0) { 372 return MoreObjects.toStringHelper(this) 373 .add("count", count) 374 .add("mean", mean) 375 .add("populationStandardDeviation", populationStandardDeviation()) 376 .add("min", min) 377 .add("max", max) 378 .toString(); 379 } else { 380 return MoreObjects.toStringHelper(this).add("count", count).toString(); 381 } 382 } 383 384 double sumOfSquaresOfDeltas() { 385 return sumOfSquaresOfDeltas; 386 } 387 388 /** 389 * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the 390 * values. The count must be non-zero. 391 * 392 * <p>The definition of the mean is the same as {@link Stats#mean}. 393 * 394 * @param values a series of values, which will be converted to {@code double} values (this may 395 * cause loss of precision) 396 * @throws IllegalArgumentException if the dataset is empty 397 */ 398 public static double meanOf(Iterable<? extends Number> values) { 399 return meanOf(values.iterator()); 400 } 401 402 /** 403 * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the 404 * values. The count must be non-zero. 405 * 406 * <p>The definition of the mean is the same as {@link Stats#mean}. 407 * 408 * @param values a series of values, which will be converted to {@code double} values (this may 409 * cause loss of precision) 410 * @throws IllegalArgumentException if the dataset is empty 411 */ 412 public static double meanOf(Iterator<? extends Number> values) { 413 checkArgument(values.hasNext()); 414 long count = 1; 415 double mean = values.next().doubleValue(); 416 while (values.hasNext()) { 417 double value = values.next().doubleValue(); 418 count++; 419 if (isFinite(value) && isFinite(mean)) { 420 // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) 421 mean += (value - mean) / count; 422 } else { 423 mean = calculateNewMeanNonFinite(mean, value); 424 } 425 } 426 return mean; 427 } 428 429 /** 430 * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the 431 * values. The count must be non-zero. 432 * 433 * <p>The definition of the mean is the same as {@link Stats#mean}. 434 * 435 * @param values a series of values 436 * @throws IllegalArgumentException if the dataset is empty 437 */ 438 public static double meanOf(double... values) { 439 checkArgument(values.length > 0); 440 double mean = values[0]; 441 for (int index = 1; index < values.length; index++) { 442 double value = values[index]; 443 if (isFinite(value) && isFinite(mean)) { 444 // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) 445 mean += (value - mean) / (index + 1); 446 } else { 447 mean = calculateNewMeanNonFinite(mean, value); 448 } 449 } 450 return mean; 451 } 452 453 /** 454 * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the 455 * values. The count must be non-zero. 456 * 457 * <p>The definition of the mean is the same as {@link Stats#mean}. 458 * 459 * @param values a series of values 460 * @throws IllegalArgumentException if the dataset is empty 461 */ 462 public static double meanOf(int... values) { 463 checkArgument(values.length > 0); 464 double mean = values[0]; 465 for (int index = 1; index < values.length; index++) { 466 double value = values[index]; 467 if (isFinite(value) && isFinite(mean)) { 468 // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) 469 mean += (value - mean) / (index + 1); 470 } else { 471 mean = calculateNewMeanNonFinite(mean, value); 472 } 473 } 474 return mean; 475 } 476 477 /** 478 * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the 479 * values. The count must be non-zero. 480 * 481 * <p>The definition of the mean is the same as {@link Stats#mean}. 482 * 483 * @param values a series of values, which will be converted to {@code double} values (this may 484 * cause loss of precision for longs of magnitude over 2^53 (slightly over 9e15)) 485 * @throws IllegalArgumentException if the dataset is empty 486 */ 487 public static double meanOf(long... values) { 488 checkArgument(values.length > 0); 489 double mean = values[0]; 490 for (int index = 1; index < values.length; index++) { 491 double value = values[index]; 492 if (isFinite(value) && isFinite(mean)) { 493 // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) 494 mean += (value - mean) / (index + 1); 495 } else { 496 mean = calculateNewMeanNonFinite(mean, value); 497 } 498 } 499 return mean; 500 } 501 502 // Serialization helpers 503 504 /** The size of byte array representation in bytes. */ 505 static final int BYTES = (Long.SIZE + Double.SIZE * 4) / Byte.SIZE; 506 507 /** 508 * Gets a byte array representation of this instance. 509 * 510 * <p><b>Note:</b> No guarantees are made regarding stability of the representation between 511 * versions. 512 */ 513 public byte[] toByteArray() { 514 ByteBuffer buff = ByteBuffer.allocate(BYTES).order(ByteOrder.LITTLE_ENDIAN); 515 writeTo(buff); 516 return buff.array(); 517 } 518 519 /** 520 * Writes to the given {@link ByteBuffer} a byte representation of this instance. 521 * 522 * <p><b>Note:</b> No guarantees are made regarding stability of the representation between 523 * versions. 524 * 525 * @param buffer A {@link ByteBuffer} with at least BYTES {@link ByteBuffer#remaining}, ordered as 526 * {@link ByteOrder#LITTLE_ENDIAN}, to which a BYTES-long byte representation of this instance 527 * is written. In the process increases the position of {@link ByteBuffer} by BYTES. 528 */ 529 void writeTo(ByteBuffer buffer) { 530 checkNotNull(buffer); 531 checkArgument( 532 buffer.remaining() >= BYTES, 533 "Expected at least Stats.BYTES = %s remaining , got %s", 534 BYTES, 535 buffer.remaining()); 536 buffer 537 .putLong(count) 538 .putDouble(mean) 539 .putDouble(sumOfSquaresOfDeltas) 540 .putDouble(min) 541 .putDouble(max); 542 } 543 544 /** 545 * Creates a Stats instance from the given byte representation which was obtained by {@link 546 * #toByteArray}. 547 * 548 * <p><b>Note:</b> No guarantees are made regarding stability of the representation between 549 * versions. 550 */ 551 public static Stats fromByteArray(byte[] byteArray) { 552 checkNotNull(byteArray); 553 checkArgument( 554 byteArray.length == BYTES, 555 "Expected Stats.BYTES = %s remaining , got %s", 556 BYTES, 557 byteArray.length); 558 return readFrom(ByteBuffer.wrap(byteArray).order(ByteOrder.LITTLE_ENDIAN)); 559 } 560 561 /** 562 * Creates a Stats instance from the byte representation read from the given {@link ByteBuffer}. 563 * 564 * <p><b>Note:</b> No guarantees are made regarding stability of the representation between 565 * versions. 566 * 567 * @param buffer A {@link ByteBuffer} with at least BYTES {@link ByteBuffer#remaining}, ordered as 568 * {@link ByteOrder#LITTLE_ENDIAN}, from which a BYTES-long byte representation of this 569 * instance is read. In the process increases the position of {@link ByteBuffer} by BYTES. 570 */ 571 static Stats readFrom(ByteBuffer buffer) { 572 checkNotNull(buffer); 573 checkArgument( 574 buffer.remaining() >= BYTES, 575 "Expected at least Stats.BYTES = %s remaining , got %s", 576 BYTES, 577 buffer.remaining()); 578 return new Stats( 579 buffer.getLong(), 580 buffer.getDouble(), 581 buffer.getDouble(), 582 buffer.getDouble(), 583 buffer.getDouble()); 584 } 585 586 private static final long serialVersionUID = 0; 587}