J. Mike Rollins (Sparky) [rollins@wfu.edu]
  CISSP, GIAC GPEN
Hyperbola New
My Cats New
Kitty New
Mike is on
  LinkedIn
  FaceBook
BackYardGreen.Net
HappyPiDay.com
Green Cycle Design Group
CamoTruck.Net
  Resume  
  My Stuff  
  Art  
  My Truck  
  People  
Electronics
Jacob's Ladder
Scripts
Math
   Random Numbers
   Maple code
   Loan
   L'Hopital's rule
   Hyperbola New
   Fraction e^x
   Mandelbrot
Notes
My House
My Cars
My Cats New
My Jokes
Pi Poetry
pumpkin
Toro Mower
Development
Speed of a Piston
Not a Pipe
Linux
















Random Numbers

How to generate random numbers with a given mean and standard deviation.


It is fairly simple to generate (pseudo)random numbers from common programming languages. Many times I have needed to generate random numbers that fit a given mean and standard deviation, but I never quite knew how to generate this data. So, now that I have time, I decided to resolve this issue for future reference.

The Standard Normal Distribution is a special case of the Normal Distrubtion where the mean is 0 and variance is 1. I will use N(x) for the standard normal distribution and P(x) for the normal distribution.

The Box-Muller Transformation maps a uniform distribution (0 to 1) to a standard normal distribution.

This will allow us to generate a series of numbers conforming to the standard normal distrbution. This distribution will have a mean of 0 and variance of 1. We need to map the numbers to a normal distribution with a given mean and variance. A standard normal distribution can be mapped to a normal distribution.

Let's start with the probability function for the normal distribution.

Next, let's substitute the variable x with a special expression.

Simplify and isolate the expression for the standard normal disribution

We substitute the standard normal disribution expression. Now, we have a mapping from the standard normal disribution to the normal disribution.

The answer given by the Box-Muller Transform correspond to the variable z. So we need to multiply the Box-Muller values by the standard deviation and add the mean.

So, our plan is as follows:

  1. Generate two uniform random numbers
  2. Use the Box-Muller Transofrm to map the two uniform random numbers to a pair of numbers from a normal distribution.
  3. Multiply the Box-Muller values by the standard deviation and add the mean.

Now let's do some code.

The perl program rand1.pl illustrates the generation of uniform random numbers using the Perl function rand(). There is nothing specail about this program. I include it to validate the uniform nature of the rand() function.

The second program rand2.pl uses the Box-Muller Transform to generate numbers conforming to the standard normal distribution. The second half of this program validates the normal nature of the numbers by using the known proportions of the bell curve.

The third program rand3.pl generates the random numbers using a given mean and standard deviation. Here are the key parts of the program:

    
    # This function returns two numbers (0 to 1)
    # from a uniform distribution.
    
    sub getUniformPair
      {
        my $a = rand(1);
        my $b = rand(1);
        return ($a,$b);
      }
    
    # This function accepts two number (0 to 1) from a
    # uniform distribution and returns two numbers from
    # the standard normal distribution. (mean 0, variance 1)
    
    sub getNormalPair
      {
        my $a = shift;
        my $b = shift;
    
        my $pi = 3.14159265359;
    
        # Box-Muller Transformation
        my $x = sqrt(-2 * log($a)) * cos(2*$pi*$b);
        my $y = sqrt(-2 * log($a)) * sin(2*$pi*$b);
    
        return ($x,$y);
      }
    
    # convert the normal distribution to our 
    # distribution for our sigma an mu
    
    sub scale
      {
        my $x0 = shift;
        my $mu = shift;
        my $sigma = shift;
    
        my $x1 = $x0 * $sigma + $mu;
    
        return $x1;
      }
    
      .
      .
      .
    
    for (my $i=0; $i<($size/2); $i++)
      {
    
        # obtain two random numbers
        my ($a,$b) = getUniformPair();
    
        # transform to normal pair
        ($a,$b) = getNormalPair($a,$b);
    
        # transform to our distribution
        $a = scale($a,$mean,$stdev);
        $b = scale($b,$mean,$stdev);
      }