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