This is an automated email from the ASF dual-hosted git repository. erans pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-math.git
commit bbfe7e4ea526e39ba0a79f0258200bc0d898f0de Author: Gilles Sadowski <gillese...@gmail.com> AuthorDate: Mon Apr 27 07:39:41 2020 +0200 MATH-1531: Avoid spurious exception. In the provided use-case, computation resulted in a value slightly above 1, thus throwing an exception (invalid probability). Workaround replaces the value by 1 when it is up to one ULP away. --- src/changes/changes.xml | 6 + .../math4/distribution/EmpiricalDistribution.java | 10 +- .../distribution/EmpiricalDistributionTest.java | 129 +++++++++++++++++++++ 3 files changed, 143 insertions(+), 2 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index e6c2c8a..800f66c 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -54,6 +54,12 @@ If the output is not quite correct, check for invisible trailing spaces! </release> <release version="4.0" date="XXXX-XX-XX" description=""> + <action dev="erans" type="fix" issue="MATH-1531"> + "EmpiricalDistribution": Workaround to avoid spurious exception. + </action> + <action dev="erans" type="update" issue="MATH-1530" due-to="Yassine Damerdji"> + "SplineInterpolator": Improved performance. + </action> <action dev="erans" type="add" issue="MATH-1529"> "AkimaSplineInterpolator": Option to use alternative weights. </action> diff --git a/src/main/java/org/apache/commons/math4/distribution/EmpiricalDistribution.java b/src/main/java/org/apache/commons/math4/distribution/EmpiricalDistribution.java index b9434d1..34779db 100644 --- a/src/main/java/org/apache/commons/math4/distribution/EmpiricalDistribution.java +++ b/src/main/java/org/apache/commons/math4/distribution/EmpiricalDistribution.java @@ -31,6 +31,8 @@ import java.util.List; import org.apache.commons.statistics.distribution.NormalDistribution; import org.apache.commons.statistics.distribution.ContinuousDistribution; import org.apache.commons.statistics.distribution.ConstantContinuousDistribution; +import org.apache.commons.numbers.core.Precision; +import org.apache.commons.rng.UniformRandomProvider; import org.apache.commons.math4.exception.MathIllegalStateException; import org.apache.commons.math4.exception.MathInternalError; import org.apache.commons.math4.exception.NullArgumentException; @@ -40,7 +42,6 @@ import org.apache.commons.math4.exception.NotStrictlyPositiveException; import org.apache.commons.math4.exception.util.LocalizedFormats; import org.apache.commons.math4.stat.descriptive.StatisticalSummary; import org.apache.commons.math4.stat.descriptive.SummaryStatistics; -import org.apache.commons.rng.UniformRandomProvider; import org.apache.commons.math4.util.FastMath; import org.apache.commons.math4.util.MathUtils; @@ -616,7 +617,12 @@ public class EmpiricalDistribution extends AbstractRealDistribution if (pCrit <= 0) { return lower; } - return kernel.inverseCumulativeProbability(kBminus + pCrit * kB / pB); + + final double cP = kBminus + pCrit * kB / pB; + + return Precision.equals(cP, 1d) ? + kernel.inverseCumulativeProbability(1d) : + kernel.inverseCumulativeProbability(cP); } /** diff --git a/src/test/java/org/apache/commons/math4/distribution/EmpiricalDistributionTest.java b/src/test/java/org/apache/commons/math4/distribution/EmpiricalDistributionTest.java index 5b0f492..a7b5825 100644 --- a/src/test/java/org/apache/commons/math4/distribution/EmpiricalDistributionTest.java +++ b/src/test/java/org/apache/commons/math4/distribution/EmpiricalDistributionTest.java @@ -142,6 +142,135 @@ public final class EmpiricalDistributionTest extends RealDistributionAbstractTes } + + // MATH-1531 + @Test + public void testMath1531() { + final EmpiricalDistribution inputDistribution = new EmpiricalDistribution(120); + inputDistribution.load(new double[] { + 50.993456376721454, + 49.455345691918055, + 49.527276095295804, + 50.017183448668845, + 49.10508147470046, + 49.813998274118696, + 50.87195348756139, + 50.419474110037, + 50.63614906979689, + 49.49694777179407, + 50.71799078406067, + 50.03192853759164, + 49.915092423165994, + 49.56895392597687, + 51.034638001064934, + 50.681227971275945, + 50.43749845081759, + 49.86513120270245, + 50.21475262482965, + 49.99202971042547, + 50.02382189838519, + 49.386888585302884, + 49.45585010202781, + 49.988009479855435, + 49.8136712206123, + 49.6715197127997, + 50.1981278397565, + 49.842297508010276, + 49.62491227740015, + 50.05101916097176, + 48.834912763303926, + 49.806787657848574, + 49.478236106374695, + 49.56648347371614, + 49.95069238081982, + 49.71845132077346, + 50.6097468705947, + 49.80724637775541, + 49.90448813086025, + 49.39641861662603, + 50.434295712893714, + 49.227176959566734, + 49.541126466050905, + 49.03416593170446, + 49.11584328494423, + 49.61387482435674, + 49.92877857995328, + 50.70638552955101, + 50.60078208448842, + 49.39326233277838, + 49.21488424364095, + 49.69503351015096, + 50.13733214001718, + 50.22084761458942, + 51.09804435604931, + 49.18559131120419, + 49.52286371605357, + 49.34804374996689, + 49.6901827776375, + 50.01316351359638, + 48.7751460520373, + 50.12961836291053, + 49.9978419772511, + 49.885658399408584, + 49.673438879979834, + 49.45565980965606, + 50.429747484906564, + 49.40129274804164, + 50.13034614008073, + 49.87685735146651, + 50.12967905393557, + 50.323560376181696, + 49.83519233651367, + 49.37333369733053, + 49.70074301611427, + 50.11626105774947, + 50.28249500380083, + 50.543354367136466, + 50.05866241335002, + 50.39516515672527, + 49.4838561463057, + 50.451757089234796, + 50.31370674203726, + 49.79063762614284, + 50.19652349768548, + 49.75881420748814, + 49.98371855036422, + 49.82171344472916, + 48.810793204162415, + 49.37040569084592, + 50.050641186203976, + 50.48360952263646, + 50.86666450358076, + 50.463268776129844, + 50.137489751888666, + 50.23823061444118, + 49.881460479468004, + 50.641174398764356, + 49.09314136851421, + 48.80877928574451, + 50.46197084844826, + 49.97691704141741, + 49.99933997561926, + 50.25692254481885, + 49.52973451252715, + 49.81229858420664, + 48.996112655915994, + 48.740531054814674, + 50.026642633066416, + 49.98696633604899, + 49.61307159972952, + 50.5115278979726, + 50.75245152442404, + 50.51807785445929, + 49.60929671768147, + 49.1079533564074, + 49.65347196551866, + 49.31684818724059, + 50.4906368627049, + 50.37483603684714}); + inputDistribution.inverseCumulativeProbability(0.7166666666666669); + } + /** * Generate 1000 random values and make sure they look OK.<br> * Note that there is a non-zero (but very small) probability that