0

Looking at some legacy code in our app, found this weird implementation of Normal RNG. I want to swap it for a proper Box-Muller transformation but need some encouragement.

As you can see, it generates 5 random numbers from -3.875 to +3.875 and then averages them out to get a quasi-normally distributed value from -1 to +1. Can this possibly be right? How can this even work? Why 5 samples?

Someone, please explain this:

private double GetRandomNormalNumber()
    {
      const double SPREAD = 7.75;
      const double HALFSPREAD = 3.875;
      var random = new Random();

      var fRandomNormalNumber = ((random.NextDouble()*SPREAD - HALFSPREAD) +
                                 (random.NextDouble()*SPREAD - HALFSPREAD) +
                                 (random.NextDouble()*SPREAD - HALFSPREAD) +
                                 (random.NextDouble()*SPREAD - HALFSPREAD) +
                                 (random.NextDouble()*SPREAD - HALFSPREAD)
                                )/5;

      return fRandomNormalNumber;
    }
zvolkov
  • 17,762
  • 8
  • 65
  • 78

2 Answers2

2

Approximating a normal distribution by averaging several random uniform samples is standard, a consequence of the Central Limit Theorem. Usually, 12 samples are taken. In your case, someone decided to just take five samples, maybe for the sake of effiency.

Have a look to Generate random numbers following a normal distribution in C/C++

Community
  • 1
  • 1
anumi
  • 3,744
  • 1
  • 20
  • 22
  • Thanks, reference to Central Limit Theorem is what I was looking for – zvolkov Mar 12 '13 at 15:35
  • 1
    Note that 12 numbers are usually taken not exactly because of CLT, but because variance of a _single_ uniform random variable from [0..1] is 1/12 (as it's E[x^2] - E[x]^2 = 1/3 - 1/4 = 1/12), so sum of 12 such numbers gives variance of 1. So when you add 12 of them and subtract 6, you get a _standard_ normal random variable, with mean=0 and variance=1. – andreister Jan 12 '14 at 19:26
1

The code seems right, it just causes the area around 0.0 to have higher probability than the edges of the range (-HALFSPREAD, HALFSPREAD).

I doubt the 5 numbers is a well calculated value, most likely it's been chosen "because it works"

If you're replacing one RNG with another you should be able to: as long as the replacement has better practical characteristigs nobody should have relied on a specific output from the existing RNG

Sten Petrov
  • 10,338
  • 1
  • 40
  • 56