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>