Class Mover32RNG

java.lang.Object
squidpony.squidmath.Mover32RNG
All Implemented Interfaces:
Serializable, RandomnessSource

public final class Mover32RNG
extends Object
implements RandomnessSource
One of Mark Overton's subcycle generators from this article, specifically a cmr^cmr with two 32-bit states; this is the fastest 32-bit generator that still passes statistical tests, plus it's optimized for GWT (sometimes). It has a period of just under 2 to the 64, 0xFFF1F6F18B2A1330, which is roughly 2 to the 63.999691, and allows 2 to the 32 initial seeds.
This seems to do well in PractRand testing (32 TB passed), but this is not a generator Overton tested. "Chaotic" generators like this one tend to score well in PractRand, but it isn't clear if they will fail other tests (in particular, they can't generate all possible long values, and also can't generate 0 or possibly some other ints). As for desktop/server speed, this is faster than Starfish32RNG (which is also high-quality) and is also faster than Lathe32RNG (which is very fast but has quality issues). However, this is slower than Lathe32RNG when using GWT and viewing in Firefox; for some reason Starfish32RNG optimizes well on Firefox and less well on Chrome, but Mover does ver well in older Chrome (faster than Lathe) and rather poorly on Firefox. It doesn't do amazingly well in current Chrome versions, however, and Lathe beats it most of the time there. On 64-bit desktop or server Java, you may want to prefer Mover64RNG, which is the same algorithm using larger words and constants, or MiniMover64RNG, which is even faster but probably has a shorter period than this generator (millions of seeds have been checked to ensure a minimum period of 2 to the 20 for it, though). While each of the two parts of a Mover32RNG can have their full period evaluated, making the total period possible to calculate, the same cannot be said for Mover64RNG or MiniMover64RNG (their maximum periods are high enough for most usage, but the actual totals are still unknown).
Its period is 0xFFF1F6F18B2A1330 for the largest cycle, which it always initializes into if setState(int) is used. setState() only allows 2 to the 32 starting states, but less than 2 to the 64 states are in the largest cycle, so using a long or two ints to set the state seems ill-advised. The generator has two similar parts, each updated without needing to read from the other part. Each is a 32-bit CMR generator, which multiplies a state by a constant, rotates by another constant, and stores that as the next state. The particular constants used here were found by randomly picking 16-bit odd numbers as multipliers, checking the period for every non-zero rotation, and reporting the multiplier and rotation amount when a period was found that was greater than 0xFF000000. Better multipliers are almost guaranteed to exist, but finding them would be a challenge.
This is a RandomnessSource but not a StatefulRandomness because it needs to take care and avoid seeds that would put it in a short-period subcycle. It uses two generators with different cycle lengths, and skips at most 65536 times into each generator's cycle independently when seeding. It uses constants to store 128 known midpoints for each generator, which ensures it calculates an advance for each generator at most 511 times.
The name comes from M. Overton, who discovered this category of subcycle generators, and also how this generator can really move when it comes to speed.
Created by Tommy Ettinger on 8/6/2018.
Author:
Mark Overton, Tommy Ettinger
See Also:
Serialized Form
  • Constructor Summary

    Constructors 
    Constructor Description
    Mover32RNG()  
    Mover32RNG​(int state)  
    Mover32RNG​(int stateA, int stateB)
    Not advised for external use; prefer Mover32RNG(int) because it guarantees a good subcycle.
  • Method Summary

    Modifier and Type Method Description
    Mover32RNG copy()
    Produces a copy of this Mover32RNG that, if next() and/or nextLong() are called on this object and the copy, both will generate the same sequence of random numbers from the point copy() was called.
    boolean equals​(Object o)  
    int getStateA()
    Gets the "A" part of the state; if this generator was set with Mover32RNG(), Mover32RNG(int), or setState(int), then this will be on the optimal subcycle, otherwise it may not be.
    int getStateB()
    Gets the "B" part of the state; if this generator was set with Mover32RNG(), Mover32RNG(int), or setState(int), then this will be on the optimal subcycle, otherwise it may not be.
    int hashCode()  
    int next​(int bits)
    Using this method, any algorithm that might use the built-in Java Random can interface with this randomness source.
    int nextInt()  
    long nextLong()
    Using this method, any algorithm that needs to efficiently generate more than 32 bits of random data can interface with this randomness source.
    void setState​(int s)  
    void setStateA​(int stateA)
    Sets the "A" part of the state to any int, which may put the generator in a low-period subcycle.
    void setStateB​(int stateB)
    Sets the "B" part of the state to any int, which may put the generator in a low-period subcycle.
    String toString()  

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, notify, notifyAll, wait, wait, wait
  • Constructor Details

  • Method Details

    • setState

      public final void setState​(int s)
    • nextInt

      public final int nextInt()
    • next

      public final int next​(int bits)
      Description copied from interface: RandomnessSource
      Using this method, any algorithm that might use the built-in Java Random can interface with this randomness source.
      Specified by:
      next in interface RandomnessSource
      Parameters:
      bits - the number of bits to be returned
      Returns:
      the integer containing the appropriate number of bits
    • nextLong

      public final long nextLong()
      Description copied from interface: RandomnessSource
      Using this method, any algorithm that needs to efficiently generate more than 32 bits of random data can interface with this randomness source. Get a random long between Long.MIN_VALUE and Long.MAX_VALUE (both inclusive).
      Specified by:
      nextLong in interface RandomnessSource
      Returns:
      a random long between Long.MIN_VALUE and Long.MAX_VALUE (both inclusive)
    • copy

      public Mover32RNG copy()
      Produces a copy of this Mover32RNG that, if next() and/or nextLong() are called on this object and the copy, both will generate the same sequence of random numbers from the point copy() was called. This just need to copy the state so it isn't shared, usually, and produce a new value with the same exact state.
      Specified by:
      copy in interface RandomnessSource
      Returns:
      a copy of this Mover32RNG
    • getStateA

      public int getStateA()
      Gets the "A" part of the state; if this generator was set with Mover32RNG(), Mover32RNG(int), or setState(int), then this will be on the optimal subcycle, otherwise it may not be.
      Returns:
      the "A" part of the state, an int
    • getStateB

      public int getStateB()
      Gets the "B" part of the state; if this generator was set with Mover32RNG(), Mover32RNG(int), or setState(int), then this will be on the optimal subcycle, otherwise it may not be.
      Returns:
      the "B" part of the state, an int
    • setStateA

      public void setStateA​(int stateA)
      Sets the "A" part of the state to any int, which may put the generator in a low-period subcycle. Use setState(int) to guarantee a good subcycle.
      Parameters:
      stateA - any int
    • setStateB

      public void setStateB​(int stateB)
      Sets the "B" part of the state to any int, which may put the generator in a low-period subcycle. Use setState(int) to guarantee a good subcycle.
      Parameters:
      stateB - any int
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • equals

      public boolean equals​(Object o)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object