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 2021/07/05 17:17:32 UTC

[commons-rng] branch master updated (a968c2a -> 678bfb4)

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

aherbert pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git.


    from a968c2a  Do not compute x = hz * W[iz] unless required.
     new 085ee67  Faster method for a signed double in [-1, 1)
     new 678bfb4  Testing more methods for a signed double of -1 or 1

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../jmh/sampling/UnitSphereSamplerBenchmark.java   | 32 +++++++++++++++++++++-
 .../sampling/shape/UnitBallSamplerBenchmark.java   | 27 +++++++++++++++++-
 .../rng/sampling/shape/UnitBallSampler.java        | 18 ++++++++----
 3 files changed, 69 insertions(+), 8 deletions(-)

[commons-rng] 01/02: Faster method for a signed double in [-1, 1)

Posted by ah...@apache.org.
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-rng.git

commit 085ee67661a1e98ff3cb114ab7c4ab47e0c6a05a
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Mon Jul 5 17:52:22 2021 +0100

    Faster method for a signed double in [-1, 1)
---
 .../sampling/shape/UnitBallSamplerBenchmark.java   | 27 +++++++++++++++++++++-
 .../rng/sampling/shape/UnitBallSampler.java        | 18 ++++++++++-----
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/shape/UnitBallSamplerBenchmark.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/shape/UnitBallSamplerBenchmark.java
index 87b911b..142d75d 100644
--- a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/shape/UnitBallSamplerBenchmark.java
+++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/shape/UnitBallSamplerBenchmark.java
@@ -151,13 +151,15 @@ public class UnitBallSamplerBenchmark {
     public static class Sampler1D extends SamplerData {
         /** Name for the signed double method. */
         private static final String SIGNED_DOUBLE = "signedDouble";
+        /** Name for the signed double method, version 2. */
+        private static final String SIGNED_DOUBLE2 = "signedDouble2";
         /** Name for the two doubles method. */
         private static final String TWO_DOUBLES = "twoDoubles";
         /** Name for the boolean double method. */
         private static final String BOOLEAN_DOUBLE = "booleanDouble";
 
         /** The sampler type. */
-        @Param({BASELINE, SIGNED_DOUBLE, TWO_DOUBLES, BOOLEAN_DOUBLE})
+        @Param({BASELINE, SIGNED_DOUBLE, SIGNED_DOUBLE2, TWO_DOUBLES, BOOLEAN_DOUBLE})
         private String type;
 
         /** {@inheritDoc} */
@@ -178,6 +180,14 @@ public class UnitBallSamplerBenchmark {
                         return new double[] {makeSignedDouble(rng.nextLong())};
                     }
                 };
+            } else if (SIGNED_DOUBLE2.equals(type)) {
+                return new Sampler() {
+                    @Override
+                    public double[] sample() {
+                        // Sample [-1, 1) uniformly
+                        return new double[] {makeSignedDouble2(rng.nextLong())};
+                    }
+                };
             } else if (TWO_DOUBLES.equals(type)) {
                 return new Sampler() {
                     @Override
@@ -739,6 +749,21 @@ public class UnitBallSamplerBenchmark {
      * @return the double
      */
     private static double makeSignedDouble(long bits) {
+        // As per o.a.c.rng.core.utils.NumberFactory.makeDouble(long) but using a signed
+        // shift of 10 in place of an unsigned shift of 11.
+        return (bits >> 10) * 0x1.0p-53d;
+    }
+
+    /**
+     * Creates a signed double in the range {@code [-1, 1)}. The magnitude is sampled evenly
+     * from the 2<sup>54</sup> dyadic rationals in the range.
+     *
+     * <p>Note: This method will not return samples for both -0.0 and 0.0.
+     *
+     * @param bits the bits
+     * @return the double
+     */
+    private static double makeSignedDouble2(long bits) {
         // Use the upper 54 bits on the assumption they are more random.
         // The sign bit generates a value of 0 or 1 for subtraction.
         // The next 53 bits generates a positive number in the range [0, 1).
diff --git a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/shape/UnitBallSampler.java b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/shape/UnitBallSampler.java
index 75b3ded..3096584 100644
--- a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/shape/UnitBallSampler.java
+++ b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/shape/UnitBallSampler.java
@@ -42,8 +42,13 @@ public abstract class UnitBallSampler implements SharedStateObjectSampler<double
     private static final int TWO_D = 2;
     /** The dimension for 3D sampling. */
     private static final int THREE_D = 3;
-    /** The mask to extract the lower 53-bits from a long. */
-    private static final long LOWER_53_BITS = -1L >>> 11;
+    /**
+     * The multiplier to convert the least significant 53-bits of a {@code long} to a {@code double}.
+     * Taken from o.a.c.rng.core.utils.NumberFactory.
+     *
+     * <p>This is equivalent to 1.0 / (1L << 53).
+     */
+    private static final double DOUBLE_MULTIPLIER = 0x1.0p-53d;
 
     /**
      * Sample uniformly from a 1D unit line.
@@ -239,10 +244,11 @@ public abstract class UnitBallSampler implements SharedStateObjectSampler<double
      * @return the double
      */
     private static double makeSignedDouble(long bits) {
+        // As per o.a.c.rng.core.utils.NumberFactory.makeDouble(long) but using a signed 
+        // shift of 10 in place of an unsigned shift of 11.
         // Use the upper 54 bits on the assumption they are more random.
-        // The sign bit generates a value of 0 or 1 for subtraction.
-        // The next 53 bits generates a positive number in the range [0, 1).
-        // [0, 1) - (0 or 1) => [-1, 1)
-        return (((bits >>> 10) & LOWER_53_BITS) * 0x1.0p-53d) - (bits >>> 63);
+        // The sign bit is maintained by the signed shift.
+        // The next 53 bits generates a magnitude in the range [0, 2^53) or [-2^53, 0).
+        return (bits >> 10) * DOUBLE_MULTIPLIER;
     }
 }

[commons-rng] 02/02: Testing more methods for a signed double of -1 or 1

Posted by ah...@apache.org.
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-rng.git

commit 678bfb434f208047e53424c32a13ca05f37bf31c
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Mon Jul 5 18:13:06 2021 +0100

    Testing more methods for a signed double of -1 or 1
---
 .../jmh/sampling/UnitSphereSamplerBenchmark.java   | 32 +++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/UnitSphereSamplerBenchmark.java b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/UnitSphereSamplerBenchmark.java
index bede36f..2911155 100644
--- a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/UnitSphereSamplerBenchmark.java
+++ b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/sampling/UnitSphereSamplerBenchmark.java
@@ -125,11 +125,15 @@ public class UnitSphereSamplerBenchmark {
     public static class Sampler1D extends SamplerData {
         /** Name for the signed double method. */
         private static final String SIGNED_DOUBLE = "signedDouble";
+        /** Name for the masked int method. */
+        private static final String MASKED_INT = "maskedInt";
+        /** Name for the masked long method. */
+        private static final String MASKED_LONG = "maskedLong";
         /** Name for the boolean method. */
         private static final String BOOLEAN = "boolean";
 
         /** The sampler type. */
-        @Param({BASELINE, SIGNED_DOUBLE, BOOLEAN, ARRAY})
+        @Param({BASELINE, SIGNED_DOUBLE, MASKED_INT, MASKED_LONG, BOOLEAN, ARRAY})
         private String type;
 
         /** {@inheritDoc} */
@@ -151,6 +155,32 @@ public class UnitSphereSamplerBenchmark {
                         return new double[] {1.0 - ((rng.nextInt() >>> 30) & 0x2)};
                     }
                 };
+            } else if (MASKED_INT.equals(type)) {
+                return new Sampler() {
+                    // The value 1.0 in raw long bits
+                    private final long one = Double.doubleToRawLongBits(1.0);
+                    // Mask to extract the sign bit from an integer (as a long)
+                    private final long signBit = 1L << 31;
+
+                    @Override
+                    public double[] sample() {
+                        // Shift the sign bit and combine with the bits for a double of 1.0
+                        return new double[] {Double.longBitsToDouble(one | ((rng.nextInt() & signBit) << 32))};
+                    }
+                };
+            } else if (MASKED_LONG.equals(type)) {
+                return new Sampler() {
+                    // The value 1.0 in raw long bits
+                    private final long one = Double.doubleToRawLongBits(1.0);
+                    // Mask to extract the sign bit from a long
+                    private final long signBit = 1L << 63;
+
+                    @Override
+                    public double[] sample() {
+                        // Combine the sign bit with the bits for a double of 1.0
+                        return new double[] {Double.longBitsToDouble(one | (rng.nextLong() & signBit))};
+                    }
+                };
             } else if (BOOLEAN.equals(type)) {
                 return new Sampler() {
                     @Override