Normal/Gaussian random number generation for D
Joseph Rushton Wakeling
joseph.wakeling at webdrake.net
Mon Oct 22 07:45:30 PDT 2012
Hello all,
A request for feedback on the design of this code before I put it through some
serious testing and submit a formal pull request to Phobos' std.random.
The goal here is to provide an interface that is close to the Boost/C++11 design
while allowing for some extra interesting possibilities. In particular the goal
is to allow the possibility of different underlying generation algorithms or
"engines" that can serve different requirements regarding speed, precision,
memory consumption etc. See:
http://www.cse.cuhk.edu.hk/%7Ephwl/mt/public/archives/papers/grng_acmcs07.pdf
... for further details.
The present code contains both a function and struct interface for normal random
number generation; the latter stores the parameters of the distribution (mean
and standard deviation) and an instance of the underlying engine, but not the
random number generator.
(An alternative design choice for the struct would have been to design it as a
range with front/popFront, but for this to work I'd have had to also have it
store the RNG, and this would run into the same problems as RandomSample has due
to RNGs not being reference types. Boost/C++11 also do not store the RNG
internally but implement a variate_generator class which allows the coupling of
a random-number distribution and an underlying generator; this is the approach
I'd take for defining say a RandomVariate range.)
I've so far implemented one underlying engine, the Box-Muller method currently
used in Boost. This is not the best engine possible -- an implementation of the
Ziggurat algorithm is desirable -- but it represents what is typically used in
other libraries. The essence of Box-Muller is that it generates
(uniformly-distributed) numbers a pair at a time and then uses those to generate
a corresponding pair of normally-distributed numbers. The method is described here:
https://en.wikipedia.org/wiki/Box-Muller_transform
I've stuck very closely to the implementation in Boost, to the point of
reproducing a "trick" Boost uses to get round the fact that its uniform random
number generator only supports the interval [a, b) whereas the canonical
description of Box-Muller requires the random numbers to be distributed in the
interval (0, 1]. Obviously in D this is avoidable, but I felt there was some
advantage in reproducing identical results to Boost, at least within the limits
of floating-point numerical rounding (and maybe also because D's PI variable
goes to a greater number of decimal places).
From a licensing point of view this close reproduction isn't an issue, as Boost
and Phobos both use the same licence, but there'll be a credit to the original
Boost authors in any pull request. However, if there's a desire to
differentiate the code more strongly, that can be arranged :-) I've attached a
small C++ code example to demonstrate the common output for the D version and
that of Boost.
Anyway, what I'd really appreciate feedback on is the interface design for these
functions and structs. A few concrete questions:
(1) Does the order of template arguments seem optimal? My inclination is
perhaps to tweak it so that the Uniform RNG type goes first, the underlying
engine second, and the input/output type T goes last, as these are most likely
the order in which people will want to change things.
(2) Is there a desire to have a separate input and output type?
Alternatively, should I perhaps treat all input and internal processing as using
the real type and just use T for the output?
(3) Given the default template arguments provided, is there any way to
ensure that an instance of the Normal struct can be implemented like this:
auto normal01 = Normal(0, 1);
rather than having to do this:
auto normal01 = Normal!()(0, 1);
Yes, I could create a function that returns an instance, but I'm not sure what
to call it given that I want the normal() function to serve a similar purpose as
uniform() ... :-)
Thanks in advance for any and all feedback.
Best wishes,
-- Joe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: normal.d
Type: text/x-dsrc
Size: 3332 bytes
Desc: not available
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20121022/3ac454ab/attachment.d>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: boostnormal.cpp
Type: text/x-c++src
Size: 273 bytes
Desc: not available
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20121022/3ac454ab/attachment.cpp>
More information about the Digitalmars-d
mailing list