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}