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

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


The following commit(s) were added to refs/heads/master by this push:
     new 458a8d19 STATISTICS-101: Use Commons RNG zeta sampler
458a8d19 is described below

commit 458a8d1966de697542e262d2af3c1a7cc9ec9951
Author: Alex Herbert <[email protected]>
AuthorDate: Fri Sep 18 16:30:31 2026 +0100

    STATISTICS-101: Use Commons RNG zeta sampler
    
    See RNG-203.
---
 .../statistics/distribution/ZetaDistribution.java  | 91 +---------------------
 .../distribution/ZetaDistributionTest.java         |  3 +-
 pom.xml                                            | 14 +++-
 3 files changed, 18 insertions(+), 90 deletions(-)

diff --git 
a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ZetaDistribution.java
 
b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ZetaDistribution.java
index c85b925b..772179a1 100644
--- 
a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ZetaDistribution.java
+++ 
b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ZetaDistribution.java
@@ -17,8 +17,8 @@
 
 package org.apache.commons.statistics.distribution;
 
-import java.util.function.ToDoubleFunction;
 import org.apache.commons.rng.UniformRandomProvider;
+import org.apache.commons.rng.sampling.distribution.ZetaSampler;
 
 /**
  * Implementation of the zeta distribution.
@@ -355,92 +355,7 @@ public final class ZetaDistribution extends 
AbstractDiscreteDistribution {
     /** {@inheritDoc} */
     @Override
     public DiscreteDistribution.Sampler createSampler(final 
UniformRandomProvider rng) {
-        return new ZetaSampler(rng, exponent);
-    }
-
-    /**
-     * Sample from a zeta distribution.
-     * <ol>
-     * <li>Devroye, L (2015)
-     * Non-uniform random variate generation.
-     * Springer New York, NY. pp 550-552.</li>
-     * </ol>
-     */
-    private static final class ZetaSampler implements 
DiscreteDistribution.Sampler {
-        /**
-         * The threshold to bias the extreme sample to 1 or infinity. Change 
the
-         * extreme sample of the zeta distribution using the midpoint of the 
support
-         * domain, i.e. x = 2^31 / 2; cdf(x; a) = sf(x; a) ~ 0.5.
-         */
-        private static final double THRESHOLD = 1.0324376395045163;
-
-        /** Source of randomness. */
-        private final UniformRandomProvider rng;
-        /** a - 1. */
-        private final double am1;
-        /** Reciprocal of (a - 1) = 1 / (a - 1). */
-        private final double ram1;
-        /** b = 2^(a-1). This constants is {@code (b-1) / b}. */
-        private final double bm1Db;
-        /** Function to compute u in [0, 1]. */
-        private final ToDoubleFunction<UniformRandomProvider> nextU;
-
-        /**
-         * Create an instance.
-         *
-         * @param rng Source of randomness.
-         * @param a Exponent of the zeta distribution ({@code a > 1}).
-         */
-        ZetaSampler(UniformRandomProvider rng, double a) {
-            this.rng = rng;
-            am1 = a - 1;
-            ram1 = 1 / am1;
-            final double b = Math.pow(2, am1);
-            bm1Db = b == Double.POSITIVE_INFINITY ? 1 : (b - 1) / b;
-            // Note:
-            // u in [0, 1]
-            // u == 0 : x == inf
-            // u == 1 : x == 1
-            // When a -> 1 then bias to infinity; otherwise bias to 1.
-            nextU = a <= THRESHOLD ?
-                // u in [0, 1)
-                UniformRandomProvider::nextDouble :
-                // u in (0, 1]
-                g -> 1.0 - g.nextDouble();
-        }
-
-        @Override
-        public int sample() {
-            double u;
-            double v;
-            double x;
-            double t;
-            for (;;) {
-                // Generate iid uniform [0, 1] random variate U, V.
-                u = nextU.applyAsDouble(rng);
-                v = rng.nextDouble();
-                // X = floor ( U^{-1/(a-1)} ) , X in [1, inf]
-                x = Math.floor(Math.pow(u, -ram1));
-                t = Math.pow(1 + 1 / x, am1);
-
-                // Until:
-                //    T-1    T
-                // VX --- <= -
-                //    b-1    b
-
-                // If (a-1) -> inf then t & b -> inf; b >= t
-                // Avoid inf / inf = NaN and accept.
-                // Large a will mostly sample X=1.
-
-                // v * x * (t - 1) / (b - 1) <= t / b
-                // Rearrange terms to ratios of similar magnitude and guard 
infinity:
-                // v * x <= (t / (t - 1)) * ((b - 1) / b)
-                final double tDtm1 = t == Double.POSITIVE_INFINITY ? 1 : t / 
(t - 1);
-                if (v * x <= tDtm1 * bm1Db) {
-                    // Truncates x >= 2^31 to integer max
-                    return (int) x;
-                }
-            }
-        }
+        // Zeta distribution sampler
+        return ZetaSampler.of(rng, exponent)::sample;
     }
 }
diff --git 
a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ZetaDistributionTest.java
 
b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ZetaDistributionTest.java
index 00ca8d9d..ad72ae12 100644
--- 
a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ZetaDistributionTest.java
+++ 
b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ZetaDistributionTest.java
@@ -223,7 +223,8 @@ class ZetaDistributionTest extends 
BaseDiscreteDistributionTest {
      */
     @ParameterizedTest
     @CsvSource({
-        // Threshold to switch the sampler extreme value bias from x=1 to x=inf
+        // Threshold to switch the sampler extreme value bias from x=1 to 
x=inf.
+        // This value is used in the Commons RNG ZetaSampler (RNG-203).
         "0.5, 1073741824, 1.0324376395045163",
         // Used in the class javadoc to describe truncation of the distribution
         "0.01, 2147483647, 1.2088900037546617",
diff --git a/pom.xml b/pom.xml
index 3ab45681..ec1d7170 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,6 +56,18 @@
     </site>
   </distributionManagement>
 
+  <repositories>
+    <!-- TODO: remove when Commons RNG 1.8 is released -->
+    <repository>
+      <id>apache.snapshots</id>
+      <name>Apache Snapshot Repository</name>
+      <url>https://repository.apache.org/snapshots</url>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+    </repository>
+  </repositories>
+
   <developers>
     <developer>
       <name>Gilles Sadowski</name>
@@ -137,7 +149,7 @@
     <doclint.javadoc.qualifier>-Xdoclint:all</doclint.javadoc.qualifier>
 
     <!-- Dependency versions -->
-    <statistics.commons.rng.version>1.7</statistics.commons.rng.version>
+    
<statistics.commons.rng.version>1.8-SNAPSHOT</statistics.commons.rng.version>
     
<statistics.commons.numbers.version>1.3</statistics.commons.numbers.version>
     <statistics.commons.math3.version>3.6.1</statistics.commons.math3.version>
     
<statistics.commons.math4.version>4.0-beta1</statistics.commons.math4.version>

Reply via email to