001package squidpony.squidmath;
002
003import squidpony.StringKit;
004import java.io.Serializable;
005
006/**
007 * The fastest generator in this library on desktop JVMs; one of Mark Overton's subcycle generators from
008 * <a href="http://www.drdobbs.com/tools/229625477">this article</a>, specifically a CMR with a 64-bit state, that has
009 * its result multiplied by a constant. Its period is unknown, and it has multiple subcycles with different period
010 * lengths, but one is at the very least 2 to the 42, since the generator passes PractRand after generating that many
011 * 64-bit integers (it passes 32TB with no anomalies), and all states that can be produced using {@link #seed(int)} have
012 * a minimum period of 2 to the 20, or roughly one million. It also can pass TestU01's BigCrush suite in both forward
013 * and reversed bit order, though not for all seeds (as expected).
014 * <br>
015 * Notably, this generator's {@link #nextLong()} method is extremely small (as are all of the methods that use it as a
016 * basis), which may help with inlining decisions for HotSpot. Generating the next step just needs a bitwise rotation of
017 * the current state, multiplying the result by a 32-bit constant, and assigning that to state. Generating a long after
018 * that only needs a multiplication by another constant, which doesn't have the issues with reversed-bits testing that
019 * some other generators do when they multiply as their only output step (xorshift128 notably has patterns in its low
020 * bits, so multiplying by a constant doesn't help those bits, but the CMR generator here has no such low-bit problems).
021 * This means only three math instructions need to be performed to get a new random number (bitwise rotate left,
022 * multiply, multiply), which is extremely low for a high-quality generator. While the CMR state change does not
023 * pipeline well, the ease of calculating a complete number seems to make up for it on desktop JVMs.
024 * <br>
025 * The choice of constants for the multipliers and for the rotation needs to be carefully verified; earlier choices came
026 * close to failing PractRand at 8TB (and were worsening, so were likely to fail at 16TB), but this set of constants has
027 * higher quality in testing. Other constants did well in PractRand but had failures in TestU01 (even down to SmallCrush
028 * when reversed). For transparency, the constants used in this version:
029 * <ul>
030 * <li>The state multiplier is 0xAC564B05L (or 2891336453L), which is one of the constants evaluated in Tables of Linear
031 * Congruential Generators of Different Sizes and Good Lattice Structure, by Pierre L'Ecuyer, to be optimal for an LCG
032 * with a modulus of 2 to the 32 and an odd addend (this doesn't have an addend, but it isn't an LCG either).</li>
033 * <li>The post-processing multiplier is 0x818102004182A025L (or -9115001970698837979L), which is a probable prime with
034 * a low Hamming weight (14 bits of 64 are set), in the hope it will perform well speed-wise. This number doesn't seem
035 * as critical to the quality of the generator, and some other multipliers probably work just as well.</li>
036 * <li>A left rotation constant of 29, which was chosen because it seems to allow the generator to pass certain
037 * TestU01 statistical tests, such as Birthday Spacings, where most other rotations do not.</li>
038 * </ul>
039 * <br>
040 * This is a RandomnessSource but not a StatefulRandomness because it needs to take care and avoid seeds that would put
041 * it in a short-period subcycle. One long test brute-force checked all seeds from 1 to {@code Math.pow(2, 25)} and
042 * validated that each of their periods is at least {@code Math.pow(2, 20) - 1}. This means that as long as a period
043 * as low as 1 million is rarely allowed, a starting state can be quickly chosen from a 32-bit int by using the bottom
044 * 25 bits of the int (plus 1, to disallow the 0 state) and using the remaining 7 bits to step up to 127 times through
045 * the generator.
046 * <br>
047 * The name comes from M. Overton, who discovered this category of subcycle generators, and also how this generator can
048 * really move when it comes to speed. This generator has less state than {@link Mover64RNG}, has a shorter period than
049 * it, and is faster than it in all aspects.
050 * <br>
051 * Created by Tommy Ettinger on 11/26/2018.
052 * @author Mark Overton
053 * @author Tommy Ettinger
054 */
055public final class MiniMover64RNG implements RandomnessSource, Serializable {
056    private static final long serialVersionUID = 2L;
057    private long state;
058
059    /**
060     * Calls {@link #seed(int)} with a random int value (obtained using {@link Math#random()}).
061     */
062    public MiniMover64RNG()
063    {
064        seed((int)((Math.random() * 2.0 - 1.0) * 0x80000000));
065    }
066
067    /**
068     * The recommended constructor, this guarantees the generator will have a period of at least 2 to the 20 (roughly
069     * one million, but most if not all initial states will have much longer periods). All ints are permissible values
070     * for {@code state}.
071     * @param state any int; will be used to get the actual state used in the generator (which is a long internally)
072     */
073    public MiniMover64RNG(final int state)
074    {
075        seed(state);
076    }
077
078    /**
079     * Not advised for external use; prefer {@link #MiniMover64RNG(int)} because it guarantees a good subcycle. This
080     * constructor allows all subcycles to be produced, including ones with a shorter period.
081     * @param state the state to use, exactly unless it is 0 (then this uses 1)
082     */
083    public MiniMover64RNG(final long state)
084    {
085        this.state = state == 0L ? 1L : state;
086    }
087
088    /**
089     * Seeds the state using all bits of the given int {@code s}. Between 33554432 and 4294967296 seeds are possible,
090     * with the actual count probably much closer to 4294967296. This treats the bottom 25 bits of {@code s} (plus 1, to
091     * avoid a seed of 0) as the starting point and then generates the next state at most 127 times, with
092     * each generated state taking less time than {@link #nextLong()}. Some of the starting states are entirely possible
093     * to be within 127 steps of another starting state, so not all seeds are necessarily unique. This is not
094     * guaranteed to put the generator on an optimal subcycle, but it is guaranteed that any subcycle will have a period
095     * of at least 1048575.
096     * @param s all bits are used, none verbatim (0 is tolerated)
097     */
098    public final void seed(final int s) {
099        long v = (s & 0x1FFFFFF) + 1L; // at least 2 to the 25 sequential seeds have periods of at least 1048575.
100        for (int i = s >>> 25; i > 0; i--) {
101            v = (v << 29 | v >>> 35) * 0xAC564B05L;
102        }
103        state = v;
104    }
105
106    public final int nextInt()
107    {
108        return (int)((state = (state << 29 | state >>> 35) * 0xAC564B05L) * 0x818102004182A025L);
109    }
110    @Override
111    public final int next(final int bits)
112    {
113        return (int)((state = (state << 29 | state >>> 35) * 0xAC564B05L) * 0x818102004182A025L) >>> (32 - bits);
114    }
115    @Override
116    public final long nextLong() {
117
118        return (state = (state << 29 | state >>> 35) * 0xAC564B05L) * 0x818102004182A025L;
119//        return (state = (state << 21 | state >>> 43) * 0x9E3779B9L) * 0x41C64E6DL; // earlier, fails some of TestU01
120    }
121
122    /**
123     * Gets a pseudo-random double between 0.0 (inclusive) and 1.0 (exclusive).
124     * @return a pseudo-random double between 0.0 (inclusive) and 1.0 (exclusive)
125     */
126    public final double nextDouble() {
127        return ((state = (state << 29 | state >>> 35) * 0xAC564B05L) * 0x818102004182A025L & 0x1fffffffffffffL) * 0x1p-53;
128    }
129
130    /**
131     * Gets a pseudo-random float between 0.0f (inclusive) and 1.0f (exclusive).
132     * @return a pseudo-random float between 0.0f (inclusive) and 1.0f (exclusive)
133     */
134    public final float nextFloat() {
135        return ((state = (state << 29 | state >>> 35) * 0xAC564B05L) * 0x818102004182A025L & 0xffffffL) * 0x1p-24f;
136    }
137
138    /**
139     * Produces a copy of this MiniMover64RNG that, if next() and/or nextLong() are called on this object and the
140     * copy, both will generate the same sequence of random numbers from the point copy() was called. This just need to
141     * copy the state so it isn't shared, usually, and produce a new value with the same exact state.
142     *
143     * @return a copy of this MiniMover64RNG
144     */
145    @Override
146    public MiniMover64RNG copy() {
147        return new MiniMover64RNG(state);
148    }
149
150    /**
151     * Gets the state; if this generator was set with {@link #MiniMover64RNG()},
152     * {@link #MiniMover64RNG(int)}, or {@link #seed(int)}, then this will be on a good subcycle, otherwise it
153     * may not be. 
154     * @return the state, a long
155     */
156    public long getState()
157    {
158        return state;
159    }
160
161    /**
162     * Sets the state to any long, which may put the generator in a low-period subcycle.
163     * Use {@link #seed(int)} to guarantee a good subcycle.
164     * @param state any int
165     */
166    public void setState(final long state)
167    {
168        this.state = state == 0L ? 1L : state;
169    }
170
171    @Override
172    public String toString() {
173        return "MiniMover64RNG with state 0x" + StringKit.hex(state);
174    }
175
176    @Override
177    public boolean equals(Object o) {
178        if (this == o) return true;
179        if (o == null || getClass() != o.getClass()) return false;
180
181        MiniMover64RNG miniMover64RNG = (MiniMover64RNG) o;
182
183        return state == miniMover64RNG.state;
184    }
185
186    @Override
187    public int hashCode() {
188        return (int)(state ^ state >>> 32);
189    }
190}