/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values * @throws IllegalArgumentException if the dataset is empty */ public static double meanOf(int... values) { checkArgument(values.length > 0); double mean = values[0]; for (int index = 1; index < values.length; index++) { double value = values[index]; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / (index + 1); } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; }
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values * @throws IllegalArgumentException if the dataset is empty */ public static double meanOf(double... values) { checkArgument(values.length > 0); double mean = values[0]; for (int index = 1; index < values.length; index++) { double value = values[index]; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / (index + 1); } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; }
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values, which will be converted to {@code double} values (this may * cause loss of precision for longs of magnitude over 2^53 (slightly over 9e15)) * @throws IllegalArgumentException if the dataset is empty */ public static double meanOf(long... values) { checkArgument(values.length > 0); double mean = values[0]; for (int index = 1; index < values.length; index++) { double value = values[index]; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / (index + 1); } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; }
/** Adds the given value to the dataset. */ public void add(double value) { if (count == 0) { count = 1; mean = value; min = value; max = value; if (!isFinite(value)) { sumOfSquaresOfDeltas = NaN; } } else { count++; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) and (16) double delta = value - mean; mean += delta / count; sumOfSquaresOfDeltas += delta * (value - mean); } else { mean = calculateNewMeanNonFinite(mean, value); sumOfSquaresOfDeltas = NaN; } min = Math.min(min, value); max = Math.max(max, value); } }
/** * Returns true iff {@code left} and {@code right} are finite values not within {@code tolerance} * of each other. Note that both this method and {@link #equalWithinTolerance} returns false if * either {@code left} or {@code right} is infinite or NaN. */ public static boolean notEqualWithinTolerance(double left, double right, double tolerance) { if (Doubles.isFinite(left) && Doubles.isFinite(right)) { return Math.abs(left - right) > Math.abs(tolerance); } else { return false; } }
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values, which will be converted to {@code double} values (this may * cause loss of precision) * @throws IllegalArgumentException if the dataset is empty */ public static double meanOf(Iterator<? extends Number> values) { checkArgument(values.hasNext()); long count = 1; double mean = values.next().doubleValue(); while (values.hasNext()) { double value = values.next().doubleValue(); count++; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / count; } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; }
private static boolean isClose(double a, double b, double epsilon) { double absA = Math.abs(a); double absB = Math.abs(b); double diff = Math.abs(a - b); if (!isFinite(a) || !isFinite(b)) { return Double.compare(a, b) == 0; } // a or b is zero or both are extremely close to it // relative error is less meaningful here if (a == 0 || b == 0 || diff < Float.MIN_NORMAL) { return diff < (epsilon * Float.MIN_NORMAL); } else { // use relative error return diff / Math.min((absA + absB), Float.MAX_VALUE) < epsilon; } }
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values * @throws IllegalArgumentException if the dataset is empty */ public static double meanOf(double... values) { checkArgument(values.length > 0); double mean = values[0]; for (int index = 1; index < values.length; index++) { double value = values[index]; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / (index + 1); } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; }
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values * @throws IllegalArgumentException if the dataset is empty */ public static double meanOf(int... values) { checkArgument(values.length > 0); double mean = values[0]; for (int index = 1; index < values.length; index++) { double value = values[index]; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / (index + 1); } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; }
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values, which will be converted to {@code double} values (this may * cause loss of precision for longs of magnitude over 2^53 (slightly over 9e15)) * @throws IllegalArgumentException if the dataset is empty */ public static double meanOf(long... values) { checkArgument(values.length > 0); double mean = values[0]; for (int index = 1; index < values.length; index++) { double value = values[index]; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / (index + 1); } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; }
/** Adds the given value to the dataset. */ public void add(double value) { if (count == 0) { count = 1; mean = value; min = value; max = value; if (!isFinite(value)) { sumOfSquaresOfDeltas = NaN; } } else { count++; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) and (16) double delta = value - mean; mean += delta / count; sumOfSquaresOfDeltas += delta * (value - mean); } else { mean = calculateNewMeanNonFinite(mean, value); sumOfSquaresOfDeltas = NaN; } min = Math.min(min, value); max = Math.max(max, value); } }
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values, which will be converted to {@code double} values (this may * cause loss of precision) * @throws IllegalArgumentException if the dataset is empty */ public static double meanOf(Iterator<? extends Number> values) { checkArgument(values.hasNext()); long count = 1; double mean = values.next().doubleValue(); while (values.hasNext()) { double value = values.next().doubleValue(); count++; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / count; } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; }
public void testIsFinite() { for (double value : NUMBERS) { assertEquals(!(Double.isNaN(value) || Double.isInfinite(value)), Doubles.isFinite(value)); } }
/** Adds the given pair of values to the dataset. */ public void add(double x, double y) { // We extend the recursive expression for the one-variable case at Art of Computer Programming // vol. 2, Knuth, 4.2.2, (16) to the two-variable case. We have two value series x_i and y_i. // We define the arithmetic means X_n = 1/n \sum_{i=1}^n x_i, and Y_n = 1/n \sum_{i=1}^n y_i. // We also define the sum of the products of the differences from the means // C_n = \sum_{i=1}^n x_i y_i - n X_n Y_n // for all n >= 1. Then for all n > 1: // C_{n-1} = \sum_{i=1}^{n-1} x_i y_i - (n-1) X_{n-1} Y_{n-1} // C_n - C_{n-1} = x_n y_n - n X_n Y_n + (n-1) X_{n-1} Y_{n-1} // = x_n y_n - X_n [ y_n + (n-1) Y_{n-1} ] + [ n X_n - x_n ] Y_{n-1} // = x_n y_n - X_n y_n - x_n Y_{n-1} + X_n Y_{n-1} // = (x_n - X_n) (y_n - Y_{n-1}) xStats.add(x); if (isFinite(x) && isFinite(y)) { if (xStats.count() > 1) { sumOfProductsOfDeltas += (x - xStats.mean()) * (y - yStats.mean()); } } else { sumOfProductsOfDeltas = NaN; } yStats.add(y); }
/** Adds the given pair of values to the dataset. */ public void add(double x, double y) { // We extend the recursive expression for the one-variable case at Art of Computer Programming // vol. 2, Knuth, 4.2.2, (16) to the two-variable case. We have two value series x_i and y_i. // We define the arithmetic means X_n = 1/n \sum_{i=1}^n x_i, and Y_n = 1/n \sum_{i=1}^n y_i. // We also define the sum of the products of the differences from the means // C_n = \sum_{i=1}^n x_i y_i - n X_n Y_n // for all n >= 1. Then for all n > 1: // C_{n-1} = \sum_{i=1}^{n-1} x_i y_i - (n-1) X_{n-1} Y_{n-1} // C_n - C_{n-1} = x_n y_n - n X_n Y_n + (n-1) X_{n-1} Y_{n-1} // = x_n y_n - X_n [ y_n + (n-1) Y_{n-1} ] + [ n X_n - x_n ] Y_{n-1} // = x_n y_n - X_n y_n - x_n Y_{n-1} + X_n Y_{n-1} // = (x_n - X_n) (y_n - Y_{n-1}) xStats.add(x); if (isFinite(x) && isFinite(y)) { if (xStats.count() > 1) { sumOfProductsOfDeltas += (x - xStats.mean()) * (y - yStats.mean()); } } else { sumOfProductsOfDeltas = NaN; } yStats.add(y); }
@Description("test if value is finite") @ScalarFunction @SqlType(StandardTypes.BOOLEAN) public static boolean isFinite(@SqlType(StandardTypes.DOUBLE) double num) { return Doubles.isFinite(num); }
/** * Adds the given statistics to the dataset, as if the individual values used to compute the * statistics had been added directly. */ public void addAll(Stats values) { if (values.count() == 0) { return; } if (count == 0) { count = values.count(); mean = values.mean(); sumOfSquaresOfDeltas = values.sumOfSquaresOfDeltas(); min = values.min(); max = values.max(); } else { count += values.count(); if (isFinite(mean) && isFinite(values.mean())) { // This is a generalized version of the calculation in add(double) above. double delta = values.mean() - mean; mean += delta * values.count() / count; sumOfSquaresOfDeltas += values.sumOfSquaresOfDeltas() + delta * (values.mean() - mean) * values.count(); } else { mean = calculateNewMeanNonFinite(mean, values.mean()); sumOfSquaresOfDeltas = NaN; } min = Math.min(min, values.min()); max = Math.max(max, values.max()); } }
/** * Adds the given statistics to the dataset, as if the individual values used to compute the * statistics had been added directly. */ public void addAll(Stats values) { if (values.count() == 0) { return; } if (count == 0) { count = values.count(); mean = values.mean(); sumOfSquaresOfDeltas = values.sumOfSquaresOfDeltas(); min = values.min(); max = values.max(); } else { count += values.count(); if (isFinite(mean) && isFinite(values.mean())) { // This is a generalized version of the calculation in add(double) above. double delta = values.mean() - mean; mean += delta * values.count() / count; sumOfSquaresOfDeltas += values.sumOfSquaresOfDeltas() + delta * (values.mean() - mean) * values.count(); } else { mean = calculateNewMeanNonFinite(mean, values.mean()); sumOfSquaresOfDeltas = NaN; } min = Math.min(min, values.min()); max = Math.max(max, values.max()); } }