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