You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2022/11/22 15:41:06 UTC
[commons-statistics] 01/04: Extra moments test cases for trapezoidal distribution
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 2759762745f49715a09cdaacc7f2e981f443e01a
Author: aherbert <ah...@apache.org>
AuthorDate: Tue Nov 22 10:34:36 2022 +0000
Extra moments test cases for trapezoidal distribution
---
.../distribution/TrapezoidalDistributionTest.java | 62 ++++++++++++++++------
1 file changed, 46 insertions(+), 16 deletions(-)
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 b14a605..0d0915c 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,33 +75,63 @@ class TrapezoidalDistributionTest extends BaseContinuousDistributionTest {
@ParameterizedTest
@MethodSource
- void testAdditionalMoments(double a, double b, double c, double d, double mean, double variance) {
+ void testAdditionalMoments(double a, double b, double c, double d, double mean, double variance, int ulps) {
final TrapezoidalDistribution dist = TrapezoidalDistribution.of(a, b, c, d);
- testMoments(dist, mean, variance, DoubleTolerances.ulps(8));
+ testMoments(dist, mean, variance, DoubleTolerances.ulps(ulps));
}
static Stream<Arguments> testAdditionalMoments() {
return Stream.of(
// Computed using scipy.stats.trapezoid
// Up slope, then flat
- Arguments.of(0, 0.1, 1, 1, 0.5245614035087719, 0.07562480763311791),
- Arguments.of(0, 1e-3, 1, 1, 0.5002499583124894, 0.08325006249999839),
- Arguments.of(0, 1e-6, 1, 1, 0.5000002499999582, 0.08333325000006259),
- Arguments.of(0, 1e-9, 1, 1, 0.50000000025, 0.08333333324999997),
- Arguments.of(0, 1e-12, 1, 1, 0.50000000000025, 0.08333333333324999),
- Arguments.of(0, 1e-15, 1, 1, 0.5000000000000003, 0.0833333333333332),
- Arguments.of(0, 0, 1, 1, 0.5, 0.08333333333333331),
+ Arguments.of(0, 0.1, 1, 1, 0.5245614035087719, 0.07562480763311791, 8),
+ Arguments.of(0, 1e-3, 1, 1, 0.5002499583124894, 0.08325006249999839, 8),
+ Arguments.of(0, 1e-6, 1, 1, 0.5000002499999582, 0.08333325000006259, 8),
+ Arguments.of(0, 1e-9, 1, 1, 0.50000000025, 0.08333333324999997, 4),
+ Arguments.of(0, 1e-12, 1, 1, 0.50000000000025, 0.08333333333324999, 4),
+ Arguments.of(0, 1e-15, 1, 1, 0.5000000000000003, 0.0833333333333332, 4),
+ Arguments.of(0, 0, 1, 1, 0.5, 0.08333333333333331, 1),
// Flat, then down slope
- Arguments.of(0, 0, 0.9, 1, 0.47543859649122816, 0.07562480763311777),
- Arguments.of(0, 0, 0.999, 1, 0.49975004168751025, 0.08325006249999842),
- Arguments.of(0, 0, 0.999999, 1, 0.4999997500000417, 0.08333325000006248),
- Arguments.of(0, 0, 0.999999999, 1, 0.49999999975000003, 0.08333333325000003),
- Arguments.of(0, 0, 0.999999999999, 1, 0.49999999999975003, 0.08333333333324999),
- Arguments.of(0, 0, 0.999999999999999, 1, 0.4999999999999998, 0.08333333333333326),
- Arguments.of(0, 0, 1, 1, 0.5, 0.08333333333333331)
+ Arguments.of(0, 0, 0.9, 1, 0.47543859649122816, 0.07562480763311777, 4),
+ Arguments.of(0, 0, 0.999, 1, 0.49975004168751025, 0.08325006249999842, 4),
+ Arguments.of(0, 0, 0.999999, 1, 0.4999997500000417, 0.08333325000006248, 2),
+ Arguments.of(0, 0, 0.999999999, 1, 0.49999999975000003, 0.08333333325000003, 1),
+ Arguments.of(0, 0, 0.999999999999, 1, 0.49999999999975003, 0.08333333333324999, 1),
+ Arguments.of(0, 0, 0.999999999999999, 1, 0.4999999999999998, 0.08333333333333326, 1),
+ Arguments.of(0, 0, 1, 1, 0.5, 0.08333333333333331, 1),
+ // Computed
+ moments(-3, 1, 4, 12, 10),
+ moments(1, 2, 3, 4, 4),
+ moments(11, 15, 22, 30, 4),
+ moments(0, 1, 9, 10, 4),
+ moments(-12, -10, -2, -1, 8)
);
}
+ /**
+ * Compute the mean and variance and return the arguments: [a, b, c, d, mean, variance, ulps].
+ * The ulps are the expected units of least precision error for the test. This is typically
+ * limited by the variance as it depends on accuracy of the mean squared.
+ */
+ private static Arguments moments(double a, double b, double c, double d, int ulps) {
+ final BigDecimal aa = new BigDecimal(a);
+ final BigDecimal bb = new BigDecimal(b);
+ final BigDecimal cc = new BigDecimal(c);
+ final BigDecimal dd = new BigDecimal(d);
+ final MathContext mc = MathContext.DECIMAL128;
+ // Mean
+ BigDecimal divisor = dd.add(cc).subtract(aa).subtract(bb).multiply(BigDecimal.valueOf(3));
+ BigDecimal dc = dd.pow(3).subtract(cc.pow(3)).divide(dd.subtract(cc), mc);
+ BigDecimal ba = bb.pow(3).subtract(aa.pow(3)).divide(bb.subtract(aa), mc);
+ final BigDecimal mu = dc.subtract(ba).divide(divisor, mc);
+ // Variance
+ divisor = divisor.multiply(BigDecimal.valueOf(2));
+ dc = dd.pow(4).subtract(cc.pow(4)).divide(dd.subtract(cc), mc);
+ ba = bb.pow(4).subtract(aa.pow(4)).divide(bb.subtract(aa), mc);
+ final BigDecimal var = dc.subtract(ba).divide(divisor, mc).subtract(mu.pow(2));
+ return Arguments.of(a, b, c, d, mu.doubleValue(), var.doubleValue(), ulps);
+ }
+
/**
* Create a trapezoid with a very long upper tail to explicitly test the survival
* probability is high precision.