private static SharedStateDiscreteSampler createBinomialDistributionSamplerFromRange()

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


        private static SharedStateDiscreteSampler createBinomialDistributionSamplerFromRange(
                UniformRandomProvider rng, int trials, double p,
                boolean useInversion, double p0, int begin, int end) {

            // Assign probability values as 30-bit integers
            final int size = end - begin + 1;
            final int[] prob = new int[size];
            double t = p0;
            final double h = p / (1 - p);
            for (int i = 1; i <= begin; i++) {
                t *= (trials + 1 - i) * h / i;
            }
            int sum = toUnsignedInt30(t);
            prob[0] = sum;
            for (int i = begin + 1; i <= end; i++) {
                t *= (trials + 1 - i) * h / i;
                prob[i - begin] = toUnsignedInt30(t);
                sum += prob[i - begin];
            }

            // If the sum is < 2^30 add the remaining sum to the mode (floor((n+1)p))).
            // If above 2^30 then the effect is truncation of the long tail of the distribution.
            final int mode = (int) ((trials + 1) * p) - begin;
            prob[mode] += Math.max(0, INT_30 - sum);

            final SharedStateDiscreteSampler sampler = createSampler(rng, BINOMIAL_NAME, prob, begin);

            // Check if an inversion was made
            return useInversion ?
                   new MarsagliaTsangWangInversionBinomialSampler(trials, sampler) :
                   sampler;
        }