Minor changes. Variables name. Code slightly reorganized.
Project: http://git-wip-us.apache.org/repos/asf/commons-rng/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-rng/commit/fe6ec472 Tree: http://git-wip-us.apache.org/repos/asf/commons-rng/tree/fe6ec472 Diff: http://git-wip-us.apache.org/repos/asf/commons-rng/diff/fe6ec472 Branch: refs/heads/master Commit: fe6ec4721d16b47a07085e7aa4a7519e79bf59ff Parents: b5aac70 Author: Gilles <[email protected]> Authored: Sat Sep 10 15:21:23 2016 +0200 Committer: Gilles <[email protected]> Committed: Sat Sep 10 15:21:23 2016 +0200 ---------------------------------------------------------------------- .../rng/internal/source32/MersenneTwister.java | 74 ++++++++++++-------- 1 file changed, 43 insertions(+), 31 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-rng/blob/fe6ec472/src/main/java/org/apache/commons/rng/internal/source32/MersenneTwister.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/rng/internal/source32/MersenneTwister.java b/src/main/java/org/apache/commons/rng/internal/source32/MersenneTwister.java index 9f7f432..e53ac4e 100644 --- a/src/main/java/org/apache/commons/rng/internal/source32/MersenneTwister.java +++ b/src/main/java/org/apache/commons/rng/internal/source32/MersenneTwister.java @@ -140,23 +140,49 @@ public class MersenneTwister extends IntProvider { * @param seed Initial seed. */ private void setSeedInternal(int[] seed) { + fillStateMersenneTwister(mt, seed); + + // Initial index. + mti = N; + } + + /** + * Utility for wholly filling a {@code state} array with non-zero + * bytes, even if the {@code seed} has a smaller size. + * The procedure is the one defined by the standard implementation + * of the algorithm. + * + * @param state State to be filled (must be allocated). + * @param seed Seed (cannot be {@code null}). + */ + private static void fillStateMersenneTwister(int[] state, + int[] seed) { if (seed.length == 0) { // Accept empty seed. seed = new int[1]; } - initState(19650218); + final int stateSize = state.length; + + long mt = 19650218 & INT_MASK_LONG; + state[0] = (int) mt; + for (int i = 1; i < stateSize; i++) { + mt = (1812433253L * (mt ^ (mt >> 30)) + i) & INT_MASK_LONG; + state[i] = (int) mt; + } + 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]; + for (int k = Math.max(stateSize, seed.length); k > 0; k--) { + final long a = (state[i] & LOWER_MASK_LONG) | ((state[i] < 0) ? UPPER_MASK_LONG : 0); + final long b = (state[i - 1] & LOWER_MASK_LONG) | ((state[i - 1] < 0) ? UPPER_MASK_LONG : 0); + final long c = (a ^ ((b ^ (b >> 30)) * 1664525L)) + seed[j] + j; // Non linear. + state[i] = (int) (c & INT_MASK_LONG); + i++; + j++; + if (i >= stateSize) { + state[0] = state[stateSize - 1]; i = 1; } if (j >= seed.length) { @@ -164,33 +190,19 @@ public class MersenneTwister extends IntProvider { } } - 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); + for (int k = stateSize - 1; k > 0; k--) { + final long a = (state[i] & LOWER_MASK_LONG) | ((state[i] < 0) ? UPPER_MASK_LONG : 0); + final long b = (state[i - 1] & LOWER_MASK_LONG) | ((state[i - 1] < 0) ? UPPER_MASK_LONG : 0); + final long c = (a ^ ((b ^ (b >> 30)) * 1566083941L)) - i; // Non linear. + state[i] = (int) (c & INT_MASK_LONG); i++; - if (i >= N) { - mt[0] = mt[N - 1]; + if (i >= stateSize) { + state[0] = state[stateSize - 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; - } + state[0] = (int) UPPER_MASK_LONG; // MSB is 1, ensuring non-zero initial array. } /** {@inheritDoc} */
