private static SharedStateDiscreteSampler createPoissonDistributionFromX0()

in commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/MarsagliaTsangWangDiscreteSampler.java [777:808]


        private static SharedStateDiscreteSampler createPoissonDistributionFromX0(
                UniformRandomProvider rng, double mean) {
            final double p0 = Math.exp(-mean);

            // Recursive update of Poisson probability until the value is too small
            // p(x + 1) = p(x) * mean / (x + 1)
            double p = p0;
            int i = 1;
            while (p * DOUBLE_31 >= 1) {
                p *= mean / i++;
            }

            // Probabilities are 30-bit integers, assumed denominator 2^30
            final int size = i - 1;
            final int[] prob = new int[size];

            p = p0;
            prob[0] = toUnsignedInt30(p);
            // The sum must exceed 2^30. In edges cases this is false due to round-off.
            int sum = prob[0];
            for (i = 1; i < prob.length; i++) {
                p *= mean / i;
                prob[i] = toUnsignedInt30(p);
                sum += prob[i];
            }

            // If the sum is < 2^30 add the remaining sum to the mode (floor(mean)).
            prob[(int) mean] += Math.max(0, INT_30 - sum);

            // Note: offset = 0
            return createSampler(rng, POISSON_NAME, prob, 0);
        }