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:
- Generate two uniform random numbers
- Use the Box-Muller Transofrm to map the two uniform random numbers to a pair of numbers from
a normal distribution.
- 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);
}
|
|