On 27/04/13 15:28, Andrei de Araújo Formiga wrote:
As I have some interest in using RNGs in Rust, I'd like to chime in on
this.
The extra traits like "RandomDistribution" would be a good thing,
especially if it would be possible to "plug" a different, custom
generator than the one provided and use the custom generator with code
that simply calls rand(). For example for normal generation I might
not want to use Ziggurat, or maybe I want a quasi-random uniform
generator instead of a PRNG. (For normal generation I've been using
Box Muller but it is a bit slow, Ziggurat may be slower when
generating samples on the tails of the distribution, so maybe the
ideal would be to use the inversion method over a good algorithm for
generating quantiles, like R does, but this takes a bit more work).
Also, if you're not already doing so I'd recommend running some
statistical tests on the PRNG you're implementing, just to have a
greater degree of confidence about them. The Diehard and Dieharder
test suites are popular for testing the output of a PRNG. I may help
with this if needed.
The current organisation of core::rand means that the "raw" (P)RNG is
pluggable; everything is parameterised over an Rng trait, and, at the
moment, there is no obvious reason why this couldn't be maintained
(I'll be making every effort to keep it this way: it gives a nice way
of using (for example) both crypto-quality RNGs and simulation-speed
RNGs without reimplementing everything).
FWIW, the inversion method seems to be slower than Ziggurat for Exp(1)
(logs are really slow!), and the sampling-from-tails step should only
happen about 0.02% of the time for sampling from N(0,1), assuming I
understand the algorithm correctly. (My current implementation uses
Ziggurat with 256 slices, which means the tails start at +-3.654 for
the normal distribution.)
I would very much appreciate/need assistance, even if it is just
adding some suggestions/links to the lib wiki page[1].
At the moment I'm visualising the key part of the distribution
sampling as
trait Distribution<Ret> {
fn sample<R: Rng>(&self, rng: &R) -> Ret;
}
so that Normal can impl Distribution<f64> and Binomial can impl
Distribution<uint> (for example). This keeps the raw rng separate
from the distributions, so that all the rng needs to be able to do is
generate a u32 or a u64 and then it should be able to be used to
sample from any/all distributions.
At least, that's how I've been thinking about doing it, but I haven't
actually taken pen-to-paper/hands-to-keyboard to see if it is
reasonable in practice, and I'll be trying to have a look at other
languages to see how they do things, documenting them at [1]. (If
anyone has an example of a nice random-number related
library/paper/language etc, they should throw a link to it on that
page. I've added GSL as Diggory Hardy suggested.)
And yes, I agree that tests are important. I'm thinking it might even
be worth including a check-rand target in the makefiles depending on
how serious we are about making the rand module "perfect" (probably
only run by hand though, since it may fail sometimes due to how
randomness works).
Again, suggestions and help are most definitely welcome and wanted:
I've never architectured a random number heirachy before. :)
Huon
[1]: https://github.com/mozilla/rust/wiki/Lib-rand
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev