Uploaded image for project: 'Commons RNG'
  1. Commons RNG
  2. RNG-172

UniformLongSampler can precompute the rejection limit

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Trivial
    • Resolution: Implemented
    • 1.4
    • 1.5
    • sampling
    • None

    Description

      The UniformLongSampler uses this rejection algorithm for non-powers of 2 range 'n':

      @Override
      public long sample() {
          // Rejection algorithm copied from o.a.c.rng.core.BaseProvider
          // to avoid the (n <= 0) conditional.
          // See the JDK javadoc for java.util.Random.nextInt(int) for
          // a description of the algorithm.
          long bits;
          long val;
          do {
              bits = rng.nextLong() >>> 1;
              val  = bits % n;
          } while (bits - val + (n - 1) < 0);
          return val;
      }
      

      This requires a modulus operation per iteration. Worst case expected iteration of the loop is 2 times and thus 2 modulus calls.

      However the statement while (bits - val + (n - 1) < 0) is checking if the bits came from the range [0, limit) where limit is the largest multiple of n that is a positive value. Essential the bits must uniformly be picked from a range that can be used with modulus n and still be uniform for all values.

      This limit can be precomputed and the sampling loop changed to have 1 modulus call:

      @Override
      public long sample() {
          // Note:
          // This will have the same output as the rejection algorithm
          // from o.a.c.rng.core.BaseProvider. The limit for the uniform
          // positive value can be pre-computed. This ensures exactly
          // 1 modulus operation per call.
          long bits = rng.nextLong() >>> 1;
          while (bits >= limit) {
              bits = rng.nextLong() >>> 1;
          }
          return bits % n;
      }
      

      This does not work if the range n is a power of 2 as the limit is 2^63 and no sample for bits can be above it. This sampler uses a different method for power of 2 range and so the limit can be precomputed as used here.

      The output from the sampler will be the same.

      Attachments

        Activity

          People

            Unassigned Unassigned
            aherbert Alex Herbert
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: