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/12/06 18:39:04 UTC

[commons-statistics] branch master updated: Change LongSupplier for random bits to IntUnaryOperator

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


The following commit(s) were added to refs/heads/master by this push:
     new f4b1e8c  Change LongSupplier for random bits to IntUnaryOperator
f4b1e8c is described below

commit f4b1e8c439b9319cfa019e303074f485aca4d060
Author: aherbert <ah...@apache.org>
AuthorDate: Tue Dec 6 18:37:53 2022 +0000

    Change LongSupplier for random bits to IntUnaryOperator
    
    This removes the dependency on Commons RNG from the module.
---
 commons-statistics-ranking/pom.xml                 |  5 --
 .../commons/statistics/ranking/NaturalRanking.java | 61 ++++++++++------------
 .../statistics/ranking/NaturalRankingTest.java     | 12 ++---
 .../commons/statistics/ranking/UserGuideTest.java  |  4 +-
 src/site/xdoc/userguide/index.xml                  |  4 +-
 5 files changed, 39 insertions(+), 47 deletions(-)

diff --git a/commons-statistics-ranking/pom.xml b/commons-statistics-ranking/pom.xml
index 91a1ecb..e6e0597 100644
--- a/commons-statistics-ranking/pom.xml
+++ b/commons-statistics-ranking/pom.xml
@@ -45,11 +45,6 @@
 
   <dependencies>
 
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-rng-client-api</artifactId>
-    </dependency>
-
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-rng-simple</artifactId>
diff --git a/commons-statistics-ranking/src/main/java/org/apache/commons/statistics/ranking/NaturalRanking.java b/commons-statistics-ranking/src/main/java/org/apache/commons/statistics/ranking/NaturalRanking.java
index af7e08f..1445592 100644
--- a/commons-statistics-ranking/src/main/java/org/apache/commons/statistics/ranking/NaturalRanking.java
+++ b/commons-statistics-ranking/src/main/java/org/apache/commons/statistics/ranking/NaturalRanking.java
@@ -19,8 +19,7 @@ package org.apache.commons.statistics.ranking;
 import java.util.Arrays;
 import java.util.SplittableRandom;
 import java.util.function.DoubleUnaryOperator;
-import java.util.function.LongSupplier;
-import org.apache.commons.rng.UniformRandomProvider;
+import java.util.function.IntUnaryOperator;
 
 /**
  * Ranking based on the natural ordering on floating-point values.
@@ -31,15 +30,15 @@ import org.apache.commons.rng.UniformRandomProvider;
  * constructor arguments. Defaults are {@link NaNStrategy#FAILED} and
  * {@link TiesStrategy#AVERAGE}, respectively.
  *
- * <p>When using {@link TiesStrategy#RANDOM}, a generator of random bits may be
- * supplied as a {@link LongSupplier} argument; otherwise a default is created
+ * <p>When using {@link TiesStrategy#RANDOM}, a generator of random values in {@code [0, x)}
+ * supplied as a {@link IntUnaryOperator} argument; otherwise a default is created
  * on-demand. The source of randomness can be supplied using a method reference.
  * The following example creates a ranking with NaN values with the highest
  * ranking and ties resolved randomly:
  *
  * <pre>
  * NaturalRanking ranking = new NaturalRanking(NaNStrategy.MAXIMAL,
- *                                             new SplittableRandom()::nextLong);
+ *                                             new SplittableRandom()::nextInt);
  * </pre>
  *
  * <p>Note: Using {@link TiesStrategy#RANDOM} is not thread-safe due to the mutable
@@ -102,10 +101,9 @@ public class NaturalRanking implements RankingAlgorithm {
     /** Ties strategy. */
     private final TiesStrategy tiesStrategy;
     /** Source of randomness when ties strategy is RANDOM.
+     * Function maps positive x to {@code [0, x)}.
      * Can be null to default to a JDK implementation. */
-    private final LongSupplier randomSource;
-    /** Random generator created on demand when ties strategy is RANDOM. */
-    private UniformRandomProvider rng;
+    private IntUnaryOperator randomIntFunction;
 
     /**
      * Creates an instance with {@link NaNStrategy#FAILED} and
@@ -155,37 +153,39 @@ public class NaturalRanking implements RankingAlgorithm {
 
     /**
      * Creates an instance with {@link NaNStrategy#FAILED},
-     * {@link TiesStrategy#RANDOM} and the given the source of random data.
+     * {@link TiesStrategy#RANDOM} and the given the source of random index data.
      *
-     * @param randomSource Source of random data.
+     * @param randomIntFunction Source of random index data.
+     * Function maps positive {@code x} randomly to {@code [0, x)}
      */
-    public NaturalRanking(LongSupplier randomSource) {
-        this(DEFAULT_NAN_STRATEGY, TiesStrategy.RANDOM, randomSource);
+    public NaturalRanking(IntUnaryOperator randomIntFunction) {
+        this(DEFAULT_NAN_STRATEGY, TiesStrategy.RANDOM, randomIntFunction);
     }
 
     /**
      * Creates an instance with the specified @{@code nanStrategy},
-     * {@link TiesStrategy#RANDOM} and the given the source of random data.
+     * {@link TiesStrategy#RANDOM} and the given the source of random index data.
      *
      * @param nanStrategy NaNStrategy to use.
-     * @param randomSource Source of random data.
+     * @param randomIntFunction Source of random index data.
+     * Function maps positive {@code x} randomly to {@code [0, x)}
      */
     public NaturalRanking(NaNStrategy nanStrategy,
-                          LongSupplier randomSource) {
-        this(nanStrategy, TiesStrategy.RANDOM, randomSource);
+                          IntUnaryOperator randomIntFunction) {
+        this(nanStrategy, TiesStrategy.RANDOM, randomIntFunction);
     }
 
     /**
      * @param nanStrategy NaNStrategy to use.
      * @param tiesStrategy TiesStrategy to use.
-     * @param randomSource Source of random data.
+     * @param randomIntFunction Source of random index data.
      */
     private NaturalRanking(NaNStrategy nanStrategy,
                            TiesStrategy tiesStrategy,
-                           LongSupplier randomSource) {
+                           IntUnaryOperator randomIntFunction) {
         this.nanStrategy = nanStrategy;
         this.tiesStrategy = tiesStrategy;
-        this.randomSource = randomSource;
+        this.randomIntFunction = randomIntFunction;
     }
 
     /**
@@ -397,7 +397,7 @@ public class NaturalRanking implements RankingAlgorithm {
             // This cast is safe as c is a counter.
             int r = (int) c;
             if (tiesStrategy == TiesStrategy.RANDOM) {
-                tiesTrace.shuffle(getRNG());
+                tiesTrace.shuffle(getRandomIntFunction());
             }
             final int size = tiesTrace.size();
             for (int i = 0; i < size; i++) {
@@ -426,19 +426,16 @@ public class NaturalRanking implements RankingAlgorithm {
     }
 
     /**
-     * Gets the random generator from the source of randomness.
-     * Defaults to a system provided generator if the source of randomness is null.
+     * Gets the function to map positive {@code x} randomly to {@code [0, x)}.
+     * Defaults to a system provided generator if the constructor source of randomness is null.
      *
      * @return the RNG
      */
-    private UniformRandomProvider getRNG() {
-        UniformRandomProvider r = rng;
+    private IntUnaryOperator getRandomIntFunction() {
+        IntUnaryOperator r = randomIntFunction;
         if (r == null) {
-            // Use the provided source, or default to a SplittableRandom
-            final LongSupplier source = randomSource != null ?
-                randomSource :
-                new SplittableRandom()::nextLong;
-            rng = r = source::getAsLong;
+            // Default to a SplittableRandom
+            randomIntFunction = r = new SplittableRandom()::nextInt;
         }
         return r;
     }
@@ -506,13 +503,13 @@ public class NaturalRanking implements RankingAlgorithm {
         /**
          * Shuffle the list.
          *
-         * @param rng Source of randomness
+         * @param randomIntFunction Function maps positive {@code x} randomly to {@code [0, x)}.
          */
-        void shuffle(UniformRandomProvider rng) {
+        void shuffle(IntUnaryOperator randomIntFunction) {
             // Fisher-Yates shuffle
             final int[] array = data;
             for (int i = size; i > 1; i--) {
-                swap(array, i - 1, rng.nextInt(i));
+                swap(array, i - 1, randomIntFunction.applyAsInt(i));
             }
         }
 
diff --git a/commons-statistics-ranking/src/test/java/org/apache/commons/statistics/ranking/NaturalRankingTest.java b/commons-statistics-ranking/src/test/java/org/apache/commons/statistics/ranking/NaturalRankingTest.java
index a0acb7c..bf454b8 100644
--- a/commons-statistics-ranking/src/test/java/org/apache/commons/statistics/ranking/NaturalRankingTest.java
+++ b/commons-statistics-ranking/src/test/java/org/apache/commons/statistics/ranking/NaturalRankingTest.java
@@ -19,7 +19,7 @@ package org.apache.commons.statistics.ranking;
 import java.util.Arrays;
 import java.util.BitSet;
 import java.util.List;
-import java.util.function.LongSupplier;
+import java.util.function.IntUnaryOperator;
 import java.util.stream.Collectors;
 import java.util.stream.DoubleStream;
 import java.util.stream.IntStream;
@@ -56,7 +56,7 @@ class NaturalRankingTest {
     void testProperties() {
         final TiesStrategy defaultTs = TiesStrategy.AVERAGE;
         final NaNStrategy defaultNs = NaNStrategy.FAILED;
-        final LongSupplier randomSource = null;
+        final IntUnaryOperator randomSource = null;
         NaturalRanking ranking;
 
         ranking = new NaturalRanking();
@@ -253,7 +253,7 @@ class NaturalRankingTest {
         final UniformRandomProvider rng = RandomSource.SPLIT_MIX_64.create();
         final Stream.Builder<Arguments> builder = Stream.builder();
         builder.add(Arguments.of(
-            new NaturalRanking(rng::nextLong),
+            new NaturalRanking(rng::nextInt),
             null,
             new int[] {1, 1, 3, 2, 4},
             new int[] {3, 3, 2, 1},
@@ -262,7 +262,7 @@ class NaturalRankingTest {
             new int[] {1, 1, 1, 1}
         ));
         builder.add(Arguments.of(
-            new NaturalRanking(NaNStrategy.FIXED, rng::nextLong),
+            new NaturalRanking(NaNStrategy.FIXED, rng::nextInt),
             new int[] {3, 2, 4, 5, 2, 6, 0, 1, 2},
             new int[] {1, 1, 3, 2, 4},
             new int[] {3, 3, 2, 1},
@@ -271,7 +271,7 @@ class NaturalRankingTest {
             new int[] {1, 1, 1, 1}
         ));
         builder.add(Arguments.of(
-            new NaturalRanking(NaNStrategy.REMOVED, rng::nextLong),
+            new NaturalRanking(NaNStrategy.REMOVED, rng::nextInt),
             new int[] {3, 2, 4, 5, 2, 6, -1, 1, 2},
             new int[] {1, 1, 3, 2, 4},
             new int[] {3, 3, 2, 1},
@@ -410,7 +410,7 @@ class NaturalRankingTest {
         IntStream.range(0, after).forEach(i -> builder.add(++value[0]));
         final double[] data = builder.build().toArray();
         final UniformRandomProvider rng = RandomSource.SPLIT_MIX_64.create(seed);
-        final NaturalRanking ranking = new NaturalRanking(rng::nextLong);
+        final NaturalRanking ranking = new NaturalRanking(rng::nextInt);
         final int k = before + 1;
         final int m = before + ties;
         // Frequency of ranks for each tied position in the data
diff --git a/commons-statistics-ranking/src/test/java/org/apache/commons/statistics/ranking/UserGuideTest.java b/commons-statistics-ranking/src/test/java/org/apache/commons/statistics/ranking/UserGuideTest.java
index 123174a..1e8ba32 100644
--- a/commons-statistics-ranking/src/test/java/org/apache/commons/statistics/ranking/UserGuideTest.java
+++ b/commons-statistics-ranking/src/test/java/org/apache/commons/statistics/ranking/UserGuideTest.java
@@ -64,9 +64,9 @@ class UserGuideTest {
     void testRanking4() {
         final double[] data = {7, 5, 7, 6};
         final double[] r1 = new NaturalRanking(TiesStrategy.RANDOM).apply(data);
-        final double[] r2 = new NaturalRanking(new SplittableRandom()::nextLong).apply(data);
+        final double[] r2 = new NaturalRanking(new SplittableRandom()::nextInt).apply(data);
         final UniformRandomProvider rng = RandomSource.KISS.create();
-        final double[] r3 = new NaturalRanking(rng::nextLong).apply(data);
+        final double[] r3 = new NaturalRanking(rng::nextInt).apply(data);
         final double[] expected1 = {3, 1, 4, 2};
         final double[] expected2 = {4, 1, 3, 2};
         Assertions.assertTrue(Arrays.equals(expected1, r1) || Arrays.equals(expected2, r1));
diff --git a/src/site/xdoc/userguide/index.xml b/src/site/xdoc/userguide/index.xml
index 47c7211..ad4e074 100644
--- a/src/site/xdoc/userguide/index.xml
+++ b/src/site/xdoc/userguide/index.xml
@@ -381,10 +381,10 @@ new NaturalRanking(TiesStrategy.RANDOM).apply(data);       // (3, 1, 4, 2)  or
 <source class="prettyprint">
 double[] data = new double[] {7, 5, 7, 6};
 new NaturalRanking(TiesStrategy.RANDOM).apply(data);
-new NaturalRanking(new SplittableRandom()::nextLong).apply(data);
+new NaturalRanking(new SplittableRandom()::nextInt).apply(data);
 // From Commons RNG
 UniformRandomProvider rng = RandomSource.KISS.create();
-new NaturalRanking(rng::nextLong).apply(data);
+new NaturalRanking(rng::nextInt).apply(data);
 // ranks: (3, 1, 4, 2)  or  (4, 1, 3, 2)
 </source>
     </section>