Class TweakRNG

All Implemented Interfaces:
Serializable, IRNG, RandomnessSource

public class TweakRNG
extends AbstractRNG
implements Serializable
Somewhat experimental RNG that can be configured to smoothly transition between producing mostly values in the center of its range, to producing more values at or near the extremes, as well as favoring high or low results. The probability distribution is... unusual, with lumps that rise or fall based on centrality.
Even though this is experimental, it's still usable. Mostly the useful parts of this relate to changing centrality, making results occur more or less frequently in the center of the output range. You can also change the "favor" to bias results towards higher or lower parts of the same output range, though if favor is non-zero it may have counterintuitive results for nextLong().
Internally, this acts as a TangleRNG, which is a fairly solid, very fast algorithm, and uses its results two at a time to give to an atan2 calculation (specifically, NumberTools.atan2_(float, float) or NumberTools.atan2_(double, double). These particular approximations of atan2 range from 0.0 to 1.0 instead of -pi to pi. This means atan2 inputs with positive x and small y are likely to return values near 1.0 or near 0.0, but not between 0.25 and 0.75. The opposite is true for inputs with negative x and small y; that is likely to be near 0.5 and can't be between 0.0 and 0.25 or between 0.75 and 1.0. TweakRNG uses this property to implement centrality, changing the inputs to its internal atan2 usage so x is positive when centrality is positive, or negative when centrality is negative. Likewise, favor is implemented by changing y, though reversed; positive favor makes the atan2 calculation adjusted with negative y, making it more likely to be between 0.5 and 1.0, while negative favor pushes it back to between 0.0 and 0.5.
Here's an animation of the distribution graph changing.
Created by Tommy Ettinger on 10/6/2019.
See Also:
Serialized Form
  • Constructor Details

  • Method Details

    • next

      public int next​(int bits)
      Description copied from class: AbstractRNG
      Get up to 32 bits (inclusive) of random output; the int this produces will not require more than bits bits to represent.
      Specified by:
      next in interface IRNG
      Specified by:
      next in interface RandomnessSource
      Specified by:
      next in class AbstractRNG
      Parameters:
      bits - an int between 1 and 32, both inclusive
      Returns:
      a random number that fits in the specified number of bits
    • nextInt

      public int nextInt()
      Description copied from class: AbstractRNG
      Get a random integer between Integer.MIN_VALUE to Integer.MAX_VALUE (both inclusive).
      Specified by:
      nextInt in interface IRNG
      Specified by:
      nextInt in class AbstractRNG
      Returns:
      a 32-bit random int.
    • nextLong

      public long nextLong()
      Description copied from class: AbstractRNG
      Get a random long between Long.MIN_VALUE to Long.MAX_VALUE (both inclusive).
      Specified by:
      nextLong in interface IRNG
      Specified by:
      nextLong in interface RandomnessSource
      Specified by:
      nextLong in class AbstractRNG
      Returns:
      a 64-bit random long.
    • nextBoolean

      public boolean nextBoolean()
      Description copied from class: AbstractRNG
      Get a random bit of state, interpreted as true or false with approximately equal likelihood.
      Note: This is abstract because some implementations may be best served by using AbstractRNG.next(int) to get 1 bit, returning next(1) == 1, but others will get much better results with a sign check by calling their choice of AbstractRNG.nextInt() or AbstractRNG.nextLong() and returning nextInt() < 0 or nextLong < 0L. For example, an implementation that uses a linear congruential generator without truncating some lower bits will have very-low-period results for the bottom bit (alternating true and false), but perfectly fine results from a sign check. There are tested issues on the bottom (at least 2) bits of XoRoRNG, but again not on a sign check.
      Specified by:
      nextBoolean in interface IRNG
      Specified by:
      nextBoolean in class AbstractRNG
      Returns:
      a random boolean.
    • nextDouble

      public double nextDouble()
      Description copied from class: AbstractRNG
      Gets a random double between 0.0 inclusive and 1.0 exclusive. This returns a maximum of 0.9999999999999999 because that is the largest double value that is less than 1.0 .
      This is abstract because some generators may natively work with double or float values, but others may need to convert a long to a double as with (nextLong() & 0x1fffffffffffffL) * 0x1p-53, which is recommended if longs are fast to produce.
      Specified by:
      nextDouble in interface IRNG
      Specified by:
      nextDouble in class AbstractRNG
      Returns:
      a double between 0.0 (inclusive) and 0.9999999999999999 (inclusive)
    • nextFloat

      public float nextFloat()
      Description copied from class: AbstractRNG
      Gets a random float between 0.0f inclusive and 1.0f exclusive. This returns a maximum of 0.99999994 because that is the largest float value that is less than 1.0f .
      This is abstract because some generators may natively work with double or float values, but others may need to convert an int or long to a float as with (nextInt() & 0xffffff) * 0x1p-24f, (nextLong() & 0xffffffL) * 0x1p-24f, or next(24) * 0x1p-24f, any of which can work when the method they call is high-quality and fast. You probably would want to use nextInt() or next() if your implementation is natively 32-bit and is slower at producing longs, for example.
      Specified by:
      nextFloat in interface IRNG
      Specified by:
      nextFloat in class AbstractRNG
      Returns:
      a float between 0f (inclusive) and 0.99999994f (inclusive)
    • copy

      public TweakRNG copy()
      Description copied from class: AbstractRNG
      Creates a copy of this IRNG; it will generate the same random numbers, given the same calls in order, as this IRNG at the point copy() is called. The copy will not share references with this IRNG. If this IRNG does not permit copying itself, it is suggested to either throw an UnsupportedOperationException or return a new IRNG of the same type but with a random seed, with the latter meant as a partial defense against cheating.
      This is abstract because every implementation is likely to have different specifics for this.
      Specified by:
      copy in interface IRNG
      Specified by:
      copy in interface RandomnessSource
      Specified by:
      copy in class AbstractRNG
      Returns:
      a copy of this IRNG
    • toSerializable

      Description copied from class: AbstractRNG
      Gets a view of this IRNG in a way that implements Serializable, which may simply be this IRNG if it implements Serializable as well as IRNG.
      For implementors: It is suggested to return an RNG initialized by calling RNG(long) with AbstractRNG.nextLong() if you are unable to save the current state of this IRNG and the caller still needs something saved. This won't preserve the current state or the choice of IRNG implementation, however, so it is simply a last resort in case you don't want to throw an exception.
      Specified by:
      toSerializable in interface IRNG
      Specified by:
      toSerializable in class AbstractRNG
      Returns:
      a Serializable view of this IRNG or a similar one; may be this
    • getStateA

      public long getStateA()
    • setStateA

      public void setStateA​(long stateA)
    • getStateB

      public long getStateB()
    • setStateB

      public void setStateB​(long stateB)
    • getCentrality

      public long getCentrality()
    • setCentrality

      public void setCentrality​(long centrality)
      Adjusts the central bias of this TweakRNG, often to positive numbers (which bias toward the center of the range), but also often to negative numbers (which bias toward extreme values, though still within the range).
      Parameters:
      centrality - should be between -65535 and 65535; positive values bias toward the center of the range
    • getFavor

      public long getFavor()
    • setFavor

      public void setFavor​(long favor)
      Adjusts the value bias of this TweakRNG, often to positive numbers (which bias toward higher results), but also often to negative numbers (which bias toward lower results). All results will still be in their normal range, but will change how often high or low values occur. Unusual results will occur if favor is non-zero and you get a long with nextLong(); in that case, the values are treated as higher when unsigned, so positive favor makes both high positive values and all negative values more common. Doubles and floats will behave normally.
      Parameters:
      favor - should be between -65535 and 65535; positive values bias toward higher (unsigned for longs) results