in commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/FastLoadedDiceRollerDiscreteSampler.java [397:428]
public static FastLoadedDiceRollerDiscreteSampler of(UniformRandomProvider rng,
double[] weights,
int alpha) {
final int n = checkWeightsNonZeroLength(weights);
// Convert floating-point double to a relative weight
// using a shifted integer representation
final long[] frequencies = new long[n];
final int[] offsets = new int[n];
convertToIntegers(weights, frequencies, offsets, alpha);
// Obtain indices of non-zero weights
final int[] indices = indicesOfNonZero(frequencies);
// Edge case for 1 non-zero weight.
if (indices.length == 1) {
return new FixedValueDiscreteSampler(indexOfNonZero(frequencies));
}
final BigInteger m = sum(frequencies, offsets, indices);
// Use long arithmetic if possible. This occurs when the weights are similar in magnitude.
if (m.compareTo(MAX_LONG) <= 0) {
// Apply the offset
for (int i = 0; i < n; i++) {
frequencies[i] <<= offsets[i];
}
return createSampler(rng, frequencies, indices, m.longValue());
}
return createSampler(rng, frequencies, offsets, indices, m);
}