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 c32aa226e55812280afb1fc82b3e996dd458220d Author: Alex Herbert <aherb...@apache.org> AuthorDate: Sat Nov 19 08:43:40 2022 +0000 Use parameterized tests --- .../statistics/distribution/FDistributionTest.java | 196 ++++++++++++--------- .../distribution/GammaDistributionTest.java | 25 +-- .../distribution/GeometricDistributionTest.java | 32 ++-- .../HypergeometricDistributionTest.java | 40 +++-- .../distribution/ParetoDistributionTest.java | 26 ++- .../distribution/PascalDistributionTest.java | 28 +-- .../statistics/distribution/TDistributionTest.java | 35 ++-- .../distribution/TrapezoidalDistributionTest.java | 6 +- .../distribution/TriangularDistributionTest.java | 36 ++-- .../TruncatedNormalDistributionTest.java | 4 +- .../UniformContinuousDistributionTest.java | 30 ++-- .../UniformDiscreteDistributionTest.java | 25 +-- .../distribution/WeibullDistributionTest.java | 55 +++--- 13 files changed, 293 insertions(+), 245 deletions(-) diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/FDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/FDistributionTest.java index a0371e9..43fcb13 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/FDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/FDistributionTest.java @@ -16,8 +16,12 @@ */ package org.apache.commons.statistics.distribution; +import java.util.stream.Stream; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; /** * Test cases for {@link FDistribution}. @@ -53,21 +57,22 @@ class FDistributionTest extends BaseContinuousDistributionTest { //-------------------- Additional test cases ------------------------------- - @Test - void testAdditionalMoments() { - FDistribution dist; - - dist = FDistribution.of(1, 2); - Assertions.assertEquals(Double.NaN, dist.getMean()); - Assertions.assertEquals(Double.NaN, dist.getVariance()); - - dist = FDistribution.of(1, 3); - Assertions.assertEquals(3d / (3d - 2d), dist.getMean()); - Assertions.assertEquals(Double.NaN, dist.getVariance()); + @ParameterizedTest + @MethodSource + void testAdditionalMoments(double numeratorDegreesOfFreedom, + double denominatorDegreesOfFreedom, + double mean, + double variance) { + final FDistribution dist = FDistribution.of(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom); + testMoments(dist, mean, variance, DoubleTolerances.equals()); + } - dist = FDistribution.of(1, 5); - Assertions.assertEquals(5d / (5d - 2d), dist.getMean()); - Assertions.assertEquals((2d * 5d * 5d * 4d) / 9d, dist.getVariance()); + static Stream<Arguments> testAdditionalMoments() { + return Stream.of( + Arguments.of(1, 2, Double.NaN, Double.NaN), + Arguments.of(1, 3, 3.0 / (3 - 2), Double.NaN), + Arguments.of(1, 5, 5.0 / (5 - 2), (2 * 5 * 5 * 4) / 9.0) + ); } @Test @@ -102,82 +107,105 @@ class FDistributionTest extends BaseContinuousDistributionTest { Assertions.assertTrue(result < 1.0, "Failing to calculate inverse cumulative probability"); } - @Test - void testAdditionalLogDensity() { + @ParameterizedTest + @MethodSource + void testAdditionalLogDensity(double numeratorDegreesOfFreedom, + double denominatorDegreesOfFreedom, + double[] points, + double[] values) { + testLogDensity(FDistribution.of(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom), + points, values, DoubleTolerances.relative(1e-15)); + } + + static Stream<Arguments> testAdditionalLogDensity() { // Computed using Boost multiprecision to 100 digits (output 25 digits). // Edge cases when the standard density is sub-normal or zero. final double[] x = new double[] {1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9}; - testLogDensity(FDistribution.of(100, 100), x, - new double[] {-56.96014024624318913110565, - -165.8559950938238412964495, - -282.3927517845117162132265, - -399.7346409939330236149964, - -517.157481231596055999464, - -634.5884209792423525846316, - -752.0201707219881824362492, - -869.4520014646850073211334, - -986.883840307381342156051}, - DoubleTolerances.relative(1e-15)); - - testLogDensity(FDistribution.of(952, 912), x, - new double[] {-509.5128641158461391223255, - -1485.417858108384337659572, - -2529.705750311339816652123, - -3581.184004620825529681231, - -4633.385040722443349533971, - -5685.658392700035382988623, - -6737.938976642435125691553, - -7790.220283785087985050541, - -8842.501663247803879775318}, - DoubleTolerances.relative(1e-15)); - - // This causes intermediate overflow of the density function - testLogDensity(FDistribution.of(1e-100, 1), - new double[] {1e-200, 1e-250, 1e-300}, - new double[] {229.5653621188446231302736, - 344.6946167685469072592738, - 459.8238714182491914891139}, - DoubleTolerances.relative(1e-15)); + return Stream.of( + Arguments.of(100, 100, x, + new double[] { + -56.96014024624318913110565, + -165.8559950938238412964495, + -282.3927517845117162132265, + -399.7346409939330236149964, + -517.157481231596055999464, + -634.5884209792423525846316, + -752.0201707219881824362492, + -869.4520014646850073211334, + -986.883840307381342156051}), + Arguments.of(952, 912, x, + new double[] { + -509.5128641158461391223255, + -1485.417858108384337659572, + -2529.705750311339816652123, + -3581.184004620825529681231, + -4633.385040722443349533971, + -5685.658392700035382988623, + -6737.938976642435125691553, + -7790.220283785087985050541, + -8842.501663247803879775318}), + // This causes intermediate overflow of the density function + Arguments.of(1e-100, 1, + new double[] {1e-200, 1e-250, 1e-300}, + new double[] { + 229.5653621188446231302736, + 344.6946167685469072592738, + 459.8238714182491914891139}) + ); } - @Test - void testAdditionalDensity() { + @ParameterizedTest + @MethodSource + void testAdditionalDensity(double numeratorDegreesOfFreedom, + double denominatorDegreesOfFreedom, + double[] points, + double[] values, + double relativeError) { + testDensity(FDistribution.of(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom), + points, values, DoubleTolerances.relative(relativeError)); + } + + static Stream<Arguments> testAdditionalDensity() { + // Computed using Boost multiprecision to 100 digits (output 25 digits). + // Edge cases when the standard density is sub-normal. - testDensity(FDistribution.of(100, 100), - new double[] {1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 3e6, 4e6, 4.5e6, 5e6, 1e7}, - new double[] {1.830313161302986740491046e-25, - 9.325165326363852979476269e-73, - 2.282370632180103030176872e-123, - 2.49718772086196154389661e-174, - 2.51976260334572601372639e-225, - 2.522031398014840106819471e-276, - 1.171103964711921105069224e-300, - 4.97420298008526384736197e-307, - 1.224464123468993962344698e-309, - 5.679564178845752345371413e-312, - 0}, - DoubleTolerances.relative(3e-13)); - - testDensity(FDistribution.of(952, 912), - new double[] {10, 11, 12, 13, 14, 15, 16, 17, 18}, - new double[] {5.264712450643104177155291e-222, - 1.083049754753448067375765e-237, - 2.996024821196787172008532e-252, - 7.919262482129153149257417e-266, - 1.511696585130734458293958e-278, - 1.652611434344889324846565e-290, - 8.522337060963566999523664e-302, - 1.760000675560273604454495e-312, - 1.266172656954210816606837e-322}, - DoubleTolerances.relative(2e-13)); - - // This causes intermediate overflow of the density function - testDensity(FDistribution.of(1e-100, 1), - new double[] {1e-200, 1e-250, 1e-300}, - new double[] {5.000000000000000189458187e+99, - 4.999999999999999829961813e+149, - 4.99999999999999997466404e+199}, - DoubleTolerances.relative(5e-14)); + return Stream.of( + Arguments.of(100, 100, + new double[] {1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 3e6, 4e6, 4.5e6, 5e6, 1e7}, + new double[] { + 1.830313161302986740491046e-25, + 9.325165326363852979476269e-73, + 2.282370632180103030176872e-123, + 2.49718772086196154389661e-174, + 2.51976260334572601372639e-225, + 2.522031398014840106819471e-276, + 1.171103964711921105069224e-300, + 4.97420298008526384736197e-307, + 1.224464123468993962344698e-309, + 5.679564178845752345371413e-312, + 0 + }, 3e-13), + Arguments.of(952, 912, + new double[] {10, 11, 12, 13, 14, 15, 16, 17, 18}, + new double[] {5.264712450643104177155291e-222, + 1.083049754753448067375765e-237, + 2.996024821196787172008532e-252, + 7.919262482129153149257417e-266, + 1.511696585130734458293958e-278, + 1.652611434344889324846565e-290, + 8.522337060963566999523664e-302, + 1.760000675560273604454495e-312, + 1.266172656954210816606837e-322 + }, 2e-13), + // This causes intermediate overflow of the density function + Arguments.of(1e-100, 1, + new double[] {1e-200, 1e-250, 1e-300}, + new double[] { + 5.000000000000000189458187e+99, + 4.999999999999999829961813e+149, + 4.99999999999999997466404e+199 + }, 5e-14) + ); } } diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GammaDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GammaDistributionTest.java index 6b56fec..7c5ae4b 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GammaDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GammaDistributionTest.java @@ -21,10 +21,14 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.stream.Stream; import org.apache.commons.math3.stat.descriptive.SummaryStatistics; import org.apache.commons.numbers.gamma.LanczosApproximation; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; /** * Test cases for {@link GammaDistribution}. @@ -62,17 +66,18 @@ class GammaDistributionTest extends BaseContinuousDistributionTest { //-------------------- Additional test cases ------------------------------- - @Test - void testAdditionalMoments() { - GammaDistribution dist; - - dist = GammaDistribution.of(1, 2); - Assertions.assertEquals(2, dist.getMean()); - Assertions.assertEquals(4, dist.getVariance()); + @ParameterizedTest + @MethodSource + void testAdditionalMoments(double shape, double scale, double mean, double variance) { + final GammaDistribution dist = GammaDistribution.of(shape, scale); + testMoments(dist, mean, variance, DoubleTolerances.equals()); + } - dist = GammaDistribution.of(1.1, 4.2); - Assertions.assertEquals(1.1 * 4.2, dist.getMean()); - Assertions.assertEquals(1.1 * 4.2 * 4.2, dist.getVariance()); + static Stream<Arguments> testAdditionalMoments() { + return Stream.of( + Arguments.of(1, 2, 2, 4), + Arguments.of(1.1, 4.2, 1.1 * 4.2, 1.1 * 4.2 * 4.2) + ); } @Test diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java index 7931147..1c47922 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java @@ -17,9 +17,12 @@ package org.apache.commons.statistics.distribution; import java.util.Arrays; +import java.util.stream.Stream; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; /** @@ -49,6 +52,20 @@ class GeometricDistributionTest extends BaseDiscreteDistributionTest { //-------------------- Additional test cases ------------------------------- + @ParameterizedTest + @MethodSource + void testAdditionalMoments(double p, double mean, double variance) { + final GeometricDistribution dist = GeometricDistribution.of(p); + testMoments(dist, mean, variance, DoubleTolerances.ulps(1)); + } + + static Stream<Arguments> testAdditionalMoments() { + return Stream.of( + Arguments.of(0.5, (1.0 - 0.5) / 0.5, (1.0 - 0.5) / (0.5 * 0.5)), + Arguments.of(0.3, (1.0 - 0.3) / 0.3, (1.0 - 0.3) / (0.3 * 0.3)) + ); + } + /** * Test the PMF is computed using the power function when p is above 0.5. * <p>Note: The geometric distribution PMF is defined as: @@ -129,21 +146,6 @@ class GeometricDistributionTest extends BaseDiscreteDistributionTest { testSurvivalProbabilityInverseMapping(dist, x); } - @Test - void testAdditionalMoments() { - GeometricDistribution dist; - - final DoubleTolerance tol = DoubleTolerances.ulps(1); - - dist = GeometricDistribution.of(0.5); - TestUtils.assertEquals((1.0d - 0.5d) / 0.5d, dist.getMean(), tol); - TestUtils.assertEquals((1.0d - 0.5d) / (0.5d * 0.5d), dist.getVariance(), tol); - - dist = GeometricDistribution.of(0.3); - TestUtils.assertEquals((1.0d - 0.3d) / 0.3d, dist.getMean(), tol); - TestUtils.assertEquals((1.0d - 0.3d) / (0.3d * 0.3d), dist.getVariance(), tol); - } - /** * Test the most extreme parameters. Uses a small enough value of p that the distribution is * truncated by the maximum integer value. This creates a case where (x+1) will overflow. diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/HypergeometricDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/HypergeometricDistributionTest.java index d4ab2d1..34ecdb6 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/HypergeometricDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/HypergeometricDistributionTest.java @@ -17,10 +17,14 @@ package org.apache.commons.statistics.distribution; +import java.util.stream.Stream; import org.apache.commons.numbers.core.Precision; import org.apache.commons.rng.simple.RandomSource; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; /** * Test cases for {@link HypergeometricDistribution}. @@ -54,23 +58,21 @@ class HypergeometricDistributionTest extends BaseDiscreteDistributionTest { //-------------------- Additional test cases ------------------------------- - @Test - void testAdditionalMoments() { - HypergeometricDistribution dist; - - final DoubleTolerance tol = DoubleTolerances.ulps(1); - - dist = HypergeometricDistribution.of(1500, 40, 100); - TestUtils.assertEquals(40d * 100d / 1500d, - dist.getMean(), tol); - TestUtils.assertEquals((100d * 40d * (1500d - 100d) * (1500d - 40d)) / ((1500d * 1500d * 1499d)), - dist.getVariance(), tol); - - dist = HypergeometricDistribution.of(3000, 55, 200); - TestUtils.assertEquals(55d * 200d / 3000d, - dist.getMean(), tol); - TestUtils.assertEquals((200d * 55d * (3000d - 200d) * (3000d - 55d)) / ((3000d * 3000d * 2999d)), - dist.getVariance(), tol); + @ParameterizedTest + @MethodSource + void testAdditionalMoments(int populationSize, + int numberOfSuccesses, + int sampleSize, + double mean, double variance) { + final HypergeometricDistribution dist = HypergeometricDistribution.of(populationSize, numberOfSuccesses, sampleSize); + testMoments(dist, mean, variance, DoubleTolerances.ulps(1)); + } + + static Stream<Arguments> testAdditionalMoments() { + return Stream.of( + Arguments.of(1500, 40, 100, 40d * 100d / 1500d, (100d * 40d * (1500d - 100d) * (1500d - 40d)) / ((1500d * 1500d * 1499d))), + Arguments.of(3000, 55, 200, 55d * 200d / 3000d, (200d * 55d * (3000d - 200d) * (3000d - 55d)) / ((3000d * 3000d * 2999d))) + ); } @Test @@ -107,8 +109,8 @@ class HypergeometricDistributionTest extends BaseDiscreteDistributionTest { } private static void testHypergeometricDistributionProbabilities(int populationSize, int sampleSize, - int numberOfSucceses, double[][] data) { - final HypergeometricDistribution dist = HypergeometricDistribution.of(populationSize, numberOfSucceses, sampleSize); + int numberOfSuccesses, double[][] data) { + final HypergeometricDistribution dist = HypergeometricDistribution.of(populationSize, numberOfSuccesses, sampleSize); for (int i = 0; i < data.length; ++i) { final int x = (int)data[i][0]; final double pmf = data[i][1]; diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java index d3539ab..38450cf 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java @@ -19,6 +19,8 @@ package org.apache.commons.statistics.distribution; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; /** * Test cases for {@link ParetoDistribution}. @@ -56,6 +58,16 @@ class ParetoDistributionTest extends BaseContinuousDistributionTest { //-------------------- Additional test cases ------------------------------- + @ParameterizedTest + @CsvSource({ + "1, 1, Infinity, Infinity", + "2.2, 2.4, 3.771428571428, 14.816326530", + }) + void testAdditionalMoments(double scale, double shape, double mean, double variance) { + final ParetoDistribution dist = ParetoDistribution.of(scale, shape); + testMoments(dist, mean, variance, DoubleTolerances.relative(1e-9)); + } + @Test void testHighPrecision() { final ParetoDistribution dist = ParetoDistribution.of(2.1, 1.4); @@ -91,20 +103,6 @@ class ParetoDistributionTest extends BaseContinuousDistributionTest { testCumulativeProbabilityHighPrecision(dist2, x, values2, DoubleTolerances.absolute(8e-17)); } - @Test - void testAdditionalMoments() { - final double tol = 1e-9; - ParetoDistribution dist; - - dist = ParetoDistribution.of(1, 1); - Assertions.assertEquals(Double.POSITIVE_INFINITY, dist.getMean(), tol); - Assertions.assertEquals(Double.POSITIVE_INFINITY, dist.getVariance(), tol); - - dist = ParetoDistribution.of(2.2, 2.4); - Assertions.assertEquals(3.771428571428, dist.getMean(), tol); - Assertions.assertEquals(14.816326530, dist.getVariance(), tol); - } - /** * Check to make sure top-coding of extreme values works correctly. */ diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java index b428f29..e2847e4 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java @@ -16,7 +16,10 @@ */ package org.apache.commons.statistics.distribution; -import org.junit.jupiter.api.Test; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; /** * Test cases for {@link PascalDistribution}. @@ -49,18 +52,17 @@ class PascalDistributionTest extends BaseDiscreteDistributionTest { //-------------------- Additional test cases ------------------------------- - @Test - void testAdditionalMoments() { - PascalDistribution dist; - - DoubleTolerance tol = DoubleTolerances.ulps(1); - - dist = PascalDistribution.of(10, 0.5); - TestUtils.assertEquals((10d * 0.5d) / 0.5, dist.getMean(), tol); - TestUtils.assertEquals((10d * 0.5d) / (0.5d * 0.5d), dist.getVariance(), tol); + @ParameterizedTest + @MethodSource + void testAdditionalMoments(int r, double p, double mean, double variance) { + final PascalDistribution dist = PascalDistribution.of(r, p); + testMoments(dist, mean, variance, DoubleTolerances.ulps(1)); + } - dist = PascalDistribution.of(25, 0.7); - TestUtils.assertEquals((25d * 0.3d) / 0.7, dist.getMean(), tol); - TestUtils.assertEquals((25d * 0.3d) / (0.7d * 0.7d), dist.getVariance(), tol); + static Stream<Arguments> testAdditionalMoments() { + return Stream.of( + Arguments.of(10, 0.5, (10d * 0.5d) / 0.5, (10d * 0.5d) / (0.5d * 0.5d)), + Arguments.of(25, 0.7, (25d * 0.3d) / 0.7, (25d * 0.3d) / (0.7d * 0.7d)) + ); } } diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java index c862342..c67bc49 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java @@ -16,10 +16,13 @@ */ package org.apache.commons.statistics.distribution; +import java.util.stream.Stream; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; /** * Test cases for {@link TDistribution}. @@ -52,6 +55,21 @@ class TDistributionTest extends BaseContinuousDistributionTest { //-------------------- Additional test cases ------------------------------- + @ParameterizedTest + @MethodSource + void testAdditionalMoments(double df, double mean, double variance) { + final TDistribution dist = TDistribution.of(df); + testMoments(dist, mean, variance, DoubleTolerances.equals()); + } + + static Stream<Arguments> testAdditionalMoments() { + return Stream.of( + Arguments.of(1.5, 0, Double.POSITIVE_INFINITY), + Arguments.of(2.1, 0, 2.1 / (2.1 - 2.0)), + Arguments.of(12.1, 0, 12.1 / (12.1 - 2.0)) + ); + } + /** * @see <a href="https://issues.apache.orgg/bugzilla/show_bug.cgi?id=27243"> * Bug report that prompted this unit test.</a> @@ -65,23 +83,6 @@ class TDistributionTest extends BaseContinuousDistributionTest { }); } - @Test - void testAdditionalMoments() { - TDistribution dist; - - dist = TDistribution.of(1.5); - Assertions.assertEquals(0, dist.getMean()); - Assertions.assertEquals(Double.POSITIVE_INFINITY, dist.getVariance()); - - dist = TDistribution.of(2.1); - Assertions.assertEquals(0, dist.getMean()); - Assertions.assertEquals(2.1 / (2.1 - 2.0), dist.getVariance()); - - dist = TDistribution.of(12.1); - Assertions.assertEquals(0, dist.getMean()); - Assertions.assertEquals(12.1 / (12.1 - 2.0), dist.getVariance()); - } - /* * Adding this test to benchmark against tables published by NIST * http://itl.nist.gov/div898/handbook/eda/section3/eda3672.htm diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TrapezoidalDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TrapezoidalDistributionTest.java index 5578cf4..2670124 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TrapezoidalDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TrapezoidalDistributionTest.java @@ -75,11 +75,9 @@ class TrapezoidalDistributionTest extends BaseContinuousDistributionTest { @ParameterizedTest @MethodSource - void testAdditionalMoments(double a, double b, double c, double d, double mean, double var) { + void testAdditionalMoments(double a, double b, double c, double d, double mean, double variance) { final TrapezoidalDistribution dist = TrapezoidalDistribution.of(a, b, c, d); - final DoubleTolerance tol = DoubleTolerances.ulps(8); - TestUtils.assertEquals(mean, dist.getMean(), tol); - TestUtils.assertEquals(var, dist.getVariance(), tol); + testMoments(dist, mean, variance, DoubleTolerances.ulps(8)); } static Stream<Arguments> testAdditionalMoments() { diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java index 8dd4b44..80d2393 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java @@ -17,10 +17,12 @@ package org.apache.commons.statistics.distribution; +import java.util.stream.Stream; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; /** * Test cases for {@link TriangularDistribution}. @@ -58,6 +60,21 @@ class TriangularDistributionTest extends BaseContinuousDistributionTest { //-------------------- Additional test cases ------------------------------- + @ParameterizedTest + @MethodSource + void testAdditionalMoments(double a, double b, double c, double mean, double variance) { + final TriangularDistribution dist = TriangularDistribution.of(a, b, c); + testMoments(dist, mean, variance, DoubleTolerances.equals()); + } + + static Stream<Arguments> testAdditionalMoments() { + return Stream.of( + Arguments.of(0, 0.5, 1.0, 0.5, 1 / 24.0), + Arguments.of(0, 1, 1, 2 / 3.0, 1 / 18.0), + Arguments.of(-3, 2, 12, 3 + (2 / 3.0), 175 / 18.0) + ); + } + @ParameterizedTest @CsvSource({ "1, 2, 3", @@ -69,21 +86,4 @@ class TriangularDistributionTest extends BaseContinuousDistributionTest { Assertions.assertEquals(mode, dist.getMode()); Assertions.assertEquals(upper, dist.getSupportUpperBound()); } - - @Test - void testAdditionalMoments() { - TriangularDistribution dist; - - dist = TriangularDistribution.of(0, 0.5, 1.0); - Assertions.assertEquals(0.5, dist.getMean()); - Assertions.assertEquals(1 / 24.0, dist.getVariance()); - - dist = TriangularDistribution.of(0, 1, 1); - Assertions.assertEquals(2 / 3.0, dist.getMean()); - Assertions.assertEquals(1 / 18.0, dist.getVariance()); - - dist = TriangularDistribution.of(-3, 2, 12); - Assertions.assertEquals(3 + (2 / 3.0), dist.getMean()); - Assertions.assertEquals(175 / 18.0, dist.getVariance()); - } } diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TruncatedNormalDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TruncatedNormalDistributionTest.java index 2d8290e..0dbf539 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TruncatedNormalDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TruncatedNormalDistributionTest.java @@ -57,6 +57,8 @@ class TruncatedNormalDistributionTest extends BaseContinuousDistributionTest { return new String[] {null, null, "SupportLowerBound", "SupportUpperBound"}; } + //-------------------- Additional test cases ------------------------------- + /** * Hit the edge cases where the lower and upper bound are not infinite but the * CDF of the parent distribution is either 0 or 1. This is effectively no truncation. @@ -73,7 +75,7 @@ class TruncatedNormalDistributionTest extends BaseContinuousDistributionTest { "1.0, 2.0, -4, 6", "3.45, 6.78, -8, 10", }) - void testEffectivelyNoTruncation(double mean, double sd, double lower, double upper) { + void testMomentsEffectivelyNoTruncation(double mean, double sd, double lower, double upper) { double inf = Double.POSITIVE_INFINITY; double max = Double.MAX_VALUE; TruncatedNormalDistribution dist1; diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java index c56fde0..287d283 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java @@ -17,6 +17,7 @@ package org.apache.commons.statistics.distribution; +import java.util.stream.Stream; import org.apache.commons.rng.UniformRandomProvider; import org.apache.commons.rng.sampling.distribution.ContinuousSampler; import org.apache.commons.rng.sampling.distribution.ContinuousUniformSampler; @@ -24,7 +25,9 @@ import org.apache.commons.rng.simple.RandomSource; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; /** * Test cases for {@link UniformContinuousDistribution}. @@ -62,22 +65,19 @@ class UniformContinuousDistributionTest extends BaseContinuousDistributionTest { //-------------------- Additional test cases ------------------------------- - @Test - void testAdditionalMoments() { - UniformContinuousDistribution dist; - - dist = UniformContinuousDistribution.of(0, 1); - Assertions.assertEquals(0.5, dist.getMean()); - Assertions.assertEquals(1 / 12.0, dist.getVariance()); - - dist = UniformContinuousDistribution.of(-1.5, 0.6); - Assertions.assertEquals(-0.45, dist.getMean()); - Assertions.assertEquals(0.3675, dist.getVariance()); + @ParameterizedTest + @MethodSource + void testAdditionalMoments(double lower, double upper, double mean, double variance) { + final UniformContinuousDistribution dist = UniformContinuousDistribution.of(lower, upper); + testMoments(dist, mean, variance, DoubleTolerances.equals()); + } - // Overflow of 0.5 * (lower + upper) - dist = UniformContinuousDistribution.of(Double.MAX_VALUE / 2, Double.MAX_VALUE); - Assertions.assertEquals(Double.MAX_VALUE - Double.MAX_VALUE / 4, dist.getMean()); - Assertions.assertEquals(Double.POSITIVE_INFINITY, dist.getVariance()); + static Stream<Arguments> testAdditionalMoments() { + return Stream.of( + Arguments.of(0, 1, 0.5, 1 / 12.0), + Arguments.of(-1.5, 0.6, -0.45, 0.3675), + Arguments.of(Double.MAX_VALUE / 2, Double.MAX_VALUE, Double.MAX_VALUE - Double.MAX_VALUE / 4, Double.POSITIVE_INFINITY) + ); } /** diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java index c8f6912..33d5ecb 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java @@ -17,11 +17,14 @@ package org.apache.commons.statistics.distribution; +import java.util.stream.Stream; import org.apache.commons.math3.util.MathArrays; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; /** * Test cases for {@link UniformDiscreteDistribution}. @@ -52,18 +55,18 @@ class UniformDiscreteDistributionTest extends BaseDiscreteDistributionTest { //-------------------- Additional test cases ------------------------------- - /** Test mean/variance. */ - @Test - void testAdditionalMoments() { - UniformDiscreteDistribution dist; - - dist = UniformDiscreteDistribution.of(0, 5); - Assertions.assertEquals(2.5, dist.getMean()); - Assertions.assertEquals(35 / 12.0, dist.getVariance()); + @ParameterizedTest + @MethodSource + void testAdditionalMoments(int lower, int upper, double mean, double variance) { + final UniformDiscreteDistribution dist = UniformDiscreteDistribution.of(lower, upper); + testMoments(dist, mean, variance, DoubleTolerances.equals()); + } - dist = UniformDiscreteDistribution.of(0, 1); - Assertions.assertEquals(0.5, dist.getMean()); - Assertions.assertEquals(3 / 12.0, dist.getVariance()); + static Stream<Arguments> testAdditionalMoments() { + return Stream.of( + Arguments.of(0, 5, 2.5, 35 / 12.0), + Arguments.of(0, 1, 0.5, 3 / 12.0) + ); } // MATH-1396 diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java index 1c10306..cb5ee80 100644 --- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java +++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java @@ -17,11 +17,14 @@ package org.apache.commons.statistics.distribution; +import java.util.stream.Stream; import org.apache.commons.numbers.gamma.LogGamma; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; /** * Test cases for {@link WeibullDistribution}. @@ -53,14 +56,27 @@ class WeibullDistributionTest extends BaseContinuousDistributionTest { //-------------------- Additional test cases ------------------------------- - @Test - void testInverseCumulativeProbabilitySmallPAccuracy() { - final WeibullDistribution dist = WeibullDistribution.of(2, 3); - final double t = dist.inverseCumulativeProbability(1e-17); - // Analytically, answer is solution to 1e-17 = 1-exp(-(x/3)^2) - // x = sqrt(-9*log(1-1e-17)) - // If we're not careful, answer will be 0. Answer below is computed with care in Octave: - Assertions.assertEquals(9.48683298050514e-9, t, 1e-17); + @ParameterizedTest + @MethodSource + void testAdditionalMoments(double shape, double scale, double mean, double variance) { + final WeibullDistribution dist = WeibullDistribution.of(shape, scale); + testMoments(dist, mean, variance, DoubleTolerances.absolute(1e-9)); + } + + static Stream<Arguments> testAdditionalMoments() { + // In R: 3.5*gamma(1+(1/2.5)) (or empirically: mean(rweibull(10000, 2.5, 3.5))) + double mu1 = 3.5 * Math.exp(LogGamma.value(1 + (1 / 2.5))); + double mu2 = 2.222 * Math.exp(LogGamma.value(1 + (1 / 10.4))); + return Stream.of( + Arguments.of(2.5, 3.5, mu1, + (3.5 * 3.5) * + Math.exp(LogGamma.value(1 + (2 / 2.5))) - + (mu1 * mu1)), + Arguments.of(10.4, 2.222, mu2, + (2.222 * 2.222) * + Math.exp(LogGamma.value(1 + (2 / 10.4))) - + (mu2 * mu2)) + ); } @ParameterizedTest @@ -75,21 +91,12 @@ class WeibullDistributionTest extends BaseContinuousDistributionTest { } @Test - void testAdditionalMoments() { - final double tol = 1e-9; - WeibullDistribution dist; - - dist = WeibullDistribution.of(2.5, 3.5); - // In R: 3.5*gamma(1+(1/2.5)) (or empirically: mean(rweibull(10000, 2.5, 3.5))) - Assertions.assertEquals(3.5 * Math.exp(LogGamma.value(1 + (1 / 2.5))), dist.getMean(), tol); - Assertions.assertEquals((3.5 * 3.5) * - Math.exp(LogGamma.value(1 + (2 / 2.5))) - - (dist.getMean() * dist.getMean()), dist.getVariance(), tol); - - dist = WeibullDistribution.of(10.4, 2.222); - Assertions.assertEquals(2.222 * Math.exp(LogGamma.value(1 + (1 / 10.4))), dist.getMean(), tol); - Assertions.assertEquals((2.222 * 2.222) * - Math.exp(LogGamma.value(1 + (2 / 10.4))) - - (dist.getMean() * dist.getMean()), dist.getVariance(), tol); + void testInverseCumulativeProbabilitySmallPAccuracy() { + final WeibullDistribution dist = WeibullDistribution.of(2, 3); + final double t = dist.inverseCumulativeProbability(1e-17); + // Analytically, answer is solution to 1e-17 = 1-exp(-(x/3)^2) + // x = sqrt(-9*log(1-1e-17)) + // If we're not careful, answer will be 0. Answer below is computed with care in Octave: + Assertions.assertEquals(9.48683298050514e-9, t, 1e-17); } }