aboutsummaryrefslogtreecommitdiff
path: root/android/guava/src/com/google/common/math/PairedStats.java
diff options
context:
space:
mode:
Diffstat (limited to 'android/guava/src/com/google/common/math/PairedStats.java')
-rw-r--r--android/guava/src/com/google/common/math/PairedStats.java319
1 files changed, 0 insertions, 319 deletions
diff --git a/android/guava/src/com/google/common/math/PairedStats.java b/android/guava/src/com/google/common/math/PairedStats.java
deleted file mode 100644
index a636e51d3..000000000
--- a/android/guava/src/com/google/common/math/PairedStats.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.Double.NaN;
-import static java.lang.Double.doubleToLongBits;
-import static java.lang.Double.isNaN;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Objects;
-import java.io.Serializable;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import org.checkerframework.checker.nullness.compatqual.NullableDecl;
-
-/**
- * An immutable value object capturing some basic statistics about a collection of paired double
- * values (e.g. points on a plane). Build instances with {@link PairedStatsAccumulator#snapshot}.
- *
- * @author Pete Gillin
- * @since 20.0
- */
-@Beta
-@GwtIncompatible
-public final class PairedStats implements Serializable {
-
- private final Stats xStats;
- private final Stats yStats;
- private final double sumOfProductsOfDeltas;
-
- /**
- * Internal constructor. Users should use {@link PairedStatsAccumulator#snapshot}.
- *
- * <p>To ensure that the created instance obeys its contract, the parameters should satisfy the
- * following constraints. This is the callers responsibility and is not enforced here.
- *
- * <ul>
- * <li>Both {@code xStats} and {@code yStats} must have the same {@code count}.
- * <li>If that {@code count} is 1, {@code sumOfProductsOfDeltas} must be exactly 0.0.
- * <li>If that {@code count} is more than 1, {@code sumOfProductsOfDeltas} must be finite.
- * </ul>
- */
- PairedStats(Stats xStats, Stats yStats, double sumOfProductsOfDeltas) {
- this.xStats = xStats;
- this.yStats = yStats;
- this.sumOfProductsOfDeltas = sumOfProductsOfDeltas;
- }
-
- /** Returns the number of pairs in the dataset. */
- public long count() {
- return xStats.count();
- }
-
- /** Returns the statistics on the {@code x} values alone. */
- public Stats xStats() {
- return xStats;
- }
-
- /** Returns the statistics on the {@code y} values alone. */
- public Stats yStats() {
- return yStats;
- }
-
- /**
- * Returns the population covariance of the values. The count must be non-zero.
- *
- * <p>This is guaranteed to return zero if the dataset contains a single pair of finite values. It
- * is not guaranteed to return zero when the dataset consists of the same pair of values multiple
- * times, due to numerical errors.
- *
- * <h3>Non-finite values</h3>
- *
- * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link
- * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link Double#NaN}.
- *
- * @throws IllegalStateException if the dataset is empty
- */
- public double populationCovariance() {
- checkState(count() != 0);
- return sumOfProductsOfDeltas / count();
- }
-
- /**
- * Returns the sample covariance of the values. The count must be greater than one.
- *
- * <p>This is not guaranteed to return zero when the dataset consists of the same pair of values
- * multiple times, due to numerical errors.
- *
- * <h3>Non-finite values</h3>
- *
- * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link
- * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link Double#NaN}.
- *
- * @throws IllegalStateException if the dataset is empty or contains a single pair of values
- */
- public double sampleCovariance() {
- checkState(count() > 1);
- return sumOfProductsOfDeltas / (count() - 1);
- }
-
- /**
- * Returns the <a href="http://mathworld.wolfram.com/CorrelationCoefficient.html">Pearson's or
- * product-moment correlation coefficient</a> of the values. The count must greater than one, and
- * the {@code x} and {@code y} values must both have non-zero population variance (i.e. {@code
- * xStats().populationVariance() > 0.0 && yStats().populationVariance() > 0.0}). The result is not
- * guaranteed to be exactly +/-1 even when the data are perfectly (anti-)correlated, due to
- * numerical errors. However, it is guaranteed to be in the inclusive range [-1, +1].
- *
- * <h3>Non-finite values</h3>
- *
- * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link
- * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link Double#NaN}.
- *
- * @throws IllegalStateException if the dataset is empty or contains a single pair of values, or
- * either the {@code x} and {@code y} dataset has zero population variance
- */
- public double pearsonsCorrelationCoefficient() {
- checkState(count() > 1);
- if (isNaN(sumOfProductsOfDeltas)) {
- return NaN;
- }
- double xSumOfSquaresOfDeltas = xStats().sumOfSquaresOfDeltas();
- double ySumOfSquaresOfDeltas = yStats().sumOfSquaresOfDeltas();
- checkState(xSumOfSquaresOfDeltas > 0.0);
- checkState(ySumOfSquaresOfDeltas > 0.0);
- // The product of two positive numbers can be zero if the multiplication underflowed. We
- // force a positive value by effectively rounding up to MIN_VALUE.
- double productOfSumsOfSquaresOfDeltas =
- ensurePositive(xSumOfSquaresOfDeltas * ySumOfSquaresOfDeltas);
- return ensureInUnitRange(sumOfProductsOfDeltas / Math.sqrt(productOfSumsOfSquaresOfDeltas));
- }
-
- /**
- * Returns a linear transformation giving the best fit to the data according to <a
- * href="http://mathworld.wolfram.com/LeastSquaresFitting.html">Ordinary Least Squares linear
- * regression</a> of {@code y} as a function of {@code x}. The count must be greater than one, and
- * either the {@code x} or {@code y} data must have a non-zero population variance (i.e. {@code
- * xStats().populationVariance() > 0.0 || yStats().populationVariance() > 0.0}). The result is
- * guaranteed to be horizontal if there is variance in the {@code x} data but not the {@code y}
- * data, and vertical if there is variance in the {@code y} data but not the {@code x} data.
- *
- * <p>This fit minimizes the root-mean-square error in {@code y} as a function of {@code x}. This
- * error is defined as the square root of the mean of the squares of the differences between the
- * actual {@code y} values of the data and the values predicted by the fit for the {@code x}
- * values (i.e. it is the square root of the mean of the squares of the vertical distances between
- * the data points and the best fit line). For this fit, this error is a fraction {@code sqrt(1 -
- * R*R)} of the population standard deviation of {@code y}, where {@code R} is the Pearson's
- * correlation coefficient (as given by {@link #pearsonsCorrelationCoefficient()}).
- *
- * <p>The corresponding root-mean-square error in {@code x} as a function of {@code y} is a
- * fraction {@code sqrt(1/(R*R) - 1)} of the population standard deviation of {@code x}. This fit
- * does not normally minimize that error: to do that, you should swap the roles of {@code x} and
- * {@code y}.
- *
- * <h3>Non-finite values</h3>
- *
- * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link
- * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link
- * LinearTransformation#forNaN()}.
- *
- * @throws IllegalStateException if the dataset is empty or contains a single pair of values, or
- * both the {@code x} and {@code y} dataset must have zero population variance
- */
- public LinearTransformation leastSquaresFit() {
- checkState(count() > 1);
- if (isNaN(sumOfProductsOfDeltas)) {
- return LinearTransformation.forNaN();
- }
- double xSumOfSquaresOfDeltas = xStats.sumOfSquaresOfDeltas();
- if (xSumOfSquaresOfDeltas > 0.0) {
- if (yStats.sumOfSquaresOfDeltas() > 0.0) {
- return LinearTransformation.mapping(xStats.mean(), yStats.mean())
- .withSlope(sumOfProductsOfDeltas / xSumOfSquaresOfDeltas);
- } else {
- return LinearTransformation.horizontal(yStats.mean());
- }
- } else {
- checkState(yStats.sumOfSquaresOfDeltas() > 0.0);
- return LinearTransformation.vertical(xStats.mean());
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * <p><b>Note:</b> This tests exact equality of the calculated statistics, including the floating
- * point values. Two instances are guaranteed to be considered equal if one is copied from the
- * other using {@code second = new PairedStatsAccumulator().addAll(first).snapshot()}, if both
- * were obtained by calling {@code snapshot()} on the same {@link PairedStatsAccumulator} without
- * adding any values in between the two calls, or if one is obtained from the other after
- * round-tripping through java serialization. However, floating point rounding errors mean that it
- * may be false for some instances where the statistics are mathematically equal, including
- * instances constructed from the same values in a different order... or (in the general case)
- * even in the same order. (It is guaranteed to return true for instances constructed from the
- * same values in the same order if {@code strictfp} is in effect, or if the system architecture
- * guarantees {@code strictfp}-like semantics.)
- */
- @Override
- public boolean equals(@NullableDecl Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- PairedStats other = (PairedStats) obj;
- return xStats.equals(other.xStats)
- && yStats.equals(other.yStats)
- && doubleToLongBits(sumOfProductsOfDeltas) == doubleToLongBits(other.sumOfProductsOfDeltas);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p><b>Note:</b> This hash code is consistent with exact equality of the calculated statistics,
- * including the floating point values. See the note on {@link #equals} for details.
- */
- @Override
- public int hashCode() {
- return Objects.hashCode(xStats, yStats, sumOfProductsOfDeltas);
- }
-
- @Override
- public String toString() {
- if (count() > 0) {
- return MoreObjects.toStringHelper(this)
- .add("xStats", xStats)
- .add("yStats", yStats)
- .add("populationCovariance", populationCovariance())
- .toString();
- } else {
- return MoreObjects.toStringHelper(this)
- .add("xStats", xStats)
- .add("yStats", yStats)
- .toString();
- }
- }
-
- double sumOfProductsOfDeltas() {
- return sumOfProductsOfDeltas;
- }
-
- private static double ensurePositive(double value) {
- if (value > 0.0) {
- return value;
- } else {
- return Double.MIN_VALUE;
- }
- }
-
- private static double ensureInUnitRange(double value) {
- if (value >= 1.0) {
- return 1.0;
- }
- if (value <= -1.0) {
- return -1.0;
- }
- return value;
- }
-
- // Serialization helpers
-
- /** The size of byte array representation in bytes. */
- private static final int BYTES = Stats.BYTES * 2 + Double.SIZE / Byte.SIZE;
-
- /**
- * Gets a byte array representation of this instance.
- *
- * <p><b>Note:</b> No guarantees are made regarding stability of the representation between
- * versions.
- */
- public byte[] toByteArray() {
- ByteBuffer buffer = ByteBuffer.allocate(BYTES).order(ByteOrder.LITTLE_ENDIAN);
- xStats.writeTo(buffer);
- yStats.writeTo(buffer);
- buffer.putDouble(sumOfProductsOfDeltas);
- return buffer.array();
- }
-
- /**
- * Creates a {@link PairedStats} instance from the given byte representation which was obtained by
- * {@link #toByteArray}.
- *
- * <p><b>Note:</b> No guarantees are made regarding stability of the representation between
- * versions.
- */
- public static PairedStats fromByteArray(byte[] byteArray) {
- checkNotNull(byteArray);
- checkArgument(
- byteArray.length == BYTES,
- "Expected PairedStats.BYTES = %s, got %s",
- BYTES,
- byteArray.length);
- ByteBuffer buffer = ByteBuffer.wrap(byteArray).order(ByteOrder.LITTLE_ENDIAN);
- Stats xStats = Stats.readFrom(buffer);
- Stats yStats = Stats.readFrom(buffer);
- double sumOfProductsOfDeltas = buffer.getDouble();
- return new PairedStats(xStats, yStats, sumOfProductsOfDeltas);
- }
-
- private static final long serialVersionUID = 0;
-}