in commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/PoissonSamplerCache.java [191:228]
public SharedStateDiscreteSampler createSharedStateSampler(UniformRandomProvider rng,
double mean) {
// Ensure the same functionality as the PoissonSampler by
// using a SmallMeanPoissonSampler under the switch point.
if (mean < PoissonSampler.PIVOT) {
return SmallMeanPoissonSampler.of(rng, mean);
}
if (mean > maxN) {
// Outside the range of the cache.
// This avoids extra parameter checks and handles the case when
// the cache is empty or if Math.floor(mean) is not an integer.
return LargeMeanPoissonSampler.of(rng, mean);
}
// Convert the mean into an integer.
final int n = (int) Math.floor(mean);
if (n < minN) {
// Outside the lower range of the cache.
return LargeMeanPoissonSampler.of(rng, mean);
}
// Look in the cache for a state that can be reused.
// Note: The cache is offset by minN.
final int index = n - minN;
final LargeMeanPoissonSamplerState state = values[index];
if (state == null) {
// Create a sampler and store the state for reuse.
// Do not worry about thread contention
// as the state is effectively immutable.
// If recomputed and replaced it will the same.
final LargeMeanPoissonSampler sampler = new LargeMeanPoissonSampler(rng, mean);
values[index] = sampler.getState();
return sampler;
}
// Compute the remaining fraction of the mean
final double lambdaFractional = mean - n;
return new LargeMeanPoissonSampler(rng, state, lambdaFractional);
}