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();
}
}