private double sampleOverhang()

in commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/ZigguratSampler.java [663:703]


        private double sampleOverhang(int j, long xx) {
            // Recycle the initial random deviate.
            // Shift right to make an unsigned long.
            long u1 = xx >>> 1;
            for (;;) {
                // Sample from the triangle:
                //    X[j],Y[j]
                //        |\-->u1
                //        | \  |
                //        |  \ |
                //        |   \|    Overhang j (with hypotenuse not pdf(x))
                //        |    \
                //        |    |\
                //        |    | \
                //        |    u2 \
                //        +-------- X[j-1],Y[j-1]
                // Create a second uniform deviate (as u1 is recycled).
                final long u = randomInt63();
                // If u2 < u1 then reflect in the hypotenuse by swapping u1 and u2.
                // Use conditional ternary to avoid a 50/50 branch statement to swap the pair.
                final long u2 = u1 < u ? u : u1;
                u1 = u1 < u ? u1 : u;
                final double x = interpolate(X, j, u1);
                if (u2 - u1 >= E_MAX) {
                    // Early Exit: x < y - epsilon
                    return x;
                }

                // Note: Frequencies have been empirically measured per call into expOverhang:
                // Early Exit = 0.823328
                // Accept Y   = 0.161930
                // Reject Y   = 0.0147417 (recursion)

                if (interpolate(Y, j, u2) <= Math.exp(-x)) {
                    return x;
                }

                // Generate another variate for the next iteration
                u1 = randomInt63();
            }
        }