Class Oriole32RNG

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

public final class Oriole32RNG
extends Object
implements RandomnessSource, Serializable
A modification of Blackman and Vigna's xoroshiro128+ generator using two 32-bit ints of state instead of two 64-bit longs and also incorporating a large-increment counter (Weyl sequence) that is added to the rotated xoroshiro output; this is tied with Lathe32RNG for the fastest generator on GWT I have found that also passes the full 32TB battery of PractRand's statistical tests. Starfish32RNG has 2D equidistribution while this only has 1D; this means Starfish32RNG (and GWTRNG) can produce all pairs of ints or all longs (except for one) with equal likelihood, while Oriole32RNG (and Lathe32RNG) produce some pairs more often than others. In statistical testing, xoroshiro always fails some binary matrix rank tests, but smaller-state versions fail other tests as well. The changes Oriole makes apply only to the output of xoroshiro, not its well-tested state transition for the "xoroshiro state" part of this generator, and these changes eliminate all statistical failures on 32TB of tested data, avoiding the failures the small-state variant of xoroshiro suffers on BinaryRank, BCFN, DC6, and FPF. It avoids multiplication, like xoroshiro and much of the xorshift family of generators, and any arithmetic it performs is safe for GWT. Oriole takes advantage of xoroshiro's flaws being mostly confined to its output's lower bits by rotating the output of xoroshiro (the weaker 32-bit-state version) and adding a "Weyl sequence," essentially a large-increment counter that overflows and wraps frequently, to the output. Although the upper bits of xoroshiro are not free of artifacts either, they are harder to find issues with (see this article by PCG-Random's author for more detail). It is unclear if the changes made here would improve the larger-state version, but they probably would help to some extent with at least the binary rank failures. The period is also improved by incorporating the Weyl sequence, up to 0xFFFFFFFFFFFFFFFF00000000 .
The name comes from the insectivorous orange songbird called an oriole, which as I have found from the one that visits my backyard, reacts quickly and is always looking for bugs to remove. It also sounds like "xoro."
Original version here for xorshiro128+; this version uses different constants by the same author, Sebastiano Vigna.
Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org) Ported and modified in 2018 by Tommy Ettinger
Author:
Sebastiano Vigna, David Blackman, Tommy Ettinger (if there's a flaw, use SquidLib's or Sarong's issues and don't bother Vigna or Blackman, it's probably a mistake in SquidLib's implementation)
See Also:
A related generator that implements StatefulRandomness and has very similar speed, Serialized Form
  • Constructor Summary

    Constructors 
    Constructor Description
    Oriole32RNG()
    Creates a new generator seeded using three calls to Math.random().
    Oriole32RNG​(int seed)
    Constructs this Oriole32RNG by dispersing the bits of seed using setSeed(int) across the two parts of state this has.
    Oriole32RNG​(int stateA, int stateB)
    Constructs this Oriole32RNG by calling setState(int, int, int) on stateA and stateB as given but producing stateC via stateA ^ stateB; see that method for the specific details (stateA and stateB are kept as-is unless they are both 0).
    Oriole32RNG​(int stateA, int stateB, int stateC)
    Constructs this Oriole32RNG by calling setState(int, int, int) on the arguments as given; see that method for the specific details (stateA and stateB are kept as-is unless they are both 0).
  • Method Summary

    Modifier and Type Method Description
    Oriole32RNG copy()
    Produces a copy of this RandomnessSource 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()  
    int getStateB()  
    int getStateC()  
    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()
    Can return any int, positive or negative, of any size permissible in a 32-bit signed integer.
    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 setSeed​(int seed)
    Sets the state of this generator using one int, running it through Zog32RNG's algorithm three times to get three ints.
    void setState​(int stateA, int stateB, int stateC)
    Sets the current internal state of this Oriole32RNG with three ints, where stateA and stateB can each be any int unless they are both 0, and stateC can be any int without restrictions.
    void setStateA​(int stateA)  
    void setStateB​(int stateB)  
    void setStateC​(int stateC)  
    String toString()  

    Methods inherited from class java.lang.Object

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

    • Oriole32RNG

      public Oriole32RNG()
      Creates a new generator seeded using three calls to Math.random().
    • Oriole32RNG

      public Oriole32RNG​(int seed)
      Constructs this Oriole32RNG by dispersing the bits of seed using setSeed(int) across the two parts of state this has.
      Parameters:
      seed - a long that won't be used exactly, but will affect both components of state
    • Oriole32RNG

      public Oriole32RNG​(int stateA, int stateB)
      Constructs this Oriole32RNG by calling setState(int, int, int) on stateA and stateB as given but producing stateC via stateA ^ stateB; see that method for the specific details (stateA and stateB are kept as-is unless they are both 0).
      Parameters:
      stateA - the number to use as the first part of the state; this will be 1 instead if both seeds are 0
      stateB - the number to use as the second part of the state
    • Oriole32RNG

      public Oriole32RNG​(int stateA, int stateB, int stateC)
      Constructs this Oriole32RNG by calling setState(int, int, int) on the arguments as given; see that method for the specific details (stateA and stateB are kept as-is unless they are both 0).
      Parameters:
      stateA - the number to use as the first part of the state; this will be 1 instead if both seeds are 0
      stateB - the number to use as the second part of the state
      stateC - the number to use as the counter part of the state (third part)
  • Method Details

    • 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
    • nextInt

      public final int nextInt()
      Can return any int, positive or negative, of any size permissible in a 32-bit signed integer.
      Returns:
      any int, all 32 bits are random
    • 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 Oriole32RNG copy()
      Produces a copy of this RandomnessSource 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 needs 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 RandomnessSource
    • setSeed

      public void setSeed​(int seed)
      Sets the state of this generator using one int, running it through Zog32RNG's algorithm three times to get three ints.
      Parameters:
      seed - the int to use to assign this generator's state
    • getStateA

      public int getStateA()
    • setStateA

      public void setStateA​(int stateA)
    • getStateB

      public int getStateB()
    • setStateB

      public void setStateB​(int stateB)
    • getStateC

      public int getStateC()
    • setStateC

      public void setStateC​(int stateC)
    • setState

      public void setState​(int stateA, int stateB, int stateC)
      Sets the current internal state of this Oriole32RNG with three ints, where stateA and stateB can each be any int unless they are both 0, and stateC can be any int without restrictions.
      Parameters:
      stateA - any int except 0 (0 will be treated as 1 instead)
      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