Class ZigguratSampler
java.lang.Object
org.apache.commons.rng.sampling.distribution.ZigguratSampler
- All Implemented Interfaces:
ContinuousSampler
,SharedStateContinuousSampler
,SharedStateSampler<SharedStateContinuousSampler>
- Direct Known Subclasses:
ZigguratSampler.Exponential
,ZigguratSampler.NormalizedGaussian
Modified ziggurat method for sampling from Gaussian and exponential distributions.
Uses the algorithm from:
McFarland, C.D. (2016)
"A modified ziggurat algorithm for generating exponentially and normally distributed pseudorandom numbers".
Journal of Statistical Computation and Simulation 86, 1281-1294.
Note: The algorithm is a modification of the
Marsaglia and Tsang "Ziggurat" method
.
The modification improves performance by:
- Creating layers of the ziggurat entirely inside the probability density function (area B); this allows the majority of samples to be obtained without checking if the value is in the region of the ziggurat layer that requires a rejection test.
- For samples not within the main ziggurat (area A) alias sampling is used to choose a layer and rejection of points above the PDF is accelerated using precomputation of triangle regions entirely below or above the curve.
\ ----------+\ | \ B |A \ -------------+\ | \
Sampling uses UniformRandomProvider.nextLong()
.
- Since:
- 1.4
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic class
Modified ziggurat method for sampling from an exponential distribution.static final class
Modified ziggurat method for sampling from a Gaussian distribution with mean 0 and standard deviation 1. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final int
Mask to extract the lowest 8-bits from an integer.private static final long
Mask to create an unsigned long from a signed long.private final UniformRandomProvider
Underlying source of randomness.private static final double
2^63. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription(package private) static double
interpolate
(double[] v, int j, long u) Compute the value of a point using linear interpolation of a data table of values using the provided uniform deviate.(package private) long
nextLong()
Generates along
.(package private) long
Generates a positivelong
in[0, 2^63)
.(package private) String
Generate a string to represent the sampler.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface org.apache.commons.rng.sampling.distribution.ContinuousSampler
sample, samples, samples
Methods inherited from interface org.apache.commons.rng.sampling.SharedStateSampler
withUniformRandomProvider
-
Field Details
-
MASK_INT8
private static final int MASK_INT8Mask to extract the lowest 8-bits from an integer.- See Also:
-
MAX_INT64
private static final long MAX_INT64Mask to create an unsigned long from a signed long. This is the maximum value of a 64-bit long.- See Also:
-
TWO_POW_63
private static final double TWO_POW_632^63.- See Also:
-
rng
Underlying source of randomness.
-
-
Constructor Details
-
ZigguratSampler
ZigguratSampler(UniformRandomProvider rng) - Parameters:
rng
- Generator of uniformly distributed random numbers.
-
-
Method Details
-
toString
Generate a string to represent the sampler.- Parameters:
type
- Sampler type (e.g. "exponential").- Returns:
- the string
-
nextLong
long nextLong()Generates along
.- Returns:
- the long
-
randomInt63
long randomInt63()Generates a positivelong
in[0, 2^63)
.In the c reference implementation RANDOM_INT63() obtains the current random value and then advances the RNG. This implementation obtains a new value from the RNG. Thus the java implementation must ensure a previous call to the RNG is cached if RANDOM_INT63() is called without first advancing the RNG.
- Returns:
- the long
-
interpolate
static double interpolate(double[] v, int j, long u) Compute the value of a point using linear interpolation of a data table of values using the provided uniform deviate.value = v[j] + u * (v[j-1] - v[j])
This can be used to generate the (x,y) coordinates of a point in a rectangle with the upper-left corner at
j
and lower-right corner atj-1
:X[j],Y[j] |\ | | \| | \ | |\ Ziggurat overhang j (with hypotenuse not pdf(x)) | | \ | u2 \ | \ |-->u1 \ +-------- X[j-1],Y[j-1] x = X[j] + u1 * (X[j-1] - X[j]) y = Y[j] + u2 * (Y[j-1] - Y[j])
- Parameters:
v
- Ziggurat data table. Values assumed to be scaled by 2^-63.j
- Index j. Value assumed to be above zero.u
- Uniform deviate. Value assumed to be in[0, 2^63)
.- Returns:
- value
-