Closed nathan-at-least closed 1 year ago
The answer is partly historical, but mostly that we have two variants of range sampling: when you want to construct a sampler to use many times, and when you just want to sample that range once.
You can do this:
let dice = Uniform::from(1..=6);
let num_sixes = dice.sample_iter(rand::thread_rng())
.take(100)
.filter(|x| *x == 6)
.count();
println!("Number of sixes: {}", num_sixes);
(Of course, you can also do that with a Binomial distribution.)
Range
is not a good replacement for the uniform distribution struct, because we store the transformed values optimized for sampling. This reduces the work required when sampling many times.
This applies to most distributions: We usually store some transformation of the input values.
Converting a Range
to a uniform distribution is possible, as @dhardy showed.
Thanks for the explanations!
This is an API design question (which I would typically ask in a github "Discussions area" if it were enabled). If this is an inappropriate location, let me know a better place to ask.
Why does
Rng::gen_range
exist, rather than sampling astd::ops::Range
from aDistribution
type?The API I imagine that seems less surprising given
Distribution
is:It also seems like
gen_range
only supports uniform distributions within a range, whereas theDistribution<Range>
approach could support arbitrary distributions over ranges.I am not well-versed in stats/probability, so I wouldn't be surprised if I have some conceptual gap about this API approach. I'm also wondering if this is just a legacy (e.g. older
rand
didn't haveDistribution
or olderstd
didn't have theRange*
types).