This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-statistics.git

commit 33bd58fb891dd6975a4e6c299329d6adce1782e2
Author: Alex Herbert <[email protected]>
AuthorDate: Tue Jan 2 11:05:02 2024 +0000

    Use descriptive module to compute statistics
---
 commons-statistics-inference/pom.xml               |   6 +
 .../statistics/inference/ChiSquareTest.java        |   3 +-
 .../apache/commons/statistics/inference/GTest.java |   3 +-
 .../statistics/inference/StatisticUtils.java       | 149 +++++----------------
 .../apache/commons/statistics/inference/TTest.java |  31 +++--
 .../statistics/inference/StatisticUtilsTest.java   |  71 +++-------
 .../commons/statistics/inference/TTestTest.java    |  30 +++--
 7 files changed, 102 insertions(+), 191 deletions(-)

diff --git a/commons-statistics-inference/pom.xml 
b/commons-statistics-inference/pom.xml
index 127e490..aec3258 100644
--- a/commons-statistics-inference/pom.xml
+++ b/commons-statistics-inference/pom.xml
@@ -44,6 +44,12 @@
 
   <dependencies>
 
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-statistics-descriptive</artifactId>
+      <version>1.1-SNAPSHOT</version>
+    </dependency>
+
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-statistics-distribution</artifactId>
diff --git 
a/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/ChiSquareTest.java
 
b/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/ChiSquareTest.java
index 49e24aa..eb70b06 100644
--- 
a/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/ChiSquareTest.java
+++ 
b/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/ChiSquareTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.commons.statistics.inference;
 
+import org.apache.commons.statistics.descriptive.LongMean;
 import org.apache.commons.statistics.distribution.ChiSquaredDistribution;
 
 /**
@@ -98,7 +99,7 @@ public final class ChiSquareTest {
     public double statistic(long[] observed) {
         Arguments.checkValuesRequiredSize(observed.length, 2);
         Arguments.checkNonNegative(observed);
-        final double e = StatisticUtils.mean(observed);
+        final double e = LongMean.of(observed).getAsDouble();
         if (e == 0) {
             throw new InferenceException(InferenceException.NO_DATA);
         }
diff --git 
a/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/GTest.java
 
b/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/GTest.java
index 4e9ea69..b1f29ea 100644
--- 
a/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/GTest.java
+++ 
b/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/GTest.java
@@ -17,6 +17,7 @@
 package org.apache.commons.statistics.inference;
 
 import org.apache.commons.numbers.core.Sum;
+import org.apache.commons.statistics.descriptive.LongMean;
 import org.apache.commons.statistics.distribution.ChiSquaredDistribution;
 
 /**
@@ -107,7 +108,7 @@ public final class GTest {
     public double statistic(long[] observed) {
         Arguments.checkValuesRequiredSize(observed.length, 2);
         Arguments.checkNonNegative(observed);
-        final double e = StatisticUtils.mean(observed);
+        final double e = LongMean.of(observed).getAsDouble();
         if (e == 0) {
             throw new InferenceException(InferenceException.NO_DATA);
         }
diff --git 
a/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/StatisticUtils.java
 
b/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/StatisticUtils.java
index 7aaae5e..f618412 100644
--- 
a/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/StatisticUtils.java
+++ 
b/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/StatisticUtils.java
@@ -21,6 +21,7 @@ import java.util.Collection;
 import java.util.stream.IntStream;
 import org.apache.commons.numbers.core.DD;
 import org.apache.commons.numbers.core.Precision;
+import org.apache.commons.statistics.descriptive.Mean;
 
 /**
  * Utility computation methods.
@@ -120,33 +121,13 @@ final class StatisticUtils {
             sum.add(DD.of(v));
     }
 
-    /**
-     * Returns the arithmetic mean of the entries in the input array,
-     * or {@code NaN} if the array is empty.
-     *
-     * @param x Values.
-     * @return the mean of the values or NaN if length = 0
-     */
-    static double mean(long[] x) {
-        final int n = x.length;
-        if (n == 0) {
-            return Double.NaN;
-        }
-
-        // Single pass high accuracy sum. The total cannot be more than 2^63 * 
2^31 bits
-        // so can be exactly represented in a double-double. Cumulative error 
in the sum
-        // is (n-1) * 4eps with eps = 2^-106. The sum should be exact to 
double precision.
-        DD dd = DD.ZERO;
-        for (final long v : x) {
-            dd = add(dd, v);
-        }
-
-        return dd.divide(n).doubleValue();
-    }
+    // Specialised statistic methods not directly supported by 
o.a.c.statistics.descriptive
 
     /**
-     * Returns the arithmetic mean of the entries in the input array,
-     * or {@code NaN} if the array is empty.
+     * Returns the arithmetic mean of the entries in the input arrays,
+     * or {@code NaN} if the combined length of the arrays is zero.
+     *
+     * <p>Supports a combined length above the maximum array size.
      *
      * <p>A two-pass, corrected algorithm is used, starting with the 
definitional formula
      * computed using the array of stored values and then correcting this by 
adding the
@@ -155,88 +136,22 @@ final class StatisticUtils {
      * Journal of the American Statistical Association, Vol. 69, No. 348 
(Dec., 1974), pp.
      * 859-866.
      *
-     * @param x Values.
-     * @return the mean of the values or NaN if length = 0
-     */
-    static double mean(double[] x) {
-        final int n = x.length;
-        // No check for n == 0 -> return NaN.
-        // This internal method is only called with non-zero length arrays.
-        // The divide by zero creates NaN anyway.
-
-        // Adapted from 
org.apache.commons.math4.legacy.stat.descriptive.moment.Mean
-        // Updated to use a stream to support high-precision summation as the 
stream maintains
-        // a rounding-error term during the aggregation. This is important
-        // when summing differences which can create cancellation: x + -x => 0.
-
-        // Compute initial estimate using definitional formula
-        final double mean = Arrays.stream(x).sum() / n;
-
-        // Compute correction factor in second pass
-        return mean + Arrays.stream(x).map(v -> v - mean).sum() / n;
-    }
-
-    /**
-     * Returns the arithmetic mean of the entries in the input arrays,
-     * or {@code NaN} if the combined length of the arrays is zero.
-     *
-     * <p>This is the equivalent of using {@link #mean(double[])} with all the 
samples
-     * concatenated into a single array. Supports a combined length above the 
maximum array
-     * size.
-     *
      * @param samples Values.
      * @return the mean of the values or NaN if length = 0
-     * @see #mean(double[])
      */
     static double mean(Collection<double[]> samples) {
-        // See above for computation details
+        final double mean = samples.stream()
+            .map(Mean::of)
+            .reduce(Mean::combine)
+            .orElseGet(() -> Mean.create())
+            .getAsDouble();
+        // Second-pass correction.
+        // Note: The correction may not be finite in the event of extreme 
values.
+        // In this case the calling method computation will fail when the mean
+        // is used and we do not check for overflow here.
         final long n = samples.stream().mapToInt(x -> x.length).sum();
-        final double mean = 
samples.stream().flatMapToDouble(Arrays::stream).sum() / n;
-        return mean + samples.stream().flatMapToDouble(Arrays::stream).map(v 
-> v - mean).sum() / n;
-    }
-
-    /**
-     * Returns the variance of the entries in the input array, or {@code NaN} 
if the array
-     * is empty.
-     *
-     * <p>This method returns the bias-corrected sample variance (using {@code 
n - 1} in
-     * the denominator).
-     *
-     * <p>Uses a two-pass algorithm. Specifically, these methods use the 
"corrected
-     * two-pass algorithm" from Chan, Golub, Levesque, <i>Algorithms for 
Computing the
-     * Sample Variance</i>, American Statistician, vol. 37, no. 3 (1983) pp.
-     * 242-247.
-     *
-     * <p>Returns 0 for a single-value (i.e. length = 1) sample.
-     *
-     * @param x Values.
-     * @param mean the mean of the input array
-     * @return the variance of the values or NaN if the array is empty
-     */
-    static double variance(double[] x, double mean) {
-        final int n = x.length;
-        // No check for n == 0 -> return NaN.
-        // This internal method is only called with non-zero length arrays.
-        // The input mean of NaN for zero length creates NaN anyway.
-        if (n == 1) {
-            return 0;
-        }
-
-        // Adapted from 
org.apache.commons.math4.legacy.stat.descriptive.moment.Variance
-        // Use a stream to accumulate the sum of deviations in high precision.
-        // This compensation term for the sum of deviations from the mean -> 0.
-        // We sum the squares in standard precision as there is no 
cancellation of summands.
-        final double[] sumSq = {0};
-        final double sum2 = Arrays.stream(x).map(v -> {
-            final double dx = v - mean;
-            sumSq[0] += dx * dx;
-            return dx;
-        }).sum();
-
-        final double sum1 = sumSq[0];
-        // Bias corrected
-        // Note: variance ~ sum1 / (n-1) but with a correction term sum2
-        return (sum1 - (sum2 * sum2 / n)) / (n - 1);
+        return mean + samples.stream()
+            .flatMapToDouble(Arrays::stream).map(v -> v - mean).sum() / n;
     }
 
     /**
@@ -247,37 +162,46 @@ final class StatisticUtils {
      * sum(x[i] - y[i]) / x.length
      * </pre>
      *
-     * <p>This computes the same result as creating an array {@code z = x - y}
-     * and calling {@link #mean(double[]) mean(z)}, but without the 
intermediate array
-     * allocation.
+     * <p>This method avoids intermediate array allocation.
+     *
+     * <p>A two-pass, corrected algorithm is used, starting with the 
definitional formula
+     * computed using the array of stored values and then correcting this by 
adding the
+     * mean deviation of the data values from the arithmetic mean. See, e.g. 
"Comparison
+     * of Several Algorithms for Computing Sample Means and Variances," Robert 
F. Ling,
+     * Journal of the American Statistical Association, Vol. 69, No. 348 
(Dec., 1974), pp.
+     * 859-866.
      *
      * @param x First array.
      * @param y Second array.
      * @return mean of paired differences
      * @throws IllegalArgumentException if the arrays do not have the same 
length.
-     * @see #mean(double[])
      */
     static double meanDifference(double[] x, double[] y) {
         final int n = x.length;
         if (n != y.length) {
             throw new InferenceException(InferenceException.VALUES_MISMATCH, 
n, y.length);
         }
-        // See mean(double[]) for details.
         final double mean = IntStream.range(0, n).mapToDouble(i -> x[i] - 
y[i]).sum() / n;
         return mean + IntStream.range(0, n).mapToDouble(i -> (x[i] - y[i]) - 
mean).sum() / n;
     }
 
     /**
      * Returns the variance of the (signed) differences between corresponding 
elements of
-     * the input arrays.
+     * the input arrays, or {@code NaN} if the arrays are empty.
      *
      * <pre>
      * var(x[i] - y[i])
      * </pre>
      *
-     * <p>This computes the same result as creating an array {@code z = x - y}
-     * and calling {@link #variance(double[], double) variance(z, mean(z))}, 
but without the
-     * intermediate array allocation.
+     * <p>Returns the bias-corrected sample variance (using {@code n - 1} in 
the denominator).
+     * Returns 0 for a single-value (i.e. length = 1) sample.
+     *
+     * <p>This method avoids intermediate array allocation.
+     *
+     * <p>Uses a two-pass algorithm. Specifically, these methods use the 
"corrected
+     * two-pass algorithm" from Chan, Golub, Levesque, <i>Algorithms for 
Computing the
+     * Sample Variance</i>, American Statistician, vol. 37, no. 3 (1983) pp.
+     * 242-247.
      *
      * @param x First array.
      * @param y Second array.
@@ -285,14 +209,12 @@ final class StatisticUtils {
      * @return variance of paired differences
      * @throws IllegalArgumentException if the arrays do not have the same 
length.
      * @see #meanDifference(double[], double[])
-     * @see #variance(double[], double)
      */
     static double varianceDifference(double[] x, double[] y, double mean) {
         final int n = x.length;
         if (n != y.length) {
             throw new InferenceException(InferenceException.VALUES_MISMATCH, 
n, y.length);
         }
-        // See variance(double[]) for details.
         if (n == 1) {
             return 0;
         }
@@ -302,6 +224,7 @@ final class StatisticUtils {
             sumSq[0] += dx * dx;
             return dx;
         }).sum();
+        // sum-of-squared deviations = sum(x^2) - sum(x)^2 / n
         final double sum1 = sumSq[0];
         return (sum1 - (sum2 * sum2 / n)) / (n - 1);
     }
diff --git 
a/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/TTest.java
 
b/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/TTest.java
index 9b15769..25c654d 100644
--- 
a/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/TTest.java
+++ 
b/commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/TTest.java
@@ -16,7 +16,10 @@
  */
 package org.apache.commons.statistics.inference;
 
+import java.util.EnumSet;
 import java.util.Objects;
+import org.apache.commons.statistics.descriptive.DoubleStatistics;
+import org.apache.commons.statistics.descriptive.Statistic;
 import org.apache.commons.statistics.distribution.TDistribution;
 
 /**
@@ -178,8 +181,10 @@ public final class TTest {
      */
     public double statistic(double[] x) {
         final long n = checkSampleSize(x.length);
-        final double m = StatisticUtils.mean(x);
-        final double v = StatisticUtils.variance(x, m);
+        final DoubleStatistics s = DoubleStatistics.of(
+            EnumSet.of(Statistic.MEAN, Statistic.VARIANCE), x);
+        final double m = s.getAsDouble(Statistic.MEAN);
+        final double v = s.getAsDouble(Statistic.VARIANCE);
         return computeT(m - mu, v, n);
     }
 
@@ -263,10 +268,13 @@ public final class TTest {
     public double statistic(double[] x, double[] y) {
         final long n1 = checkSampleSize(x.length);
         final long n2 = checkSampleSize(y.length);
-        final double m1 = StatisticUtils.mean(x);
-        final double m2 = StatisticUtils.mean(y);
-        final double v1 = StatisticUtils.variance(x, m1);
-        final double v2 = StatisticUtils.variance(y, m2);
+        final DoubleStatistics.Builder b = 
DoubleStatistics.builder(Statistic.MEAN, Statistic.VARIANCE);
+        final DoubleStatistics s1 = b.build(x);
+        final double m1 = s1.getAsDouble(Statistic.MEAN);
+        final double v1 = s1.getAsDouble(Statistic.VARIANCE);
+        final DoubleStatistics s2 = b.build(y);
+        final double m2 = s2.getAsDouble(Statistic.MEAN);
+        final double v2 = s2.getAsDouble(Statistic.VARIANCE);
         return equalVariances ?
             computeHomoscedasticT(mu, m1, v1, n1, m2, v2, n2) :
             computeT(mu, m1, v1, n1, m2, v2, n2);
@@ -387,10 +395,13 @@ public final class TTest {
         // requires the variance. So repeat the computation and compute p.
         final long n1 = checkSampleSize(x.length);
         final long n2 = checkSampleSize(y.length);
-        final double m1 = StatisticUtils.mean(x);
-        final double m2 = StatisticUtils.mean(y);
-        final double v1 = StatisticUtils.variance(x, m1);
-        final double v2 = StatisticUtils.variance(y, m2);
+        final DoubleStatistics.Builder b = 
DoubleStatistics.builder(Statistic.MEAN, Statistic.VARIANCE);
+        final DoubleStatistics s1 = b.build(x);
+        final double m1 = s1.getAsDouble(Statistic.MEAN);
+        final double v1 = s1.getAsDouble(Statistic.VARIANCE);
+        final DoubleStatistics s2 = b.build(y);
+        final double m2 = s2.getAsDouble(Statistic.MEAN);
+        final double v2 = s2.getAsDouble(Statistic.VARIANCE);
         double t;
         double df;
         if (equalVariances) {
diff --git 
a/commons-statistics-inference/src/test/java/org/apache/commons/statistics/inference/StatisticUtilsTest.java
 
b/commons-statistics-inference/src/test/java/org/apache/commons/statistics/inference/StatisticUtilsTest.java
index ac2e276..d44a6d6 100644
--- 
a/commons-statistics-inference/src/test/java/org/apache/commons/statistics/inference/StatisticUtilsTest.java
+++ 
b/commons-statistics-inference/src/test/java/org/apache/commons/statistics/inference/StatisticUtilsTest.java
@@ -16,9 +16,7 @@
  */
 package org.apache.commons.statistics.inference;
 
-import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.math.MathContext;
 import java.util.Arrays;
 import java.util.function.BiConsumer;
 import java.util.stream.IntStream;
@@ -90,6 +88,10 @@ class StatisticUtilsTest {
         TestUtils.assertThrowsWithMessage(IllegalArgumentException.class,
             () -> action.accept(new double[] {1, 1}, new long[] {1}), 
"values", "size");
 
+        // Observed is zero
+        TestUtils.assertThrowsWithMessage(IllegalArgumentException.class,
+            () -> action.accept(new double[] {1, 1}, new long[] {0, 0}), "no", 
"data");
+
         // Samples not same size, i.e. cannot be paired
         TestUtils.assertThrowsWithMessage(IllegalArgumentException.class,
             () -> action.accept(new double[] {1, 1}, new long[] {1, 2, 3}), 
"values", "size", "mismatch");
@@ -118,9 +120,11 @@ class StatisticUtilsTest {
     @MethodSource
     void testComputeRatio(double[] e, long[] o) {
         final double ratio = StatisticUtils.computeRatio(e, o);
-        final long sum1 = Arrays.stream(o).sum();
+        // Sum as an exact double
+        final double sum1 = Arrays.stream(o).mapToObj(BigInteger::valueOf)
+            .reduce(BigInteger.ZERO, BigInteger::add).doubleValue();
         final double sum2 = Arrays.stream(e).map(x -> x * ratio).sum();
-        TestUtils.assertRelativelyEquals(sum1, sum2, Math.ulp(1.0), "rescaled 
sum(e) != sum(o)");
+        TestUtils.assertRelativelyEquals(sum1, sum2, Math.ulp(sum1), "rescaled 
sum(e) != sum(o)");
     }
 
     static Stream<Arguments> testComputeRatio() {
@@ -148,6 +152,8 @@ class StatisticUtilsTest {
         final UniformRandomProvider rng = 
RandomSource.XO_RO_SHI_RO_128_PP.create(123);
         for (int n = 2; n < 1024; n *= 2) {
             builder.add(Arguments.of(rng.doubles(n).toArray(), rng.longs(n, 0, 
Integer.MAX_VALUE).toArray()));
+            // values that are not integers
+            builder.add(Arguments.of(rng.doubles(n).toArray(), 
rng.longs(n).map(x -> x >>> 1).toArray()));
         }
         return builder.build();
     }
@@ -155,10 +161,9 @@ class StatisticUtilsTest {
     @Test
     void testMeanAndVarianceSize0() {
         final double[] data = {};
-        Assertions.assertEquals(Double.NaN, StatisticUtils.mean(new long[0]), 
"mean(long[])");
-        Assertions.assertEquals(Double.NaN, StatisticUtils.mean(data), "mean");
-        Assertions.assertEquals(Double.NaN, 
StatisticUtils.mean(Arrays.asList(data, data, data)), "mean");
-        Assertions.assertEquals(Double.NaN, StatisticUtils.variance(data, 0), 
"variance");
+        Assertions.assertEquals(Double.NaN, 
StatisticUtils.mean(Arrays.asList()), "mean (empty)");
+        Assertions.assertEquals(Double.NaN, 
StatisticUtils.mean(Arrays.asList(data)), "mean (single array)");
+        Assertions.assertEquals(Double.NaN, 
StatisticUtils.mean(Arrays.asList(data, data, data)), "mean (multi array)");
         Assertions.assertEquals(Double.NaN, 
StatisticUtils.meanDifference(data, data), "meanDifference");
         Assertions.assertEquals(Double.NaN, 
StatisticUtils.varianceDifference(data, data, 0), "varianceDifference");
     }
@@ -176,15 +181,12 @@ class StatisticUtilsTest {
     @ParameterizedTest
     @MethodSource
     void testMeanAndVariance(double[] data, double mean, double variance) {
-        final double m1 = StatisticUtils.mean(data);
-        final double v1 = StatisticUtils.variance(data, m1);
-        Assertions.assertEquals(mean, m1, Math.abs(mean) * 1e-15, "mean");
-        Assertions.assertEquals(variance, v1, variance * 1e-15, "variance");
+        final double deltaMean = Math.abs(mean) * 1e-15;
 
         // For the multiple array mean, split the array
         final double[] x = Arrays.copyOf(data, data.length / 2);
         final double[] y = Arrays.copyOfRange(data, data.length / 2, 
data.length);
-        Assertions.assertEquals(m1, StatisticUtils.mean(Arrays.asList(x, y)), 
"mean(x, y)");
+        Assertions.assertEquals(mean, StatisticUtils.mean(Arrays.asList(x, 
y)), deltaMean, "mean(x, y)");
 
         // For the difference computation construct input so that data = data1 
- data2.
         // This is simple if data1 = data and data2 is all zero but here
@@ -194,13 +196,8 @@ class StatisticUtilsTest {
         final double[] data2 = IntStream.range(0, data.length).mapToDouble(i 
-> i + c).toArray();
         final double m2 = StatisticUtils.meanDifference(data1, data2);
         final double v2 = StatisticUtils.varianceDifference(data1, data2, m2);
-        // Check absolutely equal to the single array method,
-        // i.e. the computations should be the same as generating data = data1 
- data2
-        // and calling the single array methods.
-        // This works if the input values and the offset are exactly 
representable
-        // (no rounding) which is true as the values are integers.
-        Assertions.assertEquals(m1, m2, "meanDifference");
-        Assertions.assertEquals(v1, v2, "varianceDifference");
+        Assertions.assertEquals(mean, m2, deltaMean, "meanDifference");
+        Assertions.assertEquals(variance, v2, variance * 1e-15, 
"varianceDifference");
     }
 
     static Stream<Arguments> testMeanAndVariance() {
@@ -213,38 +210,4 @@ class StatisticUtilsTest {
             Arguments.of(new double[] {-23467824, 23648, 2368, 23749, -23424, 
-23492, -92397747}, -16551817.42857143, 1195057670342971.2)
         );
     }
-
-    @ParameterizedTest
-    @MethodSource
-    void testMeanLong(long[] data) {
-        final double m1 = StatisticUtils.mean(data);
-        final BigInteger sum = Arrays.stream(data)
-                                     .mapToObj(BigInteger::valueOf)
-                                     .reduce(BigInteger.ZERO, BigInteger::add);
-        final double expected = new BigDecimal(sum)
-                .divide(BigDecimal.valueOf(data.length), 
MathContext.DECIMAL128).doubleValue();
-        Assertions.assertEquals(expected, m1);
-    }
-
-    static Stream<Arguments> testMeanLong() {
-        final Stream.Builder<Arguments> builder = Stream.builder();
-        builder.add(Arguments.of(new long[1]));
-        builder.add(Arguments.of(new long[] {42}));
-        final UniformRandomProvider rng = 
RandomSource.XO_RO_SHI_RO_128_PP.create();
-        // int values
-        builder.add(Arguments.of(rng.ints(5).asLongStream().toArray()));
-        builder.add(Arguments.of(rng.ints(25).asLongStream().toArray()));
-        builder.add(Arguments.of(rng.ints(50).asLongStream().toArray()));
-
-        // Note: This data is failed by 
Arrays.stream(data).average().getAsDouble();
-        // long values without cancellation (all positive)
-        builder.add(Arguments.of(rng.longs(5).map(x -> x >>> 1).toArray()));
-        builder.add(Arguments.of(rng.longs(50).map(x -> x >>> 1).toArray()));
-        builder.add(Arguments.of(rng.longs(500).map(x -> x >>> 1).toArray()));
-        // long values with cancellation
-        builder.add(Arguments.of(rng.longs(5).toArray()));
-        builder.add(Arguments.of(rng.longs(50).toArray()));
-        builder.add(Arguments.of(rng.longs(500).toArray()));
-        return builder.build();
-    }
 }
diff --git 
a/commons-statistics-inference/src/test/java/org/apache/commons/statistics/inference/TTestTest.java
 
b/commons-statistics-inference/src/test/java/org/apache/commons/statistics/inference/TTestTest.java
index c5961a0..07f050b 100644
--- 
a/commons-statistics-inference/src/test/java/org/apache/commons/statistics/inference/TTestTest.java
+++ 
b/commons-statistics-inference/src/test/java/org/apache/commons/statistics/inference/TTestTest.java
@@ -16,9 +16,12 @@
  */
 package org.apache.commons.statistics.inference;
 
+import java.util.EnumSet;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.stream.Stream;
+import org.apache.commons.statistics.descriptive.DoubleStatistics;
+import org.apache.commons.statistics.descriptive.Statistic;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
@@ -95,8 +98,10 @@ class TTestTest {
             final Object[] args = a.get();
             final double[] sample = (double[]) args[1];
             final Object[] args2 = new Object[args.length + 2];
-            final double m = StatisticUtils.mean(sample);
-            final double v = StatisticUtils.variance(sample, m);
+            final DoubleStatistics s = DoubleStatistics.of(
+                EnumSet.of(Statistic.MEAN, Statistic.VARIANCE), sample);
+            final double m = s.getAsDouble(Statistic.MEAN);
+            final double v = s.getAsDouble(Statistic.VARIANCE);
             args2[0] = args[0];
             args2[1] = m;
             args2[2] = v;
@@ -308,18 +313,19 @@ class TTestTest {
         // This provides data with an expected mean (mu) for the two sample 
dataset method.
         return testTwoSample().map(a -> {
             final Object[] args = a.get();
-            final double[] s1 = (double[]) args[1];
-            final double[] s2 = (double[]) args[2];
+            final double[] x = (double[]) args[1];
+            final double[] y = (double[]) args[2];
             final Object[] args2 = new Object[args.length + 4];
-            final double m1 = StatisticUtils.mean(s1);
-            final double m2 = StatisticUtils.mean(s2);
+            final DoubleStatistics.Builder b = 
DoubleStatistics.builder(Statistic.MEAN, Statistic.VARIANCE);
+            final DoubleStatistics s1 = b.build(x);
+            final DoubleStatistics s2 = b.build(y);
             args2[0] = args[0];
-            args2[1] = m1;
-            args2[2] = StatisticUtils.variance(s1, m1);
-            args2[3] = s1.length;
-            args2[4] = m2;
-            args2[5] = StatisticUtils.variance(s2, m2);
-            args2[6] = s2.length;
+            args2[1] = s1.getAsDouble(Statistic.MEAN);
+            args2[2] = s1.getAsDouble(Statistic.VARIANCE);
+            args2[3] = x.length;
+            args2[4] = s2.getAsDouble(Statistic.MEAN);
+            args2[5] = s2.getAsDouble(Statistic.VARIANCE);
+            args2[6] = y.length;
             System.arraycopy(args, 3, args2, 7, args.length - 3);
             return Arguments.of(args2);
         });

Reply via email to