Class DiscreteUniformSampler

java.lang.Object
org.apache.commons.rng.sampling.distribution.SamplerBase
org.apache.commons.rng.sampling.distribution.DiscreteUniformSampler
All Implemented Interfaces:
DiscreteSampler, SharedStateDiscreteSampler, SharedStateSampler<SharedStateDiscreteSampler>

public class DiscreteUniformSampler extends SamplerBase implements SharedStateDiscreteSampler
Discrete uniform distribution sampler.

Sampling uses UniformRandomProvider.nextInt().

When the range is a power of two the number of calls is 1 per sample. Otherwise a rejection algorithm is used to ensure uniformity. In the worst case scenario where the range spans half the range of an int (231 + 1) the expected number of calls is 2 per sample.

This sampler can be used as a replacement for UniformRandomProvider.nextInt() with appropriate adjustment of the upper bound to be inclusive and will outperform that method when the range is not a power of two. The advantage is gained by pre-computation of the rejection threshold.

The sampling algorithm is described in:

Lemire, D (2019). Fast Random Integer Generation in an Interval. ACM Transactions on Modeling and Computer Simulation 29 (1).

The number of int values required per sample follows a geometric distribution with a probability of success p of 1 - ((2^32 % n) / 2^32). This requires on average 1/p random int values per sample.

Since:
1.0
See Also:
  • Field Details

  • Constructor Details

    • DiscreteUniformSampler

      public DiscreteUniformSampler(UniformRandomProvider rng, int lower, int upper)
      This instance delegates sampling. Use the factory method of(UniformRandomProvider, int, int) to create an optimal sampler.
      Parameters:
      rng - Generator of uniformly distributed random numbers.
      lower - Lower bound (inclusive) of the distribution.
      upper - Upper bound (inclusive) of the distribution.
      Throws:
      IllegalArgumentException - if lower > upper.
  • Method Details

    • sample

      public int sample()
      Creates an int sample.
      Specified by:
      sample in interface DiscreteSampler
      Returns:
      a sample.
    • toString

      public String toString()
      Overrides:
      toString in class SamplerBase
    • withUniformRandomProvider

      public SharedStateDiscreteSampler withUniformRandomProvider(UniformRandomProvider rng)
      Create a new instance of the sampler with the same underlying state using the given uniform random provider as the source of randomness.
      Specified by:
      withUniformRandomProvider in interface SharedStateSampler<SharedStateDiscreteSampler>
      Parameters:
      rng - Generator of uniformly distributed random numbers.
      Returns:
      the sampler
      Since:
      1.3
    • of

      public static SharedStateDiscreteSampler of(UniformRandomProvider rng, int lower, int upper)
      Creates a new discrete uniform distribution sampler.
      Parameters:
      rng - Generator of uniformly distributed random numbers.
      lower - Lower bound (inclusive) of the distribution.
      upper - Upper bound (inclusive) of the distribution.
      Returns:
      the sampler
      Throws:
      IllegalArgumentException - if lower > upper.
      Since:
      1.3
    • createZeroBoundedSampler

      private static DiscreteUniformSampler.AbstractDiscreteUniformSampler createZeroBoundedSampler(UniformRandomProvider rng, int upper)
      Create a new sampler for the range 0 inclusive to upper inclusive.

      This can handle any positive upper.

      Parameters:
      rng - Generator of uniformly distributed random numbers.
      upper - Upper bound (inclusive) of the distribution. Must be positive.
      Returns:
      the sampler
    • isPowerOf2

      private static boolean isPowerOf2(int value)
      Checks if the value is a power of 2.

      This returns true for the value Integer.MIN_VALUE which can be handled as an unsigned integer of 2^31.

      Parameters:
      value - Value.
      Returns:
      true if a power of 2