http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source32/MersenneTwister.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source32/MersenneTwister.java
 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/MersenneTwister.java
new file mode 100644
index 0000000..7ae5fd8
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/MersenneTwister.java
@@ -0,0 +1,230 @@
+/*
+ * 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.math4.rng.internal.source32;
+
+import java.util.Arrays;
+import org.apache.commons.math4.exception.InsufficientDataException;
+import org.apache.commons.math4.rng.internal.util.NumberFactory;
+
+/**
+ * This class implements a powerful pseudo-random number generator
+ * developed by Makoto Matsumoto and Takuji Nishimura during
+ * 1996-1997.
+ *
+ * <p>
+ * This generator features an extremely long period
+ * (2<sup>19937</sup>-1) and 623-dimensional equidistribution up to
+ * 32 bits accuracy.  The home page for this generator is located at
+ * <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html";>
+ * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html</a>.
+ * </p>
+ *
+ * <p>
+ * This generator is described in a paper by Makoto Matsumoto and
+ * Takuji Nishimura in 1998:
+ * <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/mt.pdf";>
+ * Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random
+ * Number Generator</a>,
+ * ACM Transactions on Modeling and Computer Simulation, Vol. 8, No. 1,
+ * January 1998, pp 3--30
+ * </p>
+ *
+ * <p>
+ * This class is mainly a Java port of the
+ * <a 
href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html";>
+ * 2002-01-26 version of the generator</a> written in C by Makoto Matsumoto
+ * and Takuji Nishimura. Here is their original copyright:
+ * </p>
+ *
+ * <table border="0" width="80%" cellpadding="10" align="center" 
bgcolor="#E0E0E0">
+ * <tr><td>Copyright (C) 1997 - 2002, 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>
+ *
+ * @since 4.0
+ */
+public class MersenneTwister extends IntProvider {
+    /** Mask 32 most significant bits. */
+    private static final long INT_MASK_LONG = 0xffffffffL;
+    /** Most significant w-r bits. */
+    private static final long UPPER_MASK_LONG = 0x80000000L;
+    /** Least significant r bits */
+    private static final long LOWER_MASK_LONG = 0x7fffffffL;
+    /** Most significant w-r bits. */
+    private static final int UPPER_MASK = 0x80000000;
+    /** Least significant r bits */
+    private static final int LOWER_MASK = 0x7fffffff;
+    /** Size of the bytes pool. */
+    private static final int N = 624;
+    /** Period second parameter. */
+    private static final int M = 397;
+    /** X * MATRIX_A for X = {0, 1}. */
+    private static final int[] MAG01 = { 0x0, 0x9908b0df };
+    /** Bytes pool. */
+    private int[] mt = new int[N];
+    /** Current index in the bytes pool. */
+    private int mti;
+
+    /**
+     * Creates a new random number generator.
+     *
+     * @param seed Initial seed.
+     */
+    public MersenneTwister(int[] seed) {
+        setSeedInternal(seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected byte[] getStateInternal() {
+        final int[] s = Arrays.copyOf(mt, N + 1);
+        s[N] = mti;
+
+        return NumberFactory.makeByteArray(s);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void setStateInternal(byte[] s) {
+        if (s.length != (N + 1) * 4) {
+            throw new InsufficientDataException();
+        }
+
+        final int[] tmp = NumberFactory.makeIntArray(s);
+
+        System.arraycopy(tmp, 0, mt, 0, N);
+        mti = tmp[N];
+    }
+
+    /**
+     * Reinitializes the generator as if just built with the given seed.
+     *
+     * @param seed Initial seed.
+     */
+    private void setSeedInternal(int[] seed) {
+        initState(19650218);
+        int i = 1;
+        int j = 0;
+
+        for (int k = Math.max(N, seed.length); k != 0; k--) {
+            final long l0 = (mt[i] & LOWER_MASK_LONG)   | ((mt[i]   < 0) ? 
UPPER_MASK_LONG : 0);
+            final long l1 = (mt[i-1] & LOWER_MASK_LONG) | ((mt[i-1] < 0) ? 
UPPER_MASK_LONG : 0);
+            final long l  = (l0 ^ ((l1 ^ (l1 >> 30)) * 1664525l)) + seed[j] + 
j; // non linear
+            mt[i]   = (int) (l & INT_MASK_LONG);
+            i++; j++;
+            if (i >= N) {
+                mt[0] = mt[N - 1];
+                i = 1;
+            }
+            if (j >= seed.length) {
+                j = 0;
+            }
+        }
+
+        for (int k = N - 1; k != 0; k--) {
+            final long l0 = (mt[i] & LOWER_MASK_LONG)   | ((mt[i]   < 0) ? 
UPPER_MASK_LONG : 0);
+            final long l1 = (mt[i-1] & LOWER_MASK_LONG) | ((mt[i-1] < 0) ? 
UPPER_MASK_LONG : 0);
+            final long l  = (l0 ^ ((l1 ^ (l1 >> 30)) * 1566083941l)) - i; // 
non linear
+            mt[i]   = (int) (l & INT_MASK_LONG);
+            i++;
+            if (i >= N) {
+                mt[0] = mt[N - 1];
+                i = 1;
+            }
+        }
+
+        mt[0] = UPPER_MASK; // MSB is 1; assuring non-zero initial array
+    }
+
+    /**
+     * Initialize the internal state of this instance.
+     *
+     * @param seed Seed.
+     */
+    private void initState(int seed) {
+        long longMT = seed & INT_MASK_LONG;
+        mt[0]= (int) longMT;
+        for (mti = 1; mti < N; ++mti) {
+            longMT = (1812433253L * (longMT ^ (longMT >> 30)) + mti) & 
INT_MASK_LONG;
+            mt[mti]= (int) longMT;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int next() {
+        int y;
+
+        if (mti >= N) { // Generate N words at one time.
+            int mtNext = mt[0];
+            for (int k = 0; k < N - M; ++k) {
+                int mtCurr = mtNext;
+                mtNext = mt[k + 1];
+                y = (mtCurr & UPPER_MASK) | (mtNext & LOWER_MASK);
+                mt[k] = mt[k + M] ^ (y >>> 1) ^ MAG01[y & 1];
+            }
+            for (int k = N - M; k < N - 1; ++k) {
+                int mtCurr = mtNext;
+                mtNext = mt[k + 1];
+                y = (mtCurr & UPPER_MASK) | (mtNext & LOWER_MASK);
+                mt[k] = mt[k + (M - N)] ^ (y >>> 1) ^ MAG01[y & 1];
+            }
+            y = (mtNext & UPPER_MASK) | (mt[0] & LOWER_MASK);
+            mt[N - 1] = mt[M - 1] ^ (y >>> 1) ^ MAG01[y & 1];
+
+            mti = 0;
+        }
+
+        y = mt[mti++];
+
+        // Tempering.
+        y ^=  y >>> 11;
+        y ^= (y << 7) & 0x9d2c5680;
+        y ^= (y << 15) & 0xefc60000;
+        y ^=  y >>> 18;
+
+        return y;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source32/RandomIntSource.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source32/RandomIntSource.java
 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/RandomIntSource.java
new file mode 100644
index 0000000..88f420c
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/RandomIntSource.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.math4.rng.internal.source32;
+
+/**
+ * Source of randomness that generate values of type {@code int}.
+ *
+ * @since 4.0
+ */
+public interface RandomIntSource {
+    /**
+     * @return the next random value.
+     */
+    int next();
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source32/Well1024a.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source32/Well1024a.java 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well1024a.java
new file mode 100644
index 0000000..86c84c3
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well1024a.java
@@ -0,0 +1,78 @@
+/*
+ * 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.math4.rng.internal.source32;
+
+/**
+ * This class implements the WELL1024a pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+ * <p>
+ * This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto
+ * <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf";>
+ * Improved Long-Period Generators Based on Linear Recurrences Modulo 2</a>
+ * ACM Transactions on Mathematical Software, 32, 1 (2006).
+ * The errata for the paper are in
+ * <a 
href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt";>wellrng-errata.txt</a>.
+ * </p>
+ *
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html";>WELL 
Random number generator</a>
+ * @since 4.0
+ */
+public class Well1024a extends AbstractWell {
+    /** Number of bits in the pool. */
+    private static final int K = 1024;
+    /** First parameter of the algorithm. */
+    private static final int M1 = 3;
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 24;
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 10;
+    /** The indirection index table. */
+    private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
+
+    /**
+     * Creates a new random number generator.
+     *
+     * @param seed Initial seed.
+     */
+    public Well1024a(int[] seed) {
+        super(K, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int next() {
+        final int indexRm1 = TABLE.getIndexPred(index);
+
+        final int v0 = v[index];
+        final int vM1 = v[TABLE.getIndexM1(index)];
+        final int vM2 = v[TABLE.getIndexM2(index)];
+        final int vM3 = v[TABLE.getIndexM3(index)];
+
+        final int z0 = v[indexRm1];
+        final int z1 = v0 ^ (vM1 ^ (vM1 >>> 8));
+        final int z2 = (vM2 ^ (vM2 << 19)) ^ (vM3 ^ (vM3 << 14));
+        final int z3 = z1 ^ z2;
+        final int z4 = (z0 ^ (z0 << 11)) ^ (z1 ^ (z1 << 7)) ^ (z2 ^ (z2 << 
13));
+
+        v[index] = z3;
+        v[indexRm1] = z4;
+        index = indexRm1;
+
+        return z4;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source32/Well19937a.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source32/Well19937a.java 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well19937a.java
new file mode 100644
index 0000000..7f83ddf
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well19937a.java
@@ -0,0 +1,80 @@
+/*
+ * 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.math4.rng.internal.source32;
+
+/**
+ * This class implements the WELL19937a pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+ * <p>
+ * This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto
+ * <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf";>
+ * Improved Long-Period Generators Based on Linear Recurrences Modulo 2</a>
+ * ACM Transactions on Mathematical Software, 32, 1 (2006).
+ * The errata for the paper are in
+ * <a 
href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt";>wellrng-errata.txt</a>.
+ * </p>
+ *
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html";>WELL 
Random number generator</a>
+ * @since 4.0
+ */
+public class Well19937a extends AbstractWell {
+    /** Number of bits in the pool. */
+    private static final int K = 19937;
+    /** First parameter of the algorithm. */
+    private static final int M1 = 70;
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 179;
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 449;
+    /** The indirection index table. */
+    private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
+
+    /**
+     * Creates a new random number generator.
+     *
+     * @param seed Initial seed.
+     */
+    public Well19937a(int[] seed) {
+        super(K, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int next() {
+        final int indexRm1 = TABLE.getIndexPred(index);
+        final int indexRm2 = TABLE.getIndexPred2(index);
+
+        final int v0 = v[index];
+        final int vM1 = v[TABLE.getIndexM1(index)];
+        final int vM2 = v[TABLE.getIndexM2(index)];
+        final int vM3 = v[TABLE.getIndexM3(index)];
+
+        final int z0 = (0x80000000 & v[indexRm1]) ^ (0x7FFFFFFF & v[indexRm2]);
+        final int z1 = (v0 ^ (v0 << 25)) ^ (vM1 ^ (vM1 >>> 27));
+        final int z2 = (vM2 >>> 9) ^ (vM3 ^ (vM3 >>> 1));
+        final int z3 = z1 ^ z2;
+        final int z4 = z0 ^ (z1 ^ (z1 << 9)) ^ (z2 ^ (z2 << 21)) ^ (z3 ^ (z3 
>>> 21));
+
+        v[index] = z3;
+        v[indexRm1] = z4;
+        v[indexRm2] &= 0x80000000;
+        index = indexRm1;
+
+        return z4;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source32/Well19937c.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source32/Well19937c.java 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well19937c.java
new file mode 100644
index 0000000..25b9d03
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well19937c.java
@@ -0,0 +1,85 @@
+/*
+ * 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.math4.rng.internal.source32;
+
+/**
+ * This class implements the WELL19937c pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+ * <p>
+ * This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto
+ * <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf";>
+ * Improved Long-Period Generators Based on Linear Recurrences Modulo 2</a>
+ * ACM Transactions on Mathematical Software, 32, 1 (2006).
+ * The errata for the paper are in
+ * <a 
href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt";>wellrng-errata.txt</a>.
+ * </p>
+ *
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html";>WELL 
Random number generator</a>
+ * @since 2.2
+ */
+public class Well19937c extends AbstractWell {
+    /** Number of bits in the pool. */
+    private static final int K = 19937;
+    /** First parameter of the algorithm. */
+    private static final int M1 = 70;
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 179;
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 449;
+    /** The indirection index table. */
+    private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
+
+    /**
+     * Creates a new random number generator.
+     *
+     * @param seed Initial seed.
+     */
+    public Well19937c(int[] seed) {
+        super(K, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int next() {
+        final int indexRm1 = TABLE.getIndexPred(index);
+        final int indexRm2 = TABLE.getIndexPred2(index);
+
+        final int v0 = v[index];
+        final int vM1 = v[TABLE.getIndexM1(index)];
+        final int vM2 = v[TABLE.getIndexM2(index)];
+        final int vM3 = v[TABLE.getIndexM3(index)];
+
+        final int z0 = (0x80000000 & v[indexRm1]) ^ (0x7FFFFFFF & v[indexRm2]);
+        final int z1 = (v0 ^ (v0 << 25)) ^ (vM1 ^ (vM1 >>> 27));
+        final int z2 = (vM2 >>> 9) ^ (vM3 ^ (vM3 >>> 1));
+        final int z3 = z1 ^ z2;
+        int z4 = z0 ^ (z1 ^ (z1 << 9)) ^ (z2 ^ (z2 << 21)) ^ (z3 ^ (z3 >>> 
21));
+
+        v[index] = z3;
+        v[indexRm1] = z4;
+        v[indexRm2] &= 0x80000000;
+        index = indexRm1;
+
+        // add Matsumoto-Kurita tempering
+        // to get a maximally-equidistributed generator
+        z4 ^= (z4 <<  7) & 0xe46e1700;
+        z4 ^= (z4 << 15) & 0x9b868000;
+
+        return z4;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source32/Well44497a.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source32/Well44497a.java 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well44497a.java
new file mode 100644
index 0000000..8b72b83
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well44497a.java
@@ -0,0 +1,83 @@
+/*
+ * 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.math4.rng.internal.source32;
+
+/**
+ * This class implements the WELL44497a pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+ * <p>
+ * This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto
+ * <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf";>
+ * Improved Long-Period Generators Based on Linear Recurrences Modulo 2</a>
+ * ACM Transactions on Mathematical Software, 32, 1 (2006).
+ * The errata for the paper are in
+ * <a 
href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt";>wellrng-errata.txt</a>.
+ * </p>
+ *
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html";>WELL 
Random number generator</a>
+ * @since 4.0
+ */
+public class Well44497a extends AbstractWell {
+    /** Number of bits in the pool. */
+    private static final int K = 44497;
+    /** First parameter of the algorithm. */
+    private static final int M1 = 23;
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 481;
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 229;
+    /** The indirection index table. */
+    private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
+
+    /**
+     * Creates a new random number generator.
+     *
+     * @param seed Initial seed.
+     */
+    public Well44497a(int[] seed) {
+        super(K, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int next() {
+        final int indexRm1 = TABLE.getIndexPred(index);
+        final int indexRm2 = TABLE.getIndexPred2(index);
+
+        final int v0 = v[index];
+        final int vM1 = v[TABLE.getIndexM1(index)];
+        final int vM2 = v[TABLE.getIndexM2(index)];
+        final int vM3 = v[TABLE.getIndexM3(index)];
+
+        // the values below include the errata of the original article
+        final int z0 = (0xFFFF8000 & v[indexRm1]) ^ (0x00007FFF & v[indexRm2]);
+        final int z1 = (v0 ^ (v0 << 24)) ^ (vM1 ^ (vM1 >>> 30));
+        final int z2 = (vM2 ^ (vM2 << 10)) ^ (vM3 << 26);
+        final int z3 = z1 ^ z2;
+        final int z2Prime  = ((z2 << 9) ^ (z2 >>> 23)) & 0xfbffffff;
+        final int z2Second = ((z2 & 0x00020000) != 0) ? (z2Prime ^ 0xb729fcec) 
: z2Prime;
+        final int z4 = z0 ^ (z1 ^ (z1 >>> 20)) ^ z2Second ^ z3;
+
+        v[index] = z3;
+        v[indexRm1] = z4;
+        v[indexRm2] &= 0xFFFF8000;
+        index = indexRm1;
+
+        return z4;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source32/Well44497b.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source32/Well44497b.java 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well44497b.java
new file mode 100644
index 0000000..5300aba
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well44497b.java
@@ -0,0 +1,90 @@
+/*
+ * 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.math4.rng.internal.source32;
+
+/**
+ * This class implements the WELL44497b pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+ * <p>
+ * This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto
+ * <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf";>
+ * Improved Long-Period Generators Based on Linear Recurrences Modulo 2</a>
+ * ACM Transactions on Mathematical Software, 32, 1 (2006).
+ * The errata for the paper are in
+ * <a 
href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt";>wellrng-errata.txt</a>.
+ * </p>
+ *
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html";>WELL 
Random number generator</a>
+ * @since 4.0
+ */
+public class Well44497b extends AbstractWell {
+    /** Number of bits in the pool. */
+    private static final int K = 44497;
+    /** First parameter of the algorithm. */
+    private static final int M1 = 23;
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 481;
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 229;
+    /** The indirection index table. */
+    private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
+
+    /**
+     * Creates a new random number generator.
+     *
+     * @param seed Initial seed.
+     */
+    public Well44497b(int[] seed) {
+        super(K, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int next() {
+        // compute raw value given by WELL44497a generator
+        // which is NOT maximally-equidistributed
+        final int indexRm1 = TABLE.getIndexPred(index);
+        final int indexRm2 = TABLE.getIndexPred2(index);
+
+        final int v0 = v[index];
+        final int vM1 = v[TABLE.getIndexM1(index)];
+        final int vM2 = v[TABLE.getIndexM2(index)];
+        final int vM3 = v[TABLE.getIndexM3(index)];
+
+        // the values below include the errata of the original article
+        final int z0 = (0xFFFF8000 & v[indexRm1]) ^ (0x00007FFF & v[indexRm2]);
+        final int z1 = (v0 ^ (v0 << 24))  ^ (vM1 ^ (vM1 >>> 30));
+        final int z2 = (vM2 ^ (vM2 << 10)) ^ (vM3 << 26);
+        final int z3 = z1 ^ z2;
+        final int z2Prime = ((z2 << 9) ^ (z2 >>> 23)) & 0xfbffffff;
+        final int z2Second = ((z2 & 0x00020000) != 0) ? (z2Prime ^ 0xb729fcec) 
: z2Prime;
+        int z4 = z0 ^ (z1 ^ (z1 >>> 20)) ^ z2Second ^ z3;
+
+        v[index] = z3;
+        v[indexRm1] = z4;
+        v[indexRm2] &= 0xFFFF8000;
+        index = indexRm1;
+
+        // add Matsumoto-Kurita tempering
+        // to get a maximally-equidistributed generator
+        z4 ^= (z4 <<  7) & 0x93dd1400;
+        z4 ^= (z4 << 15) & 0xfa118000;
+
+        return z4;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source32/Well512a.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source32/Well512a.java 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well512a.java
new file mode 100644
index 0000000..1faf571
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/rng/internal/source32/Well512a.java
@@ -0,0 +1,78 @@
+/*
+ * 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.math4.rng.internal.source32;
+
+/**
+ * This class implements the WELL512a pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+ * <p>
+ * This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto
+ * <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf";>
+ * Improved Long-Period Generators Based on Linear Recurrences Modulo 2</a>
+ * ACM Transactions on Mathematical Software, 32, 1 (2006).
+ * The errata for the paper are in
+ * <a 
href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt";>wellrng-errata.txt</a>.
+ * </p>
+ *
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html";>WELL 
Random number generator</a>
+ * @since 4.0
+ */
+public class Well512a extends AbstractWell {
+    /** Number of bits in the pool. */
+    private static final int K = 512;
+    /** First parameter of the algorithm. */
+    private static final int M1 = 13;
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 9;
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 5;
+    /** The indirection index table. */
+    private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
+
+    /**
+     * Creates a new random number generator.
+     *
+     * @param seed Initial seed.
+     */
+    public Well512a(int[] seed) {
+        super(K, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int next() {
+        final int indexRm1 = TABLE.getIndexPred(index);
+
+        final int vi = v[index];
+        final int vi1 = v[TABLE.getIndexM1(index)];
+        final int vi2 = v[TABLE.getIndexM2(index)];
+        final int z0 = v[indexRm1];
+
+        // the values below include the errata of the original article
+        final int z1 = (vi ^ (vi << 16)) ^ (vi1 ^ (vi1 << 15));
+        final int z2 = vi2 ^ (vi2 >>> 11);
+        final int z3 = z1 ^ z2;
+        final int z4 = (z0 ^ (z0 << 2)) ^ (z1 ^ (z1 << 18)) ^ (z2 << 28) ^ (z3 
^ ((z3 << 5) & 0xda442d24));
+
+        v[index] = z3;
+        v[indexRm1] = z4;
+        index = indexRm1;
+
+        return z4;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source32/package-info.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source32/package-info.java
 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/package-info.java
new file mode 100644
index 0000000..bb7d2e2
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source32/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 int}-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.math4.rng.internal.source32.IntProvider}
+ *  </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.math4.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.math4.rng.RandomSource
+ *   factory methods}.
+ *  </li>
+ * </ul>
+ */
+
+package org.apache.commons.math4.rng.internal.source32;

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source64/LongProvider.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source64/LongProvider.java
 
b/src/main/java/org/apache/commons/math4/rng/internal/source64/LongProvider.java
new file mode 100644
index 0000000..3e73f05
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source64/LongProvider.java
@@ -0,0 +1,141 @@
+/*
+ * 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.math4.rng.internal.source64;
+
+import org.apache.commons.math4.exception.OutOfRangeException;
+import org.apache.commons.math4.rng.internal.util.NumberFactory;
+import org.apache.commons.math4.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) {
+        if (start < 0 ||
+            start >= bytes.length) {
+            throw new OutOfRangeException(start, 0, bytes.length);
+        }
+        if (len < 0 ||
+            len > bytes.length - start) {
+            throw new OutOfRangeException(len, 0, bytes.length - start);
+        }
+
+        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-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source64/MersenneTwister64.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source64/MersenneTwister64.java
 
b/src/main/java/org/apache/commons/math4/rng/internal/source64/MersenneTwister64.java
new file mode 100644
index 0000000..0280842
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source64/MersenneTwister64.java
@@ -0,0 +1,201 @@
+/*
+ * 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.math4.rng.internal.source64;
+
+import java.util.Arrays;
+import org.apache.commons.math4.exception.InsufficientDataException;
+import org.apache.commons.math4.rng.internal.util.NumberFactory;
+
+/**
+ * This class provides the 64-bits version of the originally 32-bits
+ * {@link org.apache.commons.math4.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" align="center" 
bgcolor="#E0E0E0">
+ * <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>
+ *
+ * @since 4.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) {
+        if (s.length != (NN + 1) * 8) {
+            throw new InsufficientDataException();
+        }
+
+        final long[] tmp = NumberFactory.makeLongArray(s);
+
+        System.arraycopy(tmp, 0, mt, 0, NN);
+        mti = (int) tmp[NN];
+    }
+
+    /**
+     * Reinitializes the generator as if just built with the given seed.
+     *
+     * @param seed Initial seed.
+     */
+    private void setSeedInternal(long[] seed) {
+        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-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source64/RandomLongSource.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source64/RandomLongSource.java
 
b/src/main/java/org/apache/commons/math4/rng/internal/source64/RandomLongSource.java
new file mode 100644
index 0000000..0daa068
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/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.math4.rng.internal.source64;
+
+/**
+ * Source of randomness that generate values of type {@code long}.
+ *
+ * @since 4.0
+ */
+public interface RandomLongSource {
+    /**
+     * @return the next random value.
+     */
+    long next();
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source64/SplitMix64.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source64/SplitMix64.java 
b/src/main/java/org/apache/commons/math4/rng/internal/source64/SplitMix64.java
new file mode 100644
index 0000000..086bd03
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source64/SplitMix64.java
@@ -0,0 +1,78 @@
+/*
+ * 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.math4.rng.internal.source64;
+
+import org.apache.commons.math4.exception.InsufficientDataException;
+import org.apache.commons.math4.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 4.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) {
+        if (s.length != 8) {
+            throw new InsufficientDataException();
+        }
+
+        state = NumberFactory.makeLong(s);
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source64/TwoCmres.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source64/TwoCmres.java 
b/src/main/java/org/apache/commons/math4/rng/internal/source64/TwoCmres.java
new file mode 100644
index 0000000..d6fdcd6
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/rng/internal/source64/TwoCmres.java
@@ -0,0 +1,310 @@
+/*
+ * 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.math4.rng.internal.source64;
+
+import java.util.List;
+import java.util.ArrayList;
+import org.apache.commons.math4.exception.MathInternalError;
+import org.apache.commons.math4.exception.OutOfRangeException;
+import org.apache.commons.math4.exception.InsufficientDataException;
+import org.apache.commons.math4.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:
+ *  <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>
+ * </p>
+ *
+ * @since 4.0
+ */
+public class TwoCmres extends LongProvider {
+    /** 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 InsufficientDataException if {@code x == y}.
+     */
+    private TwoCmres(int seed,
+                     Cmres x,
+                     Cmres y) {
+        if (x == y) {
+            throw new InsufficientDataException();
+        }
+        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 InsufficientDataException if {@code i == j}.
+     * @throws OutOfRangeException if {@code i < 0} or
+     * {@code i >= numberOfSubcycleGenerators()}.
+     * @throws OutOfRangeException 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) {
+        if (s.length != 16) {
+            throw new InsufficientDataException();
+        }
+
+        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 MathInternalError();
+        }
+
+        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 OutOfRangeException(index, 0, TABLE.size());
+                }
+
+                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 MathInternalError();
+                    }
+                }
+
+                TABLE.add(new Cmres(multiply, rotate, start));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source64/XorShift1024Star.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source64/XorShift1024Star.java
 
b/src/main/java/org/apache/commons/math4/rng/internal/source64/XorShift1024Star.java
new file mode 100644
index 0000000..c6bcfaa
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/source64/XorShift1024Star.java
@@ -0,0 +1,108 @@
+/*
+ * 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.math4.rng.internal.source64;
+
+import java.util.Arrays;
+import org.apache.commons.math4.exception.InsufficientDataException;
+import org.apache.commons.math4.rng.internal.util.NumberFactory;
+
+/**
+ * A fast RNG.
+ *
+ * @see <a href="http://xorshift.di.unimi.it/xorshift1024star.c";>
+ * Original source code</a>
+ *
+ * @since 4.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) {
+        if (s.length != (SEED_SIZE + 1) * 8) {
+            throw new InsufficientDataException();
+        }
+
+        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").
+        // Seeding procedure is not part of the reference code.
+
+        System.arraycopy(seed, 0, state, 0, Math.min(seed.length, 
state.length));
+
+        if (seed.length < SEED_SIZE) {
+            for (int i = seed.length; i < SEED_SIZE; i++) {
+                state[i] = 26021969L * i;
+            }
+            for (int i = SEED_SIZE - 1; i > seed.length; i--) {
+                state[i] ^= state[SEED_SIZE - i - 1];
+            }
+
+            state[seed.length] = 0x8000000000000000L; // Ensuring non-zero 
initial array.
+        }
+
+        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-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/source64/package-info.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/source64/package-info.java
 
b/src/main/java/org/apache/commons/math4/rng/internal/source64/package-info.java
new file mode 100644
index 0000000..8afab2c
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/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.math4.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.math4.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.math4.rng.RandomSource
+ *   factory methods}.
+ *  </li>
+ * </ul>
+ */
+
+package org.apache.commons.math4.rng.internal.source64;

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/util/Int2Long.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/util/Int2Long.java 
b/src/main/java/org/apache/commons/math4/rng/internal/util/Int2Long.java
new file mode 100644
index 0000000..d423c08
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/rng/internal/util/Int2Long.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.math4.rng.internal.util;
+
+/**
+ * Converts a {@code Integer} to an {@code Long}.
+ *
+ * @since 4.0
+ */
+public class Int2Long implements SeedConverter<Integer, Long> {
+    /** {@inheritDoc} */
+    @Override
+    public Long convert(Integer seed) {
+        final int s = seed;
+        return NumberFactory.makeLong(s, ~s);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return getClass().getSimpleName();
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/util/IntArray2Int.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/util/IntArray2Int.java 
b/src/main/java/org/apache/commons/math4/rng/internal/util/IntArray2Int.java
new file mode 100644
index 0000000..030895d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/rng/internal/util/IntArray2Int.java
@@ -0,0 +1,41 @@
+/*
+ * 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.math4.rng.internal.util;
+
+/**
+ * Creates a single value by "xor" of all the values in the input array.
+ *
+ * @since 4.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;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return getClass().getSimpleName();
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/util/IntArray2LongArray.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/util/IntArray2LongArray.java
 
b/src/main/java/org/apache/commons/math4/rng/internal/util/IntArray2LongArray.java
new file mode 100644
index 0000000..399de7f
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/util/IntArray2LongArray.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.math4.rng.internal.util;
+
+/**
+ * Creates a {@code long[]} from an {@code int[]}.
+ *
+ * @since 4.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;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return getClass().getSimpleName();
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/util/Long2Int.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/util/Long2Int.java 
b/src/main/java/org/apache/commons/math4/rng/internal/util/Long2Int.java
new file mode 100644
index 0000000..638b173
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/rng/internal/util/Long2Int.java
@@ -0,0 +1,36 @@
+/*
+ * 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.math4.rng.internal.util;
+
+/**
+ * Converts a {@code Long} to an {@code Integer}.
+ *
+ * @since 4.0
+ */
+public class Long2Int implements SeedConverter<Long, Integer> {
+    /** {@inheritDoc} */
+    @Override
+    public Integer convert(Long seed) {
+        return NumberFactory.makeInt(seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return getClass().getSimpleName();
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/util/Long2IntArray.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/util/Long2IntArray.java 
b/src/main/java/org/apache/commons/math4/rng/internal/util/Long2IntArray.java
new file mode 100644
index 0000000..84e5016
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/util/Long2IntArray.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.math4.rng.internal.util;
+
+import org.apache.commons.math4.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 4.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));
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "(size=" + size + ")";
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/util/Long2LongArray.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/util/Long2LongArray.java 
b/src/main/java/org/apache/commons/math4/rng/internal/util/Long2LongArray.java
new file mode 100644
index 0000000..9d8b700
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/util/Long2LongArray.java
@@ -0,0 +1,56 @@
+/*
+ * 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.math4.rng.internal.util;
+
+import org.apache.commons.math4.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 4.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;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "(size: " + size + ")";
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/util/LongArray2IntArray.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/util/LongArray2IntArray.java
 
b/src/main/java/org/apache/commons/math4/rng/internal/util/LongArray2IntArray.java
new file mode 100644
index 0000000..67b2ba8
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/util/LongArray2IntArray.java
@@ -0,0 +1,43 @@
+/*
+ * 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.math4.rng.internal.util;
+
+/**
+ * Creates an {@code int[]} from a {@code long[]}.
+ *
+ * @since 4.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;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return getClass().getSimpleName();
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/util/LongArray2Long.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/util/LongArray2Long.java 
b/src/main/java/org/apache/commons/math4/rng/internal/util/LongArray2Long.java
new file mode 100644
index 0000000..4556aaf
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/math4/rng/internal/util/LongArray2Long.java
@@ -0,0 +1,41 @@
+/*
+ * 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.math4.rng.internal.util;
+
+/**
+ * Creates a single value by "xor" of all the values in the input array.
+ *
+ * @since 4.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;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return getClass().getSimpleName();
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-math/blob/6ddf4769/src/main/java/org/apache/commons/math4/rng/internal/util/LongMixInt.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/rng/internal/util/LongMixInt.java 
b/src/main/java/org/apache/commons/math4/rng/internal/util/LongMixInt.java
new file mode 100644
index 0000000..e30a072
--- /dev/null
+++ b/src/main/java/org/apache/commons/math4/rng/internal/util/LongMixInt.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.math4.rng.internal.util;
+
+import org.apache.commons.math4.rng.internal.source64.SplitMix64;
+
+/**
+ * Uses a {@code long} value to seed a {@link SplitMix64} RNG and
+ * create an {@code int[]} with the requested number of random
+ * values.
+ *
+ * @since 4.0
+ */
+public class LongMixInt implements SeedConverter<Long, int[]> {
+    /** Size of the output array. */
+    private final int size;
+
+    /**
+     * @param size Size of the output array.
+     */
+    public LongMixInt(int size) {
+        this.size = size;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int[] convert(Long seed) {
+        return SeedFactory.createIntArray(size, new SplitMix64(seed));
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "(size=" + size + ")";
+    }
+}

Reply via email to