A Flash Developer Resource Site

# Thread: Generating Random Numbers from Normal(Gaussian) Distribution

1. ## Generating Random Numbers from Normal(Gaussian) Distribution

We are in the process of builing a statistics simulation for a client. One of the requirements of the simulation is to first generate a set of 1000 random numbers from a Normal (or Guassian) distribution.

Does ActionScript have the builty in functionality to generate random numbers from anything other than a Uniform distribution?

If this functionality is not built in, does anyone know of a component or pre-built script that can provide this functionality?

How hard would it be, if either of the two options above are not possible, to generate random numbers from a Normal(Guassian) distribuion using ActionScript?

Thanks in advance for any help!!!

Aaron

2. There is no built-in mechanism, but since actionscript is a programming language, it's not hard to put stuff like this together.

The Central Limit Theorem says that the mean of any set of variates with any distribution having a finite mean and variance tends to the normal distribution.

This suggests that if we produce a number of random numbers using Math.random() or random() which are all in the same range, and average them, the resulting numbers will exhibit normal distribution.

A very simple example of this is a pair of dice - a single die produces a number with flat distribution, but the pair exhibits something approaching normal distribution (with 7, the number in the middle of the range, being the most common).

We can reproduce this effect by producing some random numbers and averaging them, like so:

code:
```
a = random(MaxRange+1);
b = random(MaxRange+1);
c = random(MaxRange+1);
d = random(MaxRange+1);

r = Math.round((a+b+c+d)/4);
// take the average - this is our random number
// with normal distribution

```

Here is a complete script I just wrote (paste this into a new movie and set the frame-rate to 30 fps) that uses the above technique. It counts the number of hits and displays a bar chart that eventually looks like a bell curve.

See the movie here.

code:
```

// Bell Curve Sample

sumHits = [];
MaxRange = 30; // Number of random slots
Margin = 50;
BarWidth = (Stage.width-Margin*2) / MaxRange;
GraphBase = Stage.height-55;
GraphHeight = Stage.height-100;
maxHits = 1;

for (i = 0; i <= MaxRange; ++i)
{
sumHits[i] = 0;
_root.createTextField('txt_'+i, 10+i,
Margin+i*BarWidth, GraphBase+10+(i%4)*10, 20, 20);
}

onEnterFrame = function()
{
a = random(MaxRange+1);
b = random(MaxRange+1);
c = random(MaxRange+1);
d = random(MaxRange+1);

// take the average - this is our random
r = Math.round((a+b+c+d)/4);

sumHits[r]++;
if (sumHits[r] > maxHits)
maxHits = sumHits[r];
this.clear();
this.lineStyle(4, 0xFF0000, 100);
for (x = 0; x <= MaxRange; ++x)
{
this.moveTo(x*BarWidth+Margin, GraphBase);
this.lineTo(x*BarWidth+Margin, GraphBase-sumHits[x]*GraphHeight/maxHits);
_root["txt_"+x].text = sumHits[x];
}
}

```

3. jbum,
Thank you so much for the quick reply. The code that you provided will serve as a great basis by which to start developing this simulation. I also very much appreciate the explanation of the theory behind the code, it refreshed my memory of all the Statistics classes I took in college and helped me better understand the task at hand!

Thanks again for you help. It is nice to know that there are people out there like yourself that are willing to help the community!

Aaron

4. Well, here I am a couple of months later, with more requests for advice. The original code posted on this thread helped me greatly with creating the simulation that I needed to make. Now I am pushing it a little further and have run into a road block.

Here is the link to the current version of my simulation:
http://www.wayspire.com/playground/B...BellCurve3.swf

My problem lies in the third graph(on the bottom), which plots the cumulative mean of all samples drawn from the population. The point is to show how the cumulative average starts off all over the place, but as more samples are drawn, converges towards the mean of the population.

The problem here is scaling. The graph works fine, but it is hard to see the intracacies of the line. What I would like to do is scale the plots to the vertical height of the graph. For example, the height of the graph is 215px. However, I am only generating plots between 13 and 17. What I would essentially like to to is make 13 the bottom of the graph, and 17 the top.

For example:
Code:
```17 |
|\
| \  /\---
|  \/
13 |_________```
The problem, as you can see from the SWF, is that the graph is not scaling, and is instead scrunched up at the top of the graph...

Code:
```17 |\/\/------
|
|
|
13 |_________```
Here is the code:
Code:
```if (_root.StdDev > _root.Mean/2) {
var MaxRange = 2 * _root.Mean + 2*(_root.StdDev-(_root.Mean/2));
} else {
var MaxRange = 2 * _root.Mean;
}

var GraphWidth = 215;
var GraphHeight = 165;
var GraphBase = GraphHeight-1;

var minMean = 215;
var maxMean = 1;
for (i = 0; i <= Count; i++) {
if (_root.CumulativeMeanHits[i] > maxMean) {
maxMean = _root.CumulativeMeanHits[i];
} else if (_root.CumulativeMeanHits[i] < minMean) {
minMean = _root.CumulativeMeanHits[i];
}
}

_root.CumulativeGraph.clear();
_root.CumulativeGraph.lineStyle(1, 0x000000);
_root.CumulativeGraph.moveTo(0, _root.GraphBase);
for (x = 0; x <= Count; x++) {
with(_root.CumulativeGraph) {
lineTo(x*(GraphWidth/Samples), _root.GraphBase-(_root.CumulativeMeanHits[x]*(_root.GraphHeight/maxMean)));
}
}```
Any ideas on how to make this scale the way I would like it to?

Aaron

5. The Marsaglia transform is a more robust solution:
http://blog.controul.com/2009/04/sta...bution-in-as3/

6. Originally Posted by jbum

The Central Limit Theorem suggests that if we produce a number of random numbers using Math.random() or random() which are all in the same range, and average them, the resulting numbers will exhibit normal distribution.

We can reproduce this effect by producing some random numbers and averaging them, like so:

[as]
a = random(MaxRange+1);
b = random(MaxRange+1);
c = random(MaxRange+1);
d = random(MaxRange+1);

r = Math.round((a+b+c+d)/4);
// take the average - this is our random number
// with normal distribution
erm, if i have the number of range from 3 to 200, so i write loop for 198 time for uniform distribution, then only get the average of them as r (normally distribution rite???)

but, if now i want is log normal distribution, may i just
y = Log(r)

then, y is log normal distribution????

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•

 » Home » Movies » Tutorials » Submissions » Board » Links » Reviews » Feedback » Gallery » Fonts » The Lounge » Sound Loops » Sound FX » About FK » Sitemap