private DiscreteSampler createDiscreteSampler()

in commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/CompositeSamplers.java [445:488]


        private DiscreteSampler createDiscreteSampler(UniformRandomProvider rng,
                                                      double[] weights) {
            // Edge case. Detect uniform weights.
            final int n = weights.length;
            if (uniform(weights)) {
                // Uniformly sample from the size.
                // Note: Upper bound is inclusive.
                return DiscreteUniformSampler.of(rng, 0, n - 1);
            }

            // If possible normalise with a simple sum.
            final double sum = sum(weights);
            if (sum < Double.POSITIVE_INFINITY) {
                // Do not use f = 1.0 / sum and multiplication by f.
                // Use of divide handles a sub-normal sum.
                for (int i = 0; i < n; i++) {
                    weights[i] /= sum;
                }
            } else {
                // The sum is not finite. We know the weights are all positive finite.
                // Compute the mean without overflow and divide by the mean and number of items.
                final double mean = mean(weights);
                for (int i = 0; i < n; i++) {
                    // Two step division avoids using the denominator (mean * n)
                    weights[i] = weights[i] / mean / n;
                }
            }

            // Create the sampler from the factory.
            // Check if a SharedStateSampler is required.
            // If a default factory then the result is a SharedStateDiscreteSampler,
            // otherwise the sampler must be checked.
            if (specialisation == Specialisation.SHARED_STATE_SAMPLER &&
                !(factory instanceof DiscreteProbabilitySampler)) {
                // If the factory was user-defined then clone the weights as they may be required
                // to create a SharedStateDiscreteProbabilitySampler.
                final DiscreteSampler sampler = factory.create(rng, weights.clone());
                return sampler instanceof SharedStateDiscreteSampler ?
                     sampler :
                     new SharedStateDiscreteProbabilitySampler(sampler, factory, weights);
            }

            return factory.create(rng, weights);
        }