Class Ziggurat

java.lang.Object
com.github.tommyettinger.random.Ziggurat

public final class Ziggurat extends Object
An implementation of the Ziggurat method for generating normal-distributed random values. The Ziggurat method is not an approximation, but is faster than some simple approximations while having higher statistical quality. This is not an ideal implementation; it cannot produce as wide of an output range when compared to normal-distributing methods that can use an arbitrarily large supply of random numbers, such as Marsaglia's Polar method. Unlike those methods, this only uses one long as its input. This will randomize its input if it reaches a condition that would normally require the Ziggurat algorithm to generate another random number.
Every bit in the input long may be used in some form, but the most important distinctions are between the bottom 8 bits, which determine a "box" for where the output could be drawn from, the upper 53 bits, which form into a random double between 0 and 1, and bit 9 (or (state & 512L)), which is treated as a sign bit. If any of these bit ranges contains some value more often than other values that should be equally likely, it can manifest as an output defect. Further, generating values in the trail takes more time than other values, and that can happen most frequently when bits 0 through 7 of state are all 0.
The range this can produce is at least from -7.6719775673883905 to 7.183851151080583, and is almost certainly larger (only 4 billion distinct inputs were tested, and there are over 18 quintillion inputs possible).
From Cauldron, MIT-licensed. This in turn is based on Doornik's form of the Ziggurat method:
Doornik, Jurgen A (2005): "An improved ziggurat method to generate normal random samples." University of Oxford: 77.
  • Method Summary

    Modifier and Type
    Method
    Description
    static double
    normal(long state)
    Given a long where all bits are sufficiently (independently) random, this produces a normal-distributed (Gaussian) variable as if by a normal distribution with mean (mu) 0.0 and standard deviation (sigma) 1.0.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • normal

      public static double normal(long state)
      Given a long where all bits are sufficiently (independently) random, this produces a normal-distributed (Gaussian) variable as if by a normal distribution with mean (mu) 0.0 and standard deviation (sigma) 1.0. Note that no additive counters are considered sufficiently random for this, and linear congruential generators might not be random enough either if they return the low-order bits without changes. Patterns between different state values provided to this will generally not be preserved in the output, but this may not be true all the time for patterns on all bits.
      This is an alias for Distributor.normal(long). If you want to preserve input patterns in the normal-distributed output, you can use Distributor.probit(double) or Distributor.linearNormal(long), or variants on those.
      Parameters:
      state - a long that should be sufficiently random; quasi-random longs may not be enough
      Returns:
      a normal-distributed double with mean (mu) 0.0 and standard deviation (sigma) 1.0