4
\$\begingroup\$

I place various divs on screen by adding random x and y positions successively normalized with this function. My question is, how well is it written? Can I improve it? If so, then how?

I am worried not only about the coding style but also performance since I'm using multiple Math.random()s.

   function normalize(n) {
        var x = 0, i = 0;
        while (i < n) {
            x += Math.random();
            i++;
        }
        return (x / n);
    }
\$\endgroup\$
2
  • \$\begingroup\$ What values of n do you intend to use? 5? 100? \$\endgroup\$ Feb 13, 2016 at 3:31
  • \$\begingroup\$ @200_success 0 to 20 \$\endgroup\$
    – Asperger
    Feb 13, 2016 at 16:14

2 Answers 2

2
\$\begingroup\$

With totally zero context of what's going on and I'm not a math person, why "normalize"? What does "normalize" mean? As a front-end developer, normalize.css comes into mind, but it's not related to CSS. So I'm clueless. If you can give a better name, that would be great.

Also, a more compact way to write this is using a for loop

function normalize(n) {
  for(var x = 0, i = 0; i < n; i++){
    x += Math.random();
  }
  return (x / n);
}
\$\endgroup\$
1
  • \$\begingroup\$ it normalizes the range of possible output values into the interval of [0, 1) (the same interval of the return values from Math.random(), see my answer for the math in all its g(l)ory. \$\endgroup\$ Feb 14, 2016 at 2:02
2
\$\begingroup\$

I place various divs on screen by adding random x and y positions successively normalized with this function.

This is a rather vague requirement, yet the resulting code is quite specific.

I am worried not only about the coding style but also performance since I'm using multiple Math.random()s.

I am worried about if the generated output is actually the desired one. (Are you aware of what this function does?)

What's going on

Let's start by recaping what Math.random() does by quoting MDN:

The Math.random() function returns a floating-point, pseudo-random number in the range [0, 1)

Basically speaking, that means it's uniformly distributed between 0 and 1 with every value in between equally likely.

Now what happens if you add multiple such uniformly distributed variables together as you do with variable x?

Figure 7.6 of this pdf from Section 7.2 (page 15 in the pdf, page 299 in the document) shows the density function of the sum of n such random variables:

convolution of distributions

The X-axis shows what values are possible and the Y-axis shows how the probability is to get this value.1

For n=2, most values that you get for x will be around 1. For n=4, the peak is at 2. In general (as you can see from the picture, the peak is at n/2. Again, for n=1, you get a uniform distribution with everything in [0, 1) equally likely. I added the density for n=1 to the plot in blue color:

added n=1

On top of that, you do the normalisation of (x / n), which squishes all the curves in the plot into the interval [0, 1) on the X-axis and does indeed normalise the range of possible values. I allowed myself to retrace two of the plots:

marked plots

and to normalize them by scaling each one into the interval [0, 1):

normalized plots

ignoring my mad image editing skills, it looks like both plots are pretty similar now. They both have the peak in the middle. Sure, the first one has a higher peak, but that doesn't make them much different: both probabilities will produce values near their peak with a higher likelyhood, which is in the middle for both of them.

So far it looks like the several calls to Math.random() create very similarly distributed random variables.

A practical demonstration

I created the above plots for all n up to 10 with this piece of octave code:

max = 10;
plots = [];

for n = 1:max

    r = zeros(1000000,1);
    
    for i = 1:n
        r += rand(1000000, 1) * 1000;
    endfor
    
    r /= n;
    
    y = zeros(1000,1);
    for random = r'
        y(ceil(random)) += 1;
    endfor
    
    plots = [plots y/n];
    
endfor

I work in the interval up to 1000, but qualitatively, the plots that plot(plots) yields are the same as what you see in the plot above:

n up to 10 probabilities

What values of n do you intend to use? 5? 100? – 200_success♦

@200_success 0 to 20 – Asperger

I wouldn't go as far to say it doesn't make a difference what value n has, but considering how little the distribution changes for the cost of another call to Math.random(), I don't think it's worth it.

The parameter n is also kind of meaningless. I say it's impossible to predict a certain outcome given a certain value for it. It's more like a knob that has to be adjusted by trial and error until desirable values are obtained.

summary, tl, dr;

  • The function does indeed normalize the range of values into [0, 1)
  • The parameter has not a significant influence on the shape probability density function that's used to create the values (this could be desired behaviour)
  • There's no meaningful way to influence the probability density function. A normal distribution for example is defined by how thick (or thin) the bell shape is.

1 Strictly mathematically speaking, this is horribly wrong. But for the intuitive understanding, it's perfect. Sorry math nerds.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.