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-math.git


The following commit(s) were added to refs/heads/master by this push:
     new 9a808f5a7 MATH-1696: Order enumerated real masses when computing 
quantiles (#353)
9a808f5a7 is described below

commit 9a808f5a76f2f3bfd5db877fa35bf3f9d27d8dfb
Author: Parijat Biswas <[email protected]>
AuthorDate: Thu Nov 12 02:45:50 2026 +0530

    MATH-1696: Order enumerated real masses when computing quantiles (#353)
    
    Sort enumerated real masses during construction
---
 .../distribution/EnumeratedRealDistribution.java   | 11 ++++--
 .../EnumeratedRealDistributionTest.java            | 46 ++++++++++++++++++++++
 2 files changed, 53 insertions(+), 4 deletions(-)

diff --git 
a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/distribution/EnumeratedRealDistribution.java
 
b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/distribution/EnumeratedRealDistribution.java
index 77385c8d4..efb68b342 100644
--- 
a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/distribution/EnumeratedRealDistribution.java
+++ 
b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/distribution/EnumeratedRealDistribution.java
@@ -17,7 +17,7 @@
 package org.apache.commons.math4.legacy.distribution;
 
 import java.util.ArrayList;
-import java.util.LinkedHashMap;
+import java.util.TreeMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -70,7 +70,9 @@ public class EnumeratedRealDistribution
                MathArithmeticException,
                NotFiniteNumberException,
                NotANumberException {
-        innerDistribution = new 
EnumeratedDistribution<>(createDistribution(singletons, probabilities));
+        final List<Pair<Double, Double>> samples = 
createDistribution(singletons, probabilities);
+        samples.sort((a, b) -> Double.compare(a.getKey(), b.getKey()));
+        innerDistribution = new EnumeratedDistribution<>(samples);
     }
 
     /**
@@ -80,7 +82,7 @@ public class EnumeratedRealDistribution
      * @param data input dataset
      */
     public EnumeratedRealDistribution(final double[] data) {
-        final Map<Double, Integer> dataMap = new LinkedHashMap<>();
+        final Map<Double, Integer> dataMap = new TreeMap<>();
         for (double value : data) {
             dataMap.merge(value, 1, Integer::sum);
         }
@@ -158,7 +160,8 @@ public class EnumeratedRealDistribution
 
         double probability = 0;
         double x = getSupportLowerBound();
-        for (final Pair<Double, Double> sample : innerDistribution.getPmf()) {
+        final List<Pair<Double, Double>> samples = innerDistribution.getPmf();
+        for (final Pair<Double, Double> sample : samples) {
             if (sample.getValue() == 0.0) {
                 continue;
             }
diff --git 
a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/distribution/EnumeratedRealDistributionTest.java
 
b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/distribution/EnumeratedRealDistributionTest.java
index 8a67bec58..cadf9aa5c 100644
--- 
a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/distribution/EnumeratedRealDistributionTest.java
+++ 
b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/distribution/EnumeratedRealDistributionTest.java
@@ -236,6 +236,44 @@ public class EnumeratedRealDistributionTest {
         assertEquals(28.0, distribution.inverseCumulativeProbability(0.7500), 
0.0);
     }
 
+    @Test
+    public void testInverseCumulativeProbabilityUnsortedSingletons() {
+        EnumeratedRealDistribution distribution = new 
EnumeratedRealDistribution(
+                new double[] {7, 3, -1, 3, -2, 8},
+                new double[] {0.25, 0.25, 0.25, 0.25, 0, 0});
+        assertEquals(-1, distribution.inverseCumulativeProbability(0), 0);
+        assertEquals(-1, distribution.inverseCumulativeProbability(0.25), 0);
+        assertEquals(3, distribution.inverseCumulativeProbability(0.5), 0);
+        assertEquals(3, distribution.inverseCumulativeProbability(0.75), 0);
+        assertEquals(7, distribution.inverseCumulativeProbability(1), 0);
+    }
+
+    @Test
+    public void testInverseCumulativeProbabilityUnsortedData() {
+        EnumeratedRealDistribution distribution = new 
EnumeratedRealDistribution(
+                new double[] {7, 3, -1, 3});
+        assertEquals(-1, distribution.inverseCumulativeProbability(0), 0);
+        assertEquals(-1, distribution.inverseCumulativeProbability(0.25), 0);
+        assertEquals(3, distribution.inverseCumulativeProbability(0.5), 0);
+        assertEquals(3, distribution.inverseCumulativeProbability(0.75), 0);
+        assertEquals(7, distribution.inverseCumulativeProbability(1), 0);
+    }
+
+    @Test
+    public void testInverseCumulativeProbabilityDoesNotChangeSampling() {
+        final double[] values = {7, 3, -1, 3};
+        EnumeratedRealDistribution distribution = new 
EnumeratedRealDistribution(values);
+        EnumeratedRealDistribution control = new 
EnumeratedRealDistribution(values);
+        distribution.inverseCumulativeProbability(0.5);
+        final ContinuousDistribution.Sampler actual =
+                
distribution.createSampler(RandomSource.WELL_512_A.create(12345L));
+        final ContinuousDistribution.Sampler expected =
+                control.createSampler(RandomSource.WELL_512_A.create(12345L));
+        for (int i = 0; i < 100; i++) {
+            assertEquals(expected.sample(), actual.sample(), 0);
+        }
+    }
+
     @Test
     public void testCreateFromDoubles() {
         final double[] data = new double[] {0, 1, 1, 2, 2, 2};
@@ -243,4 +281,12 @@ public class EnumeratedRealDistributionTest {
         assertEquals(0.5, distribution.density(2), 0);
         assertEquals(0.5, distribution.cumulativeProbability(1), 0);
     }
+
+    @Test
+    public void testQuantileUsesSameAccumulationOrderAsCdf() {
+        final EnumeratedRealDistribution distribution = new 
EnumeratedRealDistribution(
+            new double[] {2, 0, 1, 3}, new double[] {1, 2, 3, 1});
+        Assert.assertEquals(2, distribution.inverseCumulativeProbability(
+            distribution.cumulativeProbability(2)), 0);
+    }
 }

Reply via email to