http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/LongProvider.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/LongProvider.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/LongProvider.java new file mode 100644 index 0000000..1fb096d --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/LongProvider.java @@ -0,0 +1,134 @@ +/* + * 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.internal.source64; + +import org.apache.commons.rng.internal.util.NumberFactory; +import org.apache.commons.rng.internal.BaseProvider; + +/** + * Base class for all implementations that provide a {@code long}-based + * source randomness. + */ +public abstract class LongProvider + extends BaseProvider + implements RandomLongSource { + + /** {@inheritDoc} */ + @Override + public abstract long next(); + + /** {@inheritDoc} */ + @Override + public long nextLong() { + return next(); + } + + /** {@inheritDoc} */ + @Override + public int nextInt() { + return NumberFactory.makeInt(nextLong()); + } + + /** {@inheritDoc} */ + @Override + public double nextDouble() { + return NumberFactory.makeDouble(nextLong()); + } + + /** {@inheritDoc} */ + @Override + public boolean nextBoolean() { + return NumberFactory.makeBoolean(nextLong()); + } + + /** {@inheritDoc} */ + @Override + public float nextFloat() { + return NumberFactory.makeFloat(nextInt()); + } + + /** {@inheritDoc} */ + @Override + public void nextBytes(byte[] bytes) { + nextBytesFill(this, bytes, 0, bytes.length); + } + + /** {@inheritDoc} */ + @Override + public void nextBytes(byte[] bytes, + int start, + int len) { + checkIndex(0, bytes.length - 1, start); + checkIndex(0, bytes.length - start, len); + + nextBytesFill(this, bytes, start, len); + } + + /** + * Generates random bytes and places them into a user-supplied array. + * + * <p> + * The array is filled with bytes extracted from random {@code long} values. + * This implies that the number of random bytes generated may be larger than + * the length of the byte array. + * </p> + * + * @param source Source of randomness. + * @param bytes Array in which to put the generated bytes. Cannot be null. + * @param start Index at which to start inserting the generated bytes. + * @param len Number of bytes to insert. + */ + static void nextBytesFill(RandomLongSource source, + byte[] bytes, + int start, + int len) { + int index = start; // Index of first insertion. + + // Index of first insertion plus multiple of 8 part of length + // (i.e. length with 3 least significant bits unset). + final int indexLoopLimit = index + (len & 0x7ffffff8); + + // Start filling in the byte array, 8 bytes at a time. + while (index < indexLoopLimit) { + final long random = source.next(); + bytes[index++] = (byte) random; + bytes[index++] = (byte) (random >>> 8); + bytes[index++] = (byte) (random >>> 16); + bytes[index++] = (byte) (random >>> 24); + bytes[index++] = (byte) (random >>> 32); + bytes[index++] = (byte) (random >>> 40); + bytes[index++] = (byte) (random >>> 48); + bytes[index++] = (byte) (random >>> 56); + } + + final int indexLimit = start + len; // Index of last insertion + 1. + + // Fill in the remaining bytes. + if (index < indexLimit) { + long random = source.next(); + while (true) { + bytes[index++] = (byte) random; + if (index < indexLimit) { + random >>>= 8; + } else { + break; + } + } + } + } +}
http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/MersenneTwister64.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/MersenneTwister64.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/MersenneTwister64.java new file mode 100644 index 0000000..45a70d3 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/MersenneTwister64.java @@ -0,0 +1,202 @@ +/* + * 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.internal.source64; + +import java.util.Arrays; +import org.apache.commons.rng.internal.util.NumberFactory; + +/** + * This class provides the 64-bits version of the originally 32-bits + * {@link org.apache.commons.rng.internal.source32.MersenneTwister + * Mersenne Twister}. + * + * <p> + * This class is mainly a Java port of + * <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt64.html"> + * the 2014/2/23 version of the generator + * </a> written in C by Takuji Nishimura and Makoto Matsumoto. + * </p> + * + * <p> + * Here is their original copyright: + * </p> + * + * <table border="0" width="80%" cellpadding="10" style="background-color: #E0E0E0" summary="Mersenne Twister licence"> + * <tr><td>Copyright (C) 2004, Makoto Matsumoto and Takuji Nishimura, + * All rights reserved.</td></tr> + * + * <tr><td>Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * <ol> + * <li>Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer.</li> + * <li>Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution.</li> + * <li>The names of its contributors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission.</li> + * </ol></td></tr> + * + * <tr><td><strong>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE.</strong></td></tr> + * </table> + * + * @see <a href="https://en.wikipedia.org/wiki/Mersenne_Twister">Mersenne Twister (Wikipedia)</a> + * @since 1.0 + */ +public class MersenneTwister64 extends LongProvider { + /** Size of the bytes pool. */ + private static final int NN = 312; + /** Period second parameter. */ + private static final int MM = 156; + /** X * MATRIX_A for X = {0, 1}. */ + private static final long[] MAG01 = { 0x0, 0xb5026f5aa96619e9L }; + /** Most significant 33 bits. */ + private static final long UM = 0xffffffff80000000L; + /** Least significant 31 bits. */ + private static final long LM = 0x7fffffffL; + /** Bytes pool. */ + private long[] mt = new long[NN]; + /** Current index in the bytes pool. */ + private int mti; + + /** + * Creates a new random number generator. + * + * @param seed Initial seed. + */ + public MersenneTwister64(long[] seed) { + setSeedInternal(seed); + } + + /** {@inheritDoc} */ + @Override + protected byte[] getStateInternal() { + final long[] s = Arrays.copyOf(mt, NN + 1); + s[NN] = mti; + + return NumberFactory.makeByteArray(s); + } + + /** {@inheritDoc} */ + @Override + protected void setStateInternal(byte[] s) { + checkStateSize(s, (NN + 1) * 8); + + final long[] tmp = NumberFactory.makeLongArray(s); + System.arraycopy(tmp, 0, mt, 0, NN); + mti = (int) tmp[NN]; + } + + /** + * Initializes the generator with the given seed. + * + * @param seed Initial seed. + */ + private void setSeedInternal(long[] seed) { + if (seed.length == 0) { + // Accept empty seed. + seed = new long[1]; + } + + initState(19650218L); + int i = 1; + int j = 0; + + for (int k = Math.max(NN, seed.length); k != 0; k--) { + final long mm1 = mt[i - 1]; + mt[i] = (mt[i] ^ ((mm1 ^ (mm1 >>> 62)) * 0x369dea0f31a53f85L)) + seed[j] + j; // non linear + i++; + j++; + if (i >= NN) { + mt[0] = mt[NN - 1]; + i = 1; + } + if (j >= seed.length) { + j = 0; + } + } + for (int k = NN - 1; k != 0; k--) { + final long mm1 = mt[i - 1]; + mt[i] = (mt[i] ^ ((mm1 ^ (mm1 >>> 62)) * 0x27bb2ee687b0b0fdL)) - i; // non linear + i++; + if (i >= NN) { + mt[0] = mt[NN - 1]; + i = 1; + } + } + + mt[0] = 0x8000000000000000L; // MSB is 1; assuring non-zero initial array + } + + /** + * Initialize the internal state of this instance. + * + * @param seed Seed. + */ + private void initState(long seed) { + mt[0] = seed; + for (mti = 1; mti < NN; mti++) { + final long mm1 = mt[mti - 1]; + mt[mti] = 0x5851f42d4c957f2dL * (mm1 ^ (mm1 >>> 62)) + mti; + } + } + + /** {@inheritDoc} */ + @Override + public long next() { + long x; + + if (mti >= NN) { // generate NN words at one time + for (int i = 0; i < NN - MM; i++) { + x = (mt[i] & UM) | (mt[i + 1] & LM); + mt[i] = mt[i + MM] ^ (x >>> 1) ^ MAG01[(int)(x & 0x1L)]; + } + for (int i = NN - MM; i < NN - 1; i++) { + x = (mt[i] & UM) | (mt[i + 1] & LM); + mt[i] = mt[ i + (MM - NN)] ^ (x >>> 1) ^ MAG01[(int)(x & 0x1L)]; + } + + x = (mt[NN - 1] & UM) | (mt[0] & LM); + mt[NN - 1] = mt[MM - 1] ^ (x >>> 1) ^ MAG01[(int)(x & 0x1L)]; + + mti = 0; + } + + x = mt[mti++]; + + x ^= (x >>> 29) & 0x5555555555555555L; + x ^= (x << 17) & 0x71d67fffeda60000L; + x ^= (x << 37) & 0xfff7eee000000000L; + x ^= x >>> 43; + + return x; + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/RandomLongSource.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/RandomLongSource.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/RandomLongSource.java new file mode 100644 index 0000000..e00730d --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/RandomLongSource.java @@ -0,0 +1,30 @@ +/* + * 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.internal.source64; + +/** + * Source of randomness that generates values of type {@code long}. + * + * @since 1.0 + */ +public interface RandomLongSource { + /** + * @return the next random value. + */ + long next(); +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/SplitMix64.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/SplitMix64.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/SplitMix64.java new file mode 100644 index 0000000..4992a4b --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/SplitMix64.java @@ -0,0 +1,75 @@ +/* + * 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.internal.source64; + +import org.apache.commons.rng.internal.util.NumberFactory; + +/** + * A fast RNG, with 64 bits of state, that can be used to initialize the + * state of other generators. + * + * @see <a href="http://xorshift.di.unimi.it/splitmix64.c"> + * Original source code</a> + * + * @since 1.0 + */ +public class SplitMix64 extends LongProvider { + /** State. */ + private long state; + + /** + * Creates a new instance. + * + * @param seed Initial seed. + */ + public SplitMix64(Long seed) { + setSeedInternal(seed); + } + + /** + * Seeds the RNG. + * + * @param seed Seed. + */ + private void setSeedInternal(Long seed) { + state = seed; + } + + /** {@inheritDoc} */ + @Override + public long next() { + long z = state += 0x9e3779b97f4a7c15L; + z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L; + z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL; + return z ^ (z >>> 31); + } + + /** {@inheritDoc} */ + @Override + protected byte[] getStateInternal() { + return NumberFactory.makeByteArray(state); + } + + /** {@inheritDoc} */ + @Override + protected void setStateInternal(byte[] s) { + checkStateSize(s, 8); + + state = NumberFactory.makeLong(s); + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/TwoCmres.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/TwoCmres.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/TwoCmres.java new file mode 100644 index 0000000..1e5eabc --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/TwoCmres.java @@ -0,0 +1,307 @@ +/* + * 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.internal.source64; + +import java.util.List; +import java.util.ArrayList; +import org.apache.commons.rng.internal.util.NumberFactory; + +/** + * Random number generator designed by Mark D. Overton. + * + * <p>It is one of the many generators described by the author in the following article series:</p> + * <ul> + * <li><a href="http://www.drdobbs.com/tools/fast-high-quality-parallel-random-number/229625477">Part one</a></li> + * <li><a href="http://www.drdobbs.com/tools/fast-high-quality-parallel-random-number/231000484">Part two</a></li> + * </ul> + * + * @since 1.0 + */ +public class TwoCmres extends LongProvider { + /** Error message. */ + private static final String INTERNAL_ERROR_MSG = "Internal error: Please file a bug report"; + /** A small positive integer. */ + private static final byte SEED_GUARD = 9; + /** Factory of instances of this class. Singleton. */ + private static final Cmres.Factory FACTORY = new Cmres.Factory(); + /** First subcycle generator. */ + private final Cmres x; + /** Second subcycle generator. */ + private final Cmres y; + /** State of first subcycle generator. */ + private long xx; + /** State of second subcycle generator. */ + private long yy; + + /** + * Creates a new instance. + * + * @param seed Initial seed. + * @param x First subcycle generator. + * @param y Second subcycle generator. + * @throws IllegalArgumentException if {@code x == y}. + */ + private TwoCmres(int seed, + Cmres x, + Cmres y) { + if (x == y) { + throw new IllegalArgumentException("Subcycle generators must be different"); + } + this.x = x; + this.y = y; + setSeedInternal(seed); + } + + /** + * Creates a new instance. + * + * @param seed Seed. + */ + public TwoCmres(Integer seed) { + this(seed, 0, 1); + } + + /** + * Creates a new instance. + * + * @param seed Seed. + * @param i Table entry for first subcycle generator. + * @param j Table entry for second subcycle generator. + * @throws IllegalArgumentException if {@code i == j}. + * @throws IndexOutOfBoundsException if {@code i < 0} or + * {@code i >= numberOfSubcycleGenerators()}. + * @throws IndexOutOfBoundsException if {@code j < 0} or + * {@code j >= numberOfSubcycleGenerators()}. + */ + public TwoCmres(Integer seed, + int i, + int j) { + this(seed, FACTORY.get(i), FACTORY.get(j)); + } + + /** {@inheritDoc} */ + @Override + public long next() { + xx = x.transform(xx); + yy = y.transform(yy); + + return xx + yy; + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return super.toString() + " (" + x + " + " + y + ")"; + } + + /** + * @return the number of subcycle generators. + */ + public static int numberOfSubcycleGenerators() { + return FACTORY.numberOfSubcycleGenerators(); + } + + /** {@inheritDoc} */ + @Override + protected byte[] getStateInternal() { + return NumberFactory.makeByteArray(new long[] { xx, yy }); + } + + /** {@inheritDoc} */ + @Override + protected void setStateInternal(byte[] s) { + checkStateSize(s, 16); + + final long[] state = NumberFactory.makeLongArray(s); + xx = state[0]; + yy = state[1]; + } + + /** + * @param seed Seed. + */ + private void setSeedInternal(int seed) { + // The seeding procedure consists in going away from some + // point known to be in the cycle. + // The total number of calls to the "transform" method will + // not exceed about 130,000 (which is negligible as seeding + // will not occur more than once in normal usage). + + // Make two positive 16-bits integers. + final long s = NumberFactory.makeLong(0, seed); // s >= 0 + final int xMax = (int) (s & 0xffff + SEED_GUARD); + final int yMax = (int) ((s >> 16) + SEED_GUARD); + + if (xMax < 0 || + yMax < 0) { + throw new IllegalStateException(INTERNAL_ERROR_MSG); + } + + xx = x.getStart(); + for (int i = xMax; i > 0; i--) { + xx = x.transform(xx); + } + + yy = y.getStart(); + for (int i = yMax; i > 0; i--) { + yy = y.transform(yy); + } + } + + /** + * Subcycle generator. + * Class is immutable. + */ + static class Cmres { + /** Cycle start. */ + private final int start; + /** Multiplier. */ + private final long multiply; + /** Rotation. */ + private final int rotate; + + /** + * @param multiply Multiplier. + * @param rotate Positive number. Must be in {@code [0, 64]}. + * @param start Cycle start. + */ + Cmres(long multiply, + int rotate, + int start) { + this.multiply = multiply; + this.rotate = rotate; + this.start = start; + } + + /** {@inheritDoc} */ + @Override + public String toString() { + final String sep = ", "; + // Use hexadecimal for "multiplier" field. + final String m = String.format((java.util.Locale) null, "0x%016xL", multiply); + return "Cmres: [" + m + sep + rotate + sep + start + "]"; + } + + /** + * @return the multiplier. + */ + public long getMultiply() { + return multiply; + } + + /** + * @return the cycle start. + */ + public int getStart() { + return start; + } + + /** + * @param state Current state. + * @return the new state. + */ + long transform(long state) { + long s = state; + s *= multiply; + s = rotl(s); + s -= state; + return s; + } + + /** + * @param state State. + * @return the rotated state. + */ + private long rotl(long state) { + return (state << rotate) | (state >>> (64 - rotate)); + } + + /** Factory. */ + static class Factory { + /** List of good "Cmres" subcycle generators. */ + private static final List<Cmres> TABLE = new ArrayList<Cmres>(); + + /** + * Populates the table. + * It lists parameters known to be good (provided in + * the article referred to above). + * To maintain compatibility, new entries must be added + * only at the end of the table. + */ + static { + add(0xedce446814d3b3d9L, 33, 0x13b572e7); + add(0xc5b3cf786c806df7L, 33, 0x13c8e18a); + add(0xdd91bbb8ab9e0e65L, 31, 0x06dd03a6); + add(0x7b69342c0790221dL, 31, 0x1646bb8b); + add(0x0c72c0d18614c32bL, 33, 0x06014a3d); + add(0xd8d98c13bebe26c9L, 33, 0x014e8475); + add(0xcb039dc328bbc40fL, 31, 0x008684bd); + add(0x858c5ef3c021ed2fL, 32, 0x0dc8d622); + add(0x4c8be96bfc23b127L, 33, 0x0b6b20cc); + add(0x11eab77f808cf641L, 32, 0x06534421); + add(0xbc9bd78810fd28fdL, 31, 0x1d9ba40d); + add(0x0f1505c780688cb5L, 33, 0x0b7b7b67); + add(0xadc174babc2053afL, 31, 0x267f4197); + add(0x900b6b82b31686d9L, 31, 0x023c6985); + // Add new entries here. + } + + /** + * @return the number of subcycle generators. + */ + int numberOfSubcycleGenerators() { + return TABLE.size(); + } + + /** + * @param index Index into the list of available generators. + * @return the subcycle generator entry at index {@code index}. + */ + Cmres get(int index) { + if (index < 0 || + index >= TABLE.size()) { + throw new IndexOutOfBoundsException("Out of interval [0, " + + (TABLE.size() - 1) + "]"); + } + + return TABLE.get(index); + } + + /** + * Adds an entry to the {@link Factory#TABLE}. + * + * @param multiply Multiplier. + * @param rotate Rotate. + * @param start Cycle start. + */ + private static void add(long multiply, + int rotate, + int start) { + // Sanity check: if there are duplicates, the class initialization + // will fail (and the JVM will report "NoClassDefFoundError"). + for (Cmres sg : TABLE) { + if (multiply == sg.getMultiply()) { + throw new IllegalStateException(INTERNAL_ERROR_MSG); + } + } + + TABLE.add(new Cmres(multiply, rotate, start)); + } + } + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/XorShift1024Star.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/XorShift1024Star.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/XorShift1024Star.java new file mode 100644 index 0000000..0aa2342 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/XorShift1024Star.java @@ -0,0 +1,94 @@ +/* + * 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.internal.source64; + +import java.util.Arrays; +import org.apache.commons.rng.internal.util.NumberFactory; +import org.apache.commons.rng.internal.util.SeedFactory; + +/** + * A fast RNG. + * + * @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 + */ +public class XorShift1024Star extends LongProvider { + /** Size of the state vector. */ + private static final int SEED_SIZE = 16; + /** State. */ + private final long[] state = new long[SEED_SIZE]; + /** Index in "state" array. */ + private int index; + + /** + * 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. + */ + public XorShift1024Star(long[] seed) { + setSeedInternal(seed); + } + + /** {@inheritDoc} */ + @Override + protected byte[] getStateInternal() { + final long[] s = Arrays.copyOf(state, SEED_SIZE + 1); + s[SEED_SIZE] = index; + + return NumberFactory.makeByteArray(s); + } + + /** {@inheritDoc} */ + @Override + protected void setStateInternal(byte[] s) { + checkStateSize(s, (SEED_SIZE + 1) * 8); + + final long[] tmp = NumberFactory.makeLongArray(s); + + System.arraycopy(tmp, 0, state, 0, SEED_SIZE); + index = (int) tmp[SEED_SIZE]; + } + + /** + * Seeds the RNG. + * + * @param seed Seed. + */ + private void setSeedInternal(long[] seed) { + // Reset the whole state of this RNG (i.e. "state" and "index"). + // Filling procedure is not part of the reference code. + SeedFactory.fillState(state, seed); + index = 0; + } + + /** {@inheritDoc} */ + @Override + public long next() { + final long s0 = state[index]; + 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; + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/package-info.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/package-info.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/package-info.java new file mode 100644 index 0000000..41639f3 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/source64/package-info.java @@ -0,0 +1,52 @@ +/* + * 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. + */ + +/** + * <h3> + * Concrete algorithms for {@code long}-based sources of randomness + * </h3> + * + * <p> + * <b>For internal use only:</b> Direct access to classes in this package + * is discouraged, as they could be modified without notice. + * </p> + * + * <p><b>Notes for developers</b></p> + * + * <ul> + * <li> + * A source of randomness must inherit from + * {@link org.apache.commons.rng.internal.source64.LongProvider} + * </li> + * <li> + * The "provider" must specify <em>one</em> way for setting the seed. + * For a given seed, the generated sequence must always be the same. + * </li> + * <li> + * The "provider" must implement methods {@code getStateInternal} and + * {@code setStateInternal} in order to save and restore the state of an + * instance (cf. {@link org.apache.commons.rng.internal.BaseProvider}). + * </li> + * <li> + * When a new class is implemented here, user-access to it must be provided + * through associated {@link org.apache.commons.rng.RandomSource + * factory methods}. + * </li> + * </ul> + */ + +package org.apache.commons.rng.internal.source64; http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/ByteArray2IntArray.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/ByteArray2IntArray.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/ByteArray2IntArray.java new file mode 100644 index 0000000..17bb19b --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/ByteArray2IntArray.java @@ -0,0 +1,39 @@ +/* + * 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.internal.util; + +import java.util.Arrays; + +/** + * Creates a {@code int[]} from a {@code byte[]}. + * + * @since 1.0 + */ +public class ByteArray2IntArray implements SeedConverter<byte[], int[]> { + /** Number of bytes in an {@code int}. */ + private static final int INT_SIZE = 4; + + /** {@inheritDoc} */ + @Override + public int[] convert(byte[] seed) { + final byte[] tmp = seed.length % INT_SIZE == 0 ? + seed : + Arrays.copyOf(seed, INT_SIZE * ((seed.length + INT_SIZE - 1) / INT_SIZE)); + + return NumberFactory.makeIntArray(tmp); + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/ByteArray2LongArray.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/ByteArray2LongArray.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/ByteArray2LongArray.java new file mode 100644 index 0000000..f564c01 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/ByteArray2LongArray.java @@ -0,0 +1,39 @@ +/* + * 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.internal.util; + +import java.util.Arrays; + +/** + * Creates a {@code long[]} from a {@code byte[]}. + * + * @since 1.0 + */ +public class ByteArray2LongArray implements SeedConverter<byte[], long[]> { + /** Number of bytes in a {@code long}. */ + private static final int LONG_SIZE = 8; + + /** {@inheritDoc} */ + @Override + public long[] convert(byte[] seed) { + final byte[] tmp = seed.length % LONG_SIZE == 0 ? + seed : + Arrays.copyOf(seed, LONG_SIZE * ((seed.length + LONG_SIZE - 1) / LONG_SIZE)); + + return NumberFactory.makeLongArray(tmp); + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Int2Long.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Int2Long.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Int2Long.java new file mode 100644 index 0000000..5b15134 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Int2Long.java @@ -0,0 +1,31 @@ +/* + * 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.internal.util; + +/** + * Converts a {@code Integer} to an {@code Long}. + * + * @since 1.0 + */ +public class Int2Long implements SeedConverter<Integer, Long> { + /** {@inheritDoc} */ + @Override + public Long convert(Integer seed) { + final int s = seed; + return NumberFactory.makeLong(s, ~s); + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/IntArray2Int.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/IntArray2Int.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/IntArray2Int.java new file mode 100644 index 0000000..f373529 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/IntArray2Int.java @@ -0,0 +1,35 @@ +/* + * 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.internal.util; + +/** + * Creates a single value by "xor" of all the values in the input array. + * + * @since 1.0 + */ +public class IntArray2Int implements SeedConverter<int[], Integer> { + /** {@inheritDoc} */ + @Override + public Integer convert(int[] seed) { + int out = 0; + for (int i = 0; i < seed.length; i++) { + out ^= seed[i]; + } + + return out; + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/IntArray2LongArray.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/IntArray2LongArray.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/IntArray2LongArray.java new file mode 100644 index 0000000..b4b6473 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/IntArray2LongArray.java @@ -0,0 +1,38 @@ +/* + * 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.internal.util; + +/** + * Creates a {@code long[]} from an {@code int[]}. + * + * @since 1.0 + */ +public class IntArray2LongArray implements SeedConverter<int[], long[]> { + /** {@inheritDoc} */ + @Override + public long[] convert(int[] seed) { + final int outSize = (seed.length + 1) / 2; + final long[] out = new long[outSize]; + for (int i = 0; i < outSize; i++) { + final int lo = seed[i]; + final int hi = outSize + i < seed.length ? seed[outSize + i] : 0; + out[i] = NumberFactory.makeLong(hi, lo); + } + + return out; + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2Int.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2Int.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2Int.java new file mode 100644 index 0000000..afb7d49 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2Int.java @@ -0,0 +1,30 @@ +/* + * 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.internal.util; + +/** + * Converts a {@code Long} to an {@code Integer}. + * + * @since 1.0 + */ +public class Long2Int implements SeedConverter<Long, Integer> { + /** {@inheritDoc} */ + @Override + public Integer convert(Long seed) { + return NumberFactory.makeInt(seed); + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2IntArray.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2IntArray.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2IntArray.java new file mode 100644 index 0000000..e271983 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2IntArray.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.internal.util; + +import org.apache.commons.rng.internal.source64.SplitMix64; + +/** + * Uses a {@code long} value to seed a {@link SplitMix64} RNG and + * create a {@code int[]} with the requested number of random + * values. + * + * @since 1.0 + */ +public class Long2IntArray implements SeedConverter<Long, int[]> { + /** Size of the output array. */ + private final int size; + + /** + * @param size Size of the output array. + */ + public Long2IntArray(int size) { + this.size = size; + } + + /** {@inheritDoc} */ + @Override + public int[] convert(Long seed) { + return SeedFactory.createIntArray(size, new SplitMix64(seed)); + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2LongArray.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2LongArray.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2LongArray.java new file mode 100644 index 0000000..820ba9e --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/Long2LongArray.java @@ -0,0 +1,50 @@ +/* + * 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.internal.util; + +import org.apache.commons.rng.internal.source64.SplitMix64; + +/** + * Uses a {@code Long} value to seed a {@link SplitMix64} RNG and + * create a {@code long[]} with the requested number of random + * values. + * + * @since 1.0 + */ +public class Long2LongArray implements SeedConverter<Long, long[]> { + /** Size of the output array. */ + private final int size; + + /** + * @param size Size of the output array. + */ + public Long2LongArray(int size) { + this.size = size; + } + + /** {@inheritDoc} */ + @Override + public long[] convert(Long seed) { + final long[] out = new long[size]; + final SplitMix64 rng = new SplitMix64(seed); + for (int i = 0; i < size; i++) { + out[i] = rng.nextLong(); + } + + return out; + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/LongArray2IntArray.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/LongArray2IntArray.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/LongArray2IntArray.java new file mode 100644 index 0000000..39376d8 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/LongArray2IntArray.java @@ -0,0 +1,37 @@ +/* + * 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.internal.util; + +/** + * Creates an {@code int[]} from a {@code long[]}. + * + * @since 1.0 + */ +public class LongArray2IntArray implements SeedConverter<long[], int[]> { + /** {@inheritDoc} */ + @Override + public int[] convert(long[] seed) { + final int[] out = new int[seed.length * 2]; + for (int i = 0; i < seed.length; i++) { + final long current = seed[i]; + out[i] = NumberFactory.extractLo(current); + out[seed.length + i] = NumberFactory.extractHi(current); + } + + return out; + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/LongArray2Long.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/LongArray2Long.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/LongArray2Long.java new file mode 100644 index 0000000..f6fd9d9 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/LongArray2Long.java @@ -0,0 +1,35 @@ +/* + * 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.internal.util; + +/** + * Creates a single value by "xor" of all the values in the input array. + * + * @since 1.0 + */ +public class LongArray2Long implements SeedConverter<long[], Long> { + /** {@inheritDoc} */ + @Override + public Long convert(long[] seed) { + long out = 0; + for (int i = 0; i < seed.length; i++) { + out ^= seed[i]; + } + + return out; + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/NoOpConverter.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/NoOpConverter.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/NoOpConverter.java new file mode 100644 index 0000000..6112f17 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/NoOpConverter.java @@ -0,0 +1,34 @@ +/* + * 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.internal.util; + + +/** + * Dummy converter that simply passes on its input. + * It can be useful to avoid "unchecked" compiler warnings. + * + * @param <SEED> Seed type. + * + * @since 1.0 + */ +public class NoOpConverter<SEED> implements SeedConverter<SEED, SEED> { + /** {@inheritDoc} */ + @Override + public SEED convert(SEED seed) { + return seed; + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/NumberFactory.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/NumberFactory.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/NumberFactory.java new file mode 100644 index 0000000..039decf --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/NumberFactory.java @@ -0,0 +1,332 @@ +/* + * 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.internal.util; + +import java.util.Arrays; + +/** + * Utility for creating number types from one or two {@code int} values + * or one {@code long} value, or a sequence of bytes. + */ +public final class NumberFactory { + /** See {@link #makeDouble(long)}. */ + private static final long DOUBLE_HIGH_BITS = 0x3ffL << 52; + /** See {@link #makeFloat(int)}. */ + private static final float FLOAT_MULTIPLIER = 0x1.0p-23f; + /** See {@link #makeDouble(int, int)}. */ + private static final double DOUBLE_MULTIPLIER = 0x1.0p-52d; + /** Lowest byte mask. */ + private static final long LONG_LOWEST_BYTE_MASK = 0xffL; + /** Number of bytes in a {@code long}. */ + private static final int LONG_SIZE = 8; + /** Lowest byte mask. */ + private static final int INT_LOWEST_BYTE_MASK = 0xff; + /** Number of bytes in a {@code int}. */ + private static final int INT_SIZE = 4; + + /** + * Class contains only static methods. + */ + private NumberFactory() {} + + /** + * @param v Number. + * @return a boolean. + */ + public static boolean makeBoolean(int v) { + return (v >>> 31) != 0; + } + + /** + * @param v Number. + * @return a boolean. + */ + public static boolean makeBoolean(long v) { + return (v >>> 63) != 0; + } + + /** + * @param v Number. + * @return a {@code double} value in the interval {@code [0, 1]}. + */ + public static double makeDouble(long v) { + // http://xorshift.di.unimi.it + return Double.longBitsToDouble(DOUBLE_HIGH_BITS | v >>> 12) - 1d; + } + + /** + * @param v Number (high order bits). + * @param w Number (low order bits). + * @return a {@code double} value in the interval {@code [0, 1]}. + */ + public static double makeDouble(int v, + int w) { + final long high = ((long) (v >>> 6)) << 26; + final int low = w >>> 6; + return (high | low) * DOUBLE_MULTIPLIER; + } + + /** + * @param v Number. + * @return a {@code float} value in the interval {@code [0, 1]}. + */ + public static float makeFloat(int v) { + return (v >>> 9) * FLOAT_MULTIPLIER; + } + + /** + * @param v Number (high order bits). + * @param w Number (low order bits). + * @return a {@code long} value. + */ + public static long makeLong(int v, + int w) { + return (((long) v) << 32) | (w & 0xffffffffL); + } + + /** + * Creates an {@code int} from a {@code long}. + * + * @param v Number. + * @return an {@code int} value made from the "xor" of the + * {@link #extractHi(long) high order bits} and + * {@link #extractLo(long) low order bits} of {@code v}. + */ + public static int makeInt(long v) { + return extractHi(v) ^ extractLo(v); + } + + /** + * Creates an {@code int} from a {@code long}, using the high order bits. + * + * <p>The returned value is such that if</p> + * <pre><code> + * vL = extractLo(v); + * vH = extractHi(v); + * </code></pre> + * + * <p>then {@code v} is equal to {@link #makeLong(int,int) makeLong(vH, vL)}.</p> + * + * @param v Number. + * @return an {@code int} value made from the most significant bits + * of {@code v}. + */ + public static int extractHi(long v) { + return (int) (v >>> 32); + } + + /** + * Creates an {@code int} from a {@code long}, using the low order bits. + * + * <p>The returned value is such that if</p> + * + * <pre><code> + * vL = extractLo(v); + * vH = extractHi(v); + * </code></pre> + * + * <p>then {@code v} is equal to {@link #makeLong(int,int) makeLong(vH, vL)}.</p> + * + * @param v Number. + * @return an {@code int} value made from the least significant bits + * of {@code v}. + */ + public static int extractLo(long v) { + return (int) v; + } + + /** + * Splits a {@code long} into 8 bytes. + * + * @param v Value. + * @return the bytes that compose the given value (least-significant + * byte first). + */ + public static byte[] makeByteArray(long v) { + final byte[] b = new byte[LONG_SIZE]; + + for (int i = 0; i < LONG_SIZE; i++) { + final int shift = i * 8; + b[i] = (byte) ((v >>> shift) & LONG_LOWEST_BYTE_MASK); + } + + return b; + } + + /** + * Creates a {@code long} from 8 bytes. + * + * @param input Input. + * @return the value that correspond to the given bytes assuming + * that the is ordered in increasing byte significance (i.e. the + * first byte in the array is the least-siginficant). + * @throws IllegalArgumentException if {@code input.length != 8}. + */ + public static long makeLong(byte[] input) { + checkSize(LONG_SIZE, input.length); + + long v = 0; + for (int i = 0; i < LONG_SIZE; i++) { + final int shift = i * 8; + v |= (((long) input[i]) & LONG_LOWEST_BYTE_MASK) << shift; + } + + return v; + } + + /** + * Splits an array of {@code long} values into a sequence of bytes. + * This method calls {@link #makeByteArray(long)} for each element of + * the {@code input}. + * + * @param input Input. + * @return an array of bytes. + */ + public static byte[] makeByteArray(long[] input) { + final int size = input.length * LONG_SIZE; + final byte[] b = new byte[size]; + + for (int i = 0; i < input.length; i++) { + final byte[] current = makeByteArray(input[i]); + System.arraycopy(current, 0, b, i * LONG_SIZE, LONG_SIZE); + } + + return b; + } + + /** + * Creates an array of {@code long} values from a sequence of bytes. + * This method calls {@link #makeLong(byte[])} for each subsequence + * of 8 bytes. + * + * @param input Input. + * @return an array of {@code long}. + * @throws IllegalArgumentException if {@code input.length} is not + * a multiple of 8. + */ + public static long[] makeLongArray(byte[] input) { + final int size = input.length; + final int num = size / LONG_SIZE; + checkSize(num * LONG_SIZE, size); + + final long[] output = new long[num]; + for (int i = 0; i < num; i++) { + final int from = i * LONG_SIZE; + final byte[] current = Arrays.copyOfRange(input, from, from + LONG_SIZE); + output[i] = makeLong(current); + } + + return output; + } + + /** + * Splits an {@code int} into 4 bytes. + * + * @param v Value. + * @return the bytes that compose the given value (least-significant + * byte first). + */ + public static byte[] makeByteArray(int v) { + final byte[] b = new byte[INT_SIZE]; + + for (int i = 0; i < INT_SIZE; i++) { + final int shift = i * 8; + b[i] = (byte) ((v >>> shift) & INT_LOWEST_BYTE_MASK); + } + + return b; + } + + /** + * Creates an {@code int} from 4 bytes. + * + * @param input Input. + * @return the value that correspond to the given bytes assuming + * that the is ordered in increasing byte significance (i.e. the + * first byte in the array is the least-siginficant). + * @throws IllegalArgumentException if {@code input.length != 4}. + */ + public static int makeInt(byte[] input) { + checkSize(INT_SIZE, input.length); + + int v = 0; + for (int i = 0; i < INT_SIZE; i++) { + final int shift = i * 8; + v |= (((int) input[i]) & INT_LOWEST_BYTE_MASK) << shift; + } + + return v; + } + + /** + * Splits an array of {@code int} values into a sequence of bytes. + * This method calls {@link #makeByteArray(int)} for each element of + * the {@code input}. + * + * @param input Input. + * @return an array of bytes. + */ + public static byte[] makeByteArray(int[] input) { + final int size = input.length * INT_SIZE; + final byte[] b = new byte[size]; + + for (int i = 0; i < input.length; i++) { + final byte[] current = makeByteArray(input[i]); + System.arraycopy(current, 0, b, i * INT_SIZE, INT_SIZE); + } + + return b; + } + + /** + * Creates an array of {@code int} values from a sequence of bytes. + * This method calls {@link #makeInt(byte[])} for each subsequence + * of 4 bytes. + * + * @param input Input. Length must be a multiple of 4. + * @return an array of {@code int}. + * @throws IllegalArgumentException if {@code input.length} is not + * a multiple of 4. + */ + public static int[] makeIntArray(byte[] input) { + final int size = input.length; + final int num = size / INT_SIZE; + checkSize(num * INT_SIZE, size); + + final int[] output = new int[num]; + for (int i = 0; i < num; i++) { + final int from = i * INT_SIZE; + final byte[] current = Arrays.copyOfRange(input, from, from + INT_SIZE); + output[i] = makeInt(current); + } + + return output; + } + + /** + * @param expected Expected value. + * @param actual Actual value. + * @throw IllegalArgumentException if {@code expected != actual}. + */ + private static void checkSize(int expected, + int actual) { + if (expected != actual) { + throw new IllegalArgumentException("Array size: Expected " + expected + + " but was " + actual); + } + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedConverter.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedConverter.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedConverter.java new file mode 100644 index 0000000..3286683 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedConverter.java @@ -0,0 +1,35 @@ +/* + * 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.internal.util; + +/** + * Seed converter. + * + * @param <IN> Input seed type. + * @param <OUT> Output seed type. + * + * @since 1.0 + */ +public interface SeedConverter<IN, OUT> { + /** + * Converts seed from input type to output type. + * + * @param seed Original seed value. + * @return the converted seed value. + */ + OUT convert(IN seed); +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedConverterComposer.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedConverterComposer.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedConverterComposer.java new file mode 100644 index 0000000..0fea1ca --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedConverterComposer.java @@ -0,0 +1,50 @@ +/* + * 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.internal.util; + +/** + * Composes two {@link SeedConverter converters}. + * + * @param <IN> Input seed type. + * @param <TRANS> Transitional seed type. + * @param <OUT> Output seed type. + * + * @since 1.0 + */ +public class SeedConverterComposer<IN, TRANS, OUT> implements SeedConverter<IN, OUT> { + /** First conversion. */ + private SeedConverter<IN, TRANS> first; + /** Second conversion. */ + private SeedConverter<TRANS, OUT> second; + + /** + * @param first First conversion. + * @param second second conversion. + */ + public SeedConverterComposer(SeedConverter<IN, TRANS> first, + SeedConverter<TRANS, OUT> second) { + this.first = first; + this.second = second; + } + + /** {@inheritDoc} */ + @Override + public OUT convert(IN seed) { + final TRANS trans = first.convert(seed); + return second.convert(trans); + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedFactory.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedFactory.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedFactory.java new file mode 100644 index 0000000..11fcfb1 --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/SeedFactory.java @@ -0,0 +1,357 @@ +/* + * 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.internal.util; + +import org.apache.commons.rng.internal.source32.RandomIntSource; +import org.apache.commons.rng.internal.source32.Well44497b; +import org.apache.commons.rng.internal.source64.RandomLongSource; +import org.apache.commons.rng.internal.source64.SplitMix64; + +/** + * Utilities related to seeding. + * + * <p> + * This class provides methods to generate random seeds (single values + * or arrays of values, of {@code int} or {@code long} types) that can + * be passed to the {@link org.apache.commons.rng.RandomSource + * methods that create a generator instance}. + * <br> + * Although the seed-generating methods defined in this class will likely + * return different values for all calls, there is no guarantee that the + * produced seed will result always in a "good" sequence of numbers (even + * if the generator initialized with that seed is good). + * <br> + * There is <i>no guarantee</i> that sequences will not overlap. + * </p> + * + * @since 1.0 + */ +public class SeedFactory { + /** Generator with a long period. */ + private static final RandomIntSource SEED_GENERATOR; + + static { + // Another RNG for initializing the "SEED_GENERATOR". + final long t = System.currentTimeMillis(); + final int h = System.identityHashCode(Runtime.getRuntime()); + final SplitMix64 rng = new SplitMix64(t ^ NumberFactory.makeLong(h, ~h)); + + final int blockCount = 1391; // Size of the state array of "Well44497b". + SEED_GENERATOR = new Well44497b(createIntArray(blockCount, rng)); + } + + /** + * Class contains only static methods. + */ + private SeedFactory() {} + + /** + * Creates a number for use as a seed. + * + * @return a random number. + */ + public static int createInt() { + return createInt(SEED_GENERATOR, System.identityHashCode(new Object())); + } + + /** + * Creates a number for use as a seed. + * + * @return a random number. + */ + public static long createLong() { + return createLong(SEED_GENERATOR, System.identityHashCode(new Object())); + } + + /** + * Creates an array of numbers for use as a seed. + * + * @param n Size of the array to create. + * @return an array of {@code n} random numbers. + */ + public static int[] createIntArray(int n) { + return createIntArray(n, SEED_GENERATOR, new Object()); + } + + /** + * Creates an array of numbers for use as a seed. + * + * @param n Size of the array to create. + * @return an array of {@code n} random numbers. + */ + public static long[] createLongArray(int n) { + return createLongArray(n, SEED_GENERATOR, new Object()); + } + + /** + * Simple filling procedure. + * It will + * <ol> + * <li> + * fill the beginning of {@code state} by copying + * {@code min(seed.length, state.length)} elements from + * {@code seed}, + * </li> + * <li> + * set all remaining elements of {@code state} with non-zero + * values (even if {@code seed.length < state.length}). + * </li> + * </ol> + * + * @param state State. Must be allocated. + * @param seed Seed. Cannot be null. + */ + public static void fillState(int[] state, + int[] seed) { + final int stateSize = state.length; + final int seedSize = seed.length; + System.arraycopy(seed, 0, state, 0, Math.min(seedSize, stateSize)); + + if (seedSize < stateSize) { + for (int i = seedSize; i < stateSize; i++) { + state[i] = (int) (scrambleWell(state[i - seed.length], i) & 0xffffffffL); + } + } + } + + /** + * Simple filling procedure. + * It will + * <ol> + * <li> + * fill the beginning of {@code state} by copying + * {@code min(seed.length, state.length)} elements from + * {@code seed}, + * </li> + * <li> + * set all remaining elements of {@code state} with non-zero + * values (even if {@code seed.length < state.length}). + * </li> + * </ol> + * + * @param state State. Must be allocated. + * @param seed Seed. Cannot be null. + */ + public static void fillState(long[] state, + long[] seed) { + final int stateSize = state.length; + final int seedSize = seed.length; + System.arraycopy(seed, 0, state, 0, Math.min(seedSize, stateSize)); + + if (seedSize < stateSize) { + for (int i = seedSize; i < stateSize; i++) { + state[i] = scrambleWell(state[i - seed.length], i); + } + } + } + + /** + * Creates an array of numbers for use as a seed. + * + * @param n Size of the array to create. + * @param source Source of randomness. + * @return an array of {@code n} random numbers drawn from the + * {@code source}. + */ + static long[] createLongArray(int n, + RandomIntSource source) { + return createLongArray(n, source, null); + } + + /** + * Creates an array of numbers for use as a seed. + * + * @param n Size of the array to create. + * @param source Source of randomness. + * @return an array of {@code n} random numbers drawn from the + * {@code source}. + */ + static int[] createIntArray(int n, + RandomLongSource source) { + return createIntArray(n, source, null); + } + + /** + * Creates an array of numbers for use as a seed. + * + * @param n Size of the array to create. + * @param source Source of randomness. + * @return an array of {@code n} random numbers drawn from the + * {@code source}. + */ + static int[] createIntArray(int n, + RandomIntSource source) { + return createIntArray(n, source, null); + } + + /** + * Creates an array of numbers for use as a seed. + * + * @param n Size of the array to create. + * @param source Source of randomness. + * @param h Arbitrary object whose {@link System#identityHashCode(Object) + * hash code} will be combined with the next number drawn from + * the {@code source}. + * @return an array of {@code n} random numbers. + */ + private static long[] createLongArray(int n, + RandomIntSource source, + Object h) { + final long[] array = new long[n]; + + final int hash = System.identityHashCode(h); + for (int i = 0; i < n; i++) { + array[i] = createLong(source, hash); + } + + return array; + } + + /** + * Creates an array of numbers for use as a seed. + * + * @param n Size of the array to create. + * @param source Source of randomness. + * @param h Arbitrary object whose {@link System#identityHashCode(Object) + * hash code} will be combined with the next number drawn from + * the {@code source}. + * @return an array of {@code n} random numbers. + */ + private static int[] createIntArray(int n, + RandomLongSource source, + Object h) { + final int[] array = new int[n]; + + final int hash = System.identityHashCode(h); + for (int i = 0; i < n; i += 2) { + final long v = createLong(source, hash); + + array[i] = NumberFactory.extractHi(v); + + if (i + 1 < n) { + array[i + 1] = NumberFactory.extractLo(v); + } + } + + return array; + } + + /** + * Creates an array of numbers for use as a seed. + * + * @param n Size of the array to create. + * @param source Source of randomness. + * @param h Arbitrary object whose {@link System#identityHashCode(Object) + * hash code} will be combined with the next number drawn from + * the {@code source}. + * @return an array of {@code n} random numbers. + */ + private static int[] createIntArray(int n, + RandomIntSource source, + Object h) { + final int[] array = new int[n]; + + final int hash = System.identityHashCode(h); + for (int i = 0; i < n; i++) { + array[i] = createInt(source, hash); + } + + return array; + } + + /** + * Creates a random number by performing an "xor" between the + * next value in the sequence of the {@code source} and the + * given {@code number}. + * + * @param source Source of randomness. + * @param number Arbitrary number. + * @return a random number. + */ + private static long createLong(RandomLongSource source, + int number) { + synchronized (source) { + return source.next() ^ NumberFactory.makeLong(number, number); + } + } + + /** + * Creates a random number by performing an "xor" between the + * the next value in the sequence of the {@code source} and the + * given {@code number}. + * + * @param source Source of randomness. + * @param number Arbitrary number. + * @return a random number. + */ + private static long createLong(RandomIntSource source, + int number) { + synchronized (source) { + return NumberFactory.makeLong(source.next() ^ number, + source.next() ^ number); + } + } + + /** + * Creates a random number by performing an "xor" between the + * next value in the sequence of the {@code source} and the + * given {@code number}. + * + * @param source Source of randomness. + * @param number Arbitrary number. + * @return a random number. + */ + private static int createInt(RandomIntSource source, + int number) { + synchronized (source) { + return source.next() ^ number; + } + } + + /** + * Transformation used to scramble the initial state of + * a generator. + * + * @param n Seed element. + * @param mult Multiplier. + * @param shift Shift. + * @param add Offset. + * @return the transformed seed element. + */ + private static long scramble(long n, + long mult, + int shift, + int add) { + // Code inspired from "AbstractWell" class. + return mult * (n ^ (n >> shift)) + add; + } + + /** + * Transformation used to scramble the initial state of + * a generator. + * + * @param n Seed element. + * @param add Offset. + * @return the transformed seed element. + * @see #scramble(long,long,int,int) + */ + private static long scrambleWell(long n, + int add) { + // Code inspired from "AbstractWell" class. + return scramble(n, 1812433253L, 30, add); + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/42530e25/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/package-info.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/package-info.java b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/package-info.java new file mode 100644 index 0000000..662dd2e --- /dev/null +++ b/commons-rng-core/src/main/java/org/apache/commons/rng/internal/util/package-info.java @@ -0,0 +1,22 @@ +/* + * 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. + */ + +/** + * Utilities for seed conversion. + */ + +package org.apache.commons.rng.internal.util;