Normal/Gaussian random number generation for D

Joseph Rushton Wakeling joseph.wakeling at webdrake.net
Thu Oct 25 15:41:50 PDT 2012


On 10/24/2012 11:23 PM, jerro wrote:
> I already have a NormalDist struct at
> https://github.com/jerro/phobos/blob/new-api/std/random.d#L2363 - converting
> that should be trivial.

I'll have a go at this some time in the next days. :-)

> I have only tested a distribution of the output samples, which seems to be
> correct. I agree that we should try to avoid statistical flaws as much as
> possible. Do you know of any good tests for nonuniform random number generators?

I'm not expert on this, but there are various tests described in this paper 
which compares different normal random number generation techniques:
http://www.cse.cuhk.edu.hk/%7Ephwl/mt/public/archives/papers/grng_acmcs07.pdf

... and the topic is also discussed in this paper:
http://www.doornik.com/research/ziggurat.pdf

I don't have sufficient knowhow to really feel confident about how to test these 
things though, and part of me feels it might be worth at some point approaching 
some stats experts and asking them to help define a test suite for D's random 
number functionality.

> Seems OK to me. Maybe the function that uses a static engine should have one
> version that takes Rng as a parameter and one that uses rndGen, similar to how
> uniform() works now?

Well, as I defined the function, the UniformRNG input has a default value of 
rndGen, so if you call it just as normal(mean, sigma); it should work as 
intended.  But if there's some factor which means it would be better to define a 
separate function which doesn't receive the RNG as input, I can do that.

> How would the static engines be initialized? They could be initialized on first
> use, but this would slow sample generation a bit. Another options is to
> initialize them in the static constructor. I think it would be best to make the
> engine a static field of a struct template, and initialize it in the structs
> static constructor (similar to what my ZigguratTable struct does). That way you
> don't need to check if the engine is initialized every time you generate a
> sample and the engine isn't initialized unless the function template that uses
> it is instantiated.

I think it probably depends on the details of the technique.  E.g. with 
Box-Muller you cache 2 random values, and you need to re-generate them for every 
pair of normal random variates the user requests, so there's no problem with 
having it initialized in opCall on the first call to the engine.

In general I favour that approach of initializing in opCall because it means 
that you don't have to ever pass anything to the constructor and also if I have 
a simulation which uses a lot of random numbers, its output won't be changed 
simply by creating an instance of a normal random number generator -- only when 
I start actually _using_ that generator in place of some other source of randomness.

> I think we should do that. Do you already have some code somewhere where I can
> see it? I need to know what API the NormalRandomNumberEngine struct should have.

Did you get the code I attached to my original post on this topic?  Is there 
something extra that you need?

I'm going to turn that into patches for Phobos which I'll put up on GitHub in 
the next days, so we can pull and push and test/write together as needed.

Best wishes,

     -- Joe



More information about the Digitalmars-d mailing list