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 cb6423ccfc742b209df5b9b181140bf9c15d6314
Author: Alex Herbert <aherb...@apache.org>
AuthorDate: Wed Mar 6 22:06:27 2019 +0000

    RNG-82: Add XorShift1024StarPhi generator
---
 .../rng/core/source64/XorShift1024Star.java        | 26 ++++++++++---
 .../rng/core/source64/XorShift1024StarPhi.java     | 44 ++++++++++++++++++++++
 .../org/apache/commons/rng/core/ProvidersList.java |  3 +-
 ...4StarTest.java => XorShift1024StarPhiTest.java} | 37 ++++++++++++------
 .../rng/core/source64/XorShift1024StarTest.java    | 11 ++++++
 .../apache/commons/rng/simple/RandomSource.java    |  8 ++++
 .../rng/simple/internal/ProviderBuilder.java       |  4 ++
 .../apache/commons/rng/simple/ProvidersList.java   |  1 +
 8 files changed, 116 insertions(+), 18 deletions(-)

diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024Star.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024Star.java
index 1d48896..c3557d0 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024Star.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024Star.java
@@ -21,11 +21,9 @@ import java.util.Arrays;
 import org.apache.commons.rng.core.util.NumberFactory;
 
 /**
- * A fast RNG.
- *
- * @see <a href="http://xorshift.di.unimi.it/xorshift1024star.c";>
- * Original source code</a>
+ * A fast RNG implementing the {@code XorShift1024*} algorithm.
  *
+ * @see <a href="http://xorshift.di.unimi.it/xorshift1024star.c";>Original 
source code</a>
  * @see <a href="https://en.wikipedia.org/wiki/Xorshift";>Xorshift 
(Wikipedia)</a>
  * @since 1.0
  */
@@ -34,6 +32,8 @@ public class XorShift1024Star extends LongProvider {
     private static final int SEED_SIZE = 16;
     /** State. */
     private final long[] state = new long[SEED_SIZE];
+    /** The multiplier for the XorShift1024 algorithm. */
+    private final long multiplier;
     /** Index in "state" array. */
     private int index;
 
@@ -44,8 +44,24 @@ public class XorShift1024Star extends LongProvider {
      * If the length is larger than 16, only the first 16 elements will
      * be used; if smaller, the remaining elements will be automatically
      * set.
+     * A seed containing all zeros will create a non-functional generator.
      */
     public XorShift1024Star(long[] seed) {
+        this(1181783497276652981L, seed);
+    }
+
+    /**
+     * Creates a new instance.
+     *
+     * @param multiplier The multiplier for the XorShift1024 algorithm.
+     * @param seed Initial seed.
+     * If the length is larger than 16, only the first 16 elements will
+     * be used; if smaller, the remaining elements will be automatically
+     * set.
+     * A seed containing all zeros will create a non-functional generator.
+     */
+    protected XorShift1024Star(long multiplier, long[] seed) {
+        this.multiplier = multiplier;
         setSeedInternal(seed);
     }
 
@@ -90,6 +106,6 @@ public class XorShift1024Star extends LongProvider {
         long s1 = state[index = (index + 1) & 15];
         s1 ^= s1 << 31; // a
         state[index] = s1 ^ s0 ^ (s1 >>> 11) ^ (s0 >>> 30); // b,c
-        return state[index] * 1181783497276652981L;
+        return state[index] * multiplier;
     }
 }
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024StarPhi.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024StarPhi.java
new file mode 100644
index 0000000..710dd6c
--- /dev/null
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024StarPhi.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.rng.core.source64;
+
+/**
+ * A fast RNG implementing the {@code XorShift1024*} algorithm.
+ *
+ * <p>This supersedes {@link XorShift1024Star}. The generator differs only in 
the multiplier (a
+ * fixed-point representation of the golden ratio), which eliminates linear 
dependencies from one of
+ * the lowest bits.
+ *
+ * @see <a href="http://xorshift.di.unimi.it/xorshift1024star.c";>Original 
source code</a>
+ * @see <a href="https://en.wikipedia.org/wiki/Xorshift";>Xorshift 
(Wikipedia)</a>
+ * @since 1.3
+ */
+public class XorShift1024StarPhi extends XorShift1024Star {
+    /**
+     * Creates a new instance.
+     *
+     * @param seed Initial seed.
+     * If the length is larger than 16, only the first 16 elements will
+     * be used; if smaller, the remaining elements will be automatically
+     * set.
+     * A seed containing all zeros will create a non-functional generator.
+     */
+    public XorShift1024StarPhi(long[] seed) {
+        super(0x9e3779b97f4a7c13L, seed);
+    }
+}
diff --git 
a/commons-rng-core/src/test/java/org/apache/commons/rng/core/ProvidersList.java 
b/commons-rng-core/src/test/java/org/apache/commons/rng/core/ProvidersList.java
index 767074a..c03b07f 100644
--- 
a/commons-rng-core/src/test/java/org/apache/commons/rng/core/ProvidersList.java
+++ 
b/commons-rng-core/src/test/java/org/apache/commons/rng/core/ProvidersList.java
@@ -16,7 +16,6 @@
  */
 package org.apache.commons.rng.core;
 
-import java.util.Arrays;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -35,6 +34,7 @@ import 
org.apache.commons.rng.core.source32.MultiplyWithCarry256;
 import org.apache.commons.rng.core.source32.KISSRandom;
 import org.apache.commons.rng.core.source64.SplitMix64;
 import org.apache.commons.rng.core.source64.XorShift1024Star;
+import org.apache.commons.rng.core.source64.XorShift1024StarPhi;
 import org.apache.commons.rng.core.source64.TwoCmres;
 import org.apache.commons.rng.core.source64.MersenneTwister64;
 import org.apache.commons.rng.RestorableUniformRandomProvider;
@@ -81,6 +81,7 @@ public class ProvidersList {
             // "long"-based RNGs.
             add(LIST64, new SplitMix64(g.nextLong()));
             add(LIST64, new XorShift1024Star(new long[] { g.nextLong(), 
g.nextLong(), g.nextLong(), g.nextLong() }));
+            add(LIST64, new XorShift1024StarPhi(new long[] { g.nextLong(), 
g.nextLong(), g.nextLong(), g.nextLong() }));
             add(LIST64, new TwoCmres(g.nextInt()));
             add(LIST64, new TwoCmres(g.nextInt(), 5, 8));
             add(LIST64, new MersenneTwister64(new long[] { g.nextLong(), 
g.nextLong(), g.nextLong(), g.nextLong() }));
diff --git 
a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source64/XorShift1024StarTest.java
 
b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source64/XorShift1024StarPhiTest.java
similarity index 51%
copy from 
commons-rng-core/src/test/java/org/apache/commons/rng/core/source64/XorShift1024StarTest.java
copy to 
commons-rng-core/src/test/java/org/apache/commons/rng/core/source64/XorShift1024StarPhiTest.java
index e158393..ffde7a4 100644
--- 
a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source64/XorShift1024StarTest.java
+++ 
b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source64/XorShift1024StarPhiTest.java
@@ -16,10 +16,13 @@
  */
 package org.apache.commons.rng.core.source64;
 
+import org.apache.commons.math3.stat.correlation.PearsonsCorrelation;
+import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
 import org.apache.commons.rng.core.RandomAssert;
+import org.junit.Assert;
 import org.junit.Test;
 
-public class XorShift1024StarTest {
+public class XorShift1024StarPhiTest {
     @Test
     public void testReferenceCode() {
         /*
@@ -34,18 +37,28 @@ public class XorShift1024StarTest {
         };
 
         final long[] expectedSequence = {
-            0xd85e9fc0855614cdL, 0xaf4965c9c1ac6a3dL, 0x067da398791111d8L, 
0x2771c41db58d7644L,
-            0xf71a471e1ac2b03eL, 0x953449ae275f7409L, 0x8aa570c72de0af5eL, 
0xae59db2acdae32beL,
-            0x3d46f316b8f97301L, 0x72dc8399b7a70957L, 0xf5624d788b3b6f4eL, 
0xb7a79275f6c0e7b1L,
-            0xf79354208377d498L, 0x0e5d2f2ac2b4f28fL, 0x0f8f57edc8aa802fL, 
0x5e918ea72ece0c36L,
-            0xeeb8dbdb00ac7a5aL, 0xf16f88dfef0d6047L, 0x1244c29e0e0d8d2dL, 
0xaa94f1cc42691eb7L,
-            0xd06425dd329e5de5L, 0x968b1c2e016f159cL, 0x6aadff7055065295L, 
0x3bce2efcb0d00876L,
-            0xb28d5b69ad8fb719L, 0x1e4040c451376920L, 0x6b0801a8a00de7d7L, 
0x891ba2cbe2a4675bL,
-            0x6355008481852527L, 0x7a47bcd9960126f3L, 0x07f72fcd4ebe3580L, 
0x4658b29c126840ccL,
-            0xdc7b36d3037c7539L, 0x9e30aab0410122e8L, 0x7215126e0fce932aL, 
0xda63f12a489fc8deL,
-            0x769997671b2a0158L, 0xfa9cd84e0ffc174dL, 0x34df1cd959dca211L, 
0xccea41a33ec1f763L,
+            0xc9351be6ae9af4bbL, 0x2696a1a51e3040cbL, 0xdcbbc38b838b4be8L, 
0xc989eee03351a25cL,
+            0xc4ad829b653ada72L, 0x1cff4000cc0118dfL, 0x988f3aaf7bfb2852L, 
0x3a621d4d5fb27bf2L,
+            0x0153d81cf33ff4a7L, 0x8a1b5adb974750c1L, 0x182799e238df6de2L, 
0x92d9bda951cd6377L,
+            0x601f077d2a659728L, 0x90536cc64ad5bc49L, 0x5d99d9e84e3d7fa9L, 
0xfc66f4610240613aL,
+            0x0ff67da640cdd6b6L, 0x973c7a6afbb41751L, 0x5089cb5236ac1b5bL, 
0x7ed6edc1e4d7e261L,
+            0x3e37630df0c00b63L, 0x49ec234a0d03bcc4L, 0x2bcbe2fa4b80fa33L, 
0xbaafc47b960baefaL,
+            0x1855fa47be98c84fL, 0x8d59cb57e34a73e0L, 0x256b15bb001bf641L, 
0x28ad378895f5615dL,
+            0x865547335ba2a571L, 0xfefe4c356e154585L, 0xeb87f7a74e076680L, 
0x990d2f5d1e60b914L,
+            0x3bf0f6864688af2fL, 0x8c6304df9b945d58L, 0x63bc09c335b63666L, 
0x1038139f53734ad2L,
+            0xf41b58faf5680868L, 0xa50ba830813c163bL, 0x7dc1ca503ae39817L, 
0xea3d0f2f37f5ce95L,
         };
 
-        RandomAssert.assertEquals(expectedSequence, new 
XorShift1024Star(seed));
+        RandomAssert.assertEquals(expectedSequence, new 
XorShift1024StarPhi(seed));
+    }
+
+    @Test
+    public void testConstructorWithZeroSeed() {
+        // This is allowed even though the generator is non-functional
+        final int size = 16;
+        final XorShift1024StarPhi rng = new XorShift1024StarPhi(new 
long[size]);
+        for (int i = size * 2; i-- != 0; ) {
+            Assert.assertEquals("Expected the generator to be broken", 0L, 
rng.nextLong());
+        }
     }
 }
diff --git 
a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source64/XorShift1024StarTest.java
 
b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source64/XorShift1024StarTest.java
index e158393..67fd4bb 100644
--- 
a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source64/XorShift1024StarTest.java
+++ 
b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source64/XorShift1024StarTest.java
@@ -17,6 +17,7 @@
 package org.apache.commons.rng.core.source64;
 
 import org.apache.commons.rng.core.RandomAssert;
+import org.junit.Assert;
 import org.junit.Test;
 
 public class XorShift1024StarTest {
@@ -48,4 +49,14 @@ public class XorShift1024StarTest {
 
         RandomAssert.assertEquals(expectedSequence, new 
XorShift1024Star(seed));
     }
+
+    @Test
+    public void testConstructorWithZeroSeed() {
+        // This is allowed even though the generator is non-functional
+        final int size = 16;
+        final XorShift1024Star rng = new XorShift1024Star(new long[size]);
+        for (int i = size * 2; i-- != 0; ) {
+            Assert.assertEquals("Expected the generator to be broken", 0L, 
rng.nextLong());
+        }
+    }
 }
diff --git 
a/commons-rng-simple/src/main/java/org/apache/commons/rng/simple/RandomSource.java
 
b/commons-rng-simple/src/main/java/org/apache/commons/rng/simple/RandomSource.java
index adc8f43..f2a9bd5 100644
--- 
a/commons-rng-simple/src/main/java/org/apache/commons/rng/simple/RandomSource.java
+++ 
b/commons-rng-simple/src/main/java/org/apache/commons/rng/simple/RandomSource.java
@@ -246,6 +246,14 @@ public enum RandomSource {
      */
     XOR_SHIFT_1024_S(ProviderBuilder.RandomSourceInternal.XOR_SHIFT_1024_S),
     /**
+     * Source of randomness is {@link 
org.apache.commons.rng.core.source64.XorShift1024StarPhi}.
+     * <ul>
+     *  <li>Native seed type: {@code long[]}.</li>
+     *  <li>Native seed size: 16.</li>
+     * </ul>
+     */
+    
XOR_SHIFT_1024_S_PHI(ProviderBuilder.RandomSourceInternal.XOR_SHIFT_1024_S_PHI),
+    /**
      * Source of randomness is {@link 
org.apache.commons.rng.core.source64.TwoCmres}.
      * This generator is equivalent to {@link #TWO_CMRES_SELECT} with the 
choice of the
      * pair {@code (0, 1)} for the two subcycle generators.
diff --git 
a/commons-rng-simple/src/main/java/org/apache/commons/rng/simple/internal/ProviderBuilder.java
 
b/commons-rng-simple/src/main/java/org/apache/commons/rng/simple/internal/ProviderBuilder.java
index cf82d95..e3a540e 100644
--- 
a/commons-rng-simple/src/main/java/org/apache/commons/rng/simple/internal/ProviderBuilder.java
+++ 
b/commons-rng-simple/src/main/java/org/apache/commons/rng/simple/internal/ProviderBuilder.java
@@ -39,6 +39,7 @@ import 
org.apache.commons.rng.core.source32.MultiplyWithCarry256;
 import org.apache.commons.rng.core.source32.KISSRandom;
 import org.apache.commons.rng.core.source64.SplitMix64;
 import org.apache.commons.rng.core.source64.XorShift1024Star;
+import org.apache.commons.rng.core.source64.XorShift1024StarPhi;
 import org.apache.commons.rng.core.source64.TwoCmres;
 import org.apache.commons.rng.core.source64.MersenneTwister64;
 
@@ -290,6 +291,9 @@ public final class ProviderBuilder {
         /** Source of randomness is {@link XorShift1024Star}. */
         XOR_SHIFT_1024_S(XorShift1024Star.class,
                          long[].class),
+        /** Source of randomness is {@link XorShift1024StarPhi}. */
+        XOR_SHIFT_1024_S_PHI(XorShift1024StarPhi.class,
+                         long[].class),
         /** Source of randomness is {@link TwoCmres}. */
         TWO_CMRES(TwoCmres.class,
                   Integer.class),
diff --git 
a/commons-rng-simple/src/test/java/org/apache/commons/rng/simple/ProvidersList.java
 
b/commons-rng-simple/src/test/java/org/apache/commons/rng/simple/ProvidersList.java
index 2271cf8..cb88bf2 100644
--- 
a/commons-rng-simple/src/test/java/org/apache/commons/rng/simple/ProvidersList.java
+++ 
b/commons-rng-simple/src/test/java/org/apache/commons/rng/simple/ProvidersList.java
@@ -57,6 +57,7 @@ public class ProvidersList {
             // "long"-based RNGs.
             add(LIST64, RandomSource.SPLIT_MIX_64, -988777666655555L);
             add(LIST64, RandomSource.XOR_SHIFT_1024_S, new long[] { 123456L, 
234567L, -345678L });
+            add(LIST64, RandomSource.XOR_SHIFT_1024_S_PHI, new long[] { 
-234567L, -345678L, 3456789L });
             add(LIST64, RandomSource.TWO_CMRES, 55443322);
             add(LIST64, RandomSource.TWO_CMRES_SELECT, -987654321, 5, 8);
             add(LIST64, RandomSource.MT_64, new long[] { 1234567L, 2345678L, 
-3456789L });

Reply via email to