D-Programming-Language/phobos — pull request #1029 by WebDrake (2012-12-24 14:53:18+00:00)
Title: Normal/Gaussian random number generation

A little Christmas present for D :-) This code offers both function and struct interfaces for generating random numbers drawn from a normal/Gaussian distribution, with a choice of algorithms: for now, the Box-Muller algorithm (adapted from Boost's implementation), and Jerro's adaptation of his own Ziggurat implementation. Cf. the following discussions for some background and details:
http://www.digitalmars.com/d/archives/digitalmars/D/Normal_Gaussian_random_number_generation_for_D_179010.html
https://github.com/WebDrake/phobos/pull/1
https://github.com/WebDrake/phobos/pull/2
https://github.com/WebDrake/phobos/pull/3

The different algorithms are implemented as different internal "engines" which can be chosen by the user as template parameters. This approach is proposed as a general solution for incorporating multiple different random number algorithms into Phobos, and can be used in future for other random number generating functions (e.g. for exponentially-distributed random numbers).

The struct implementations are designed to pave the way for functionality akin to Boost/C++11's variate_generator which couples a distribution and a random number generator.

Several issues for consideration when reviewing this code:

1. The floating-point type used by the internal engines. The current approach infers the type based on the CommonType of mean and standard deviation, defaulting to double if the CommonType is not floating point. However, this means that a different static instance of the engine is created for each floating-point type (float, double, real). If this is undesirable it may be better to assume highest precision (=real) for the engine's internal operations.

2. Private functions and templates introduced in Jerro's Ziggurat algorithm. Some of these may be useful beyond Ziggurat and if so might be better placed elsewhere: e.g. hasCompileTimeMinMax, isPowerOfTwo.

3. Jerro's fastUniformFloat is virtually identical in practice to Boost/C++11's uniform_01 random number distribution, which returns a uniformly-distributed random number in the half-open interval [0, 1). It may therefore be worth making it public and naming it accordingly. A difference to Boost is that this version assumes that the underlying RNG will have an integral base type, so if float-based RNGs are planned for the future, it may be worth tweaking the code accordingly.

4. Likewise, Jerro's fastUniformInt provides a speedy way of generating a uniformly-distributed integer in [0, n) and therefore may be worth making public, possibly with a name change.

5. General naming conventions used in this code, e.g. for the engines.

Jerro has also generated some interesting results based on tests of randomness (see discussion https://github.com/WebDrake/phobos/pull/1) which may be worth taking into account in the bigger picture of std.random development.

.... oh, and -- should we include a partridge in a pear tree? :-)