4

The program is supposed to do the following:

  1. Initializes a grid of values, "ActualGridValues", (X rows by Y columns) equal to 0.
  2. Creates another grid of values, "RandomGridValues", (X rows by Y columns), defines each cell in the grid as equal to the average of N random numbers between the range of -Z to Z.
  3. Adds the number from RandomGridValues to the corresponding cell from ActualGridValues.
  4. For each cell in ActualGridValues, it also adds the values of adjacent cells.
  5. Repeats steps 2-4 ad infinitum.

The result is that random structures coalesce within the grid. Groupings of high positive values will impact nearby cells and cause them to skew high, and groupings of low negative values will do the same but skewing low.

The sum product of all the values in all the cells SHOULD be zero. Although there are localized groups of high-skewed and low-skewed numbers, over a large enough sample size the total of all cells should be zero.

The problem is that, after say, 1000 iterations, the values consistently skew negative. You have structures and locallized high and low points, but the total values always skew negative. (Which means over time the entire grid becomes filled with only negative numbers).

Every time the simulation is run, the values skew negative. Any thoughts on why?

Edit: I've isolated the issue down to the following function. The average value of all the numbers in RandomGridValue almost always turn out negative.

//For every cell value, this function generates a string of random numbers between -RandMax/2 and +RandMax/2. It then takes the average of all of these numbers. It assigns that value to a cell in the RandomGridValue array. 

function AddChaos() {
     for (var l = 0; l < GridX; l++) {
         for (var m = 0; m < GridY; m++) {
             var RandomGrid = 0;
             for (var n = 0; n < RandNums; n++) {
                 RandomGrid = RandomGrid + Math.random() * RandMax * 2 - RandMax;
             }
             RandomGridValue[l][m] = RandomGrid / RandNums;
         }
     }
 }  
BenMorel
  • 34,448
  • 50
  • 182
  • 322
user2161457
  • 61
  • 1
  • 1
  • 7
  • 3
    I found this question interesting, so I did a bit of cursory searching and found this: http://stackoverflow.com/questions/3956478/understanding-randomness. Seems that multiplying random numbers may introduce a skew to the results. I think it would be worth looking into. That post is regarding multiplying two random numbers, while it looks like in your code you are just scaling it, so I'm not sure if it would be quite the same effect. Here's another post: http://stackoverflow.com/questions/11383242/how-to-generate-skewed-random-numbers-in-javascript. – Aaron Blenkush Mar 12 '13 at 15:43
  • That skew is precisely what this program is looking to capture. However it should skew the distribution towards *both* endpoints, rather than one particular endpoint. – user2161457 Mar 12 '13 at 16:03
  • 1
    If you want to sum #`RandNums` random values in [-RandMax,RandMax] you need to do this `RandomGrid += (Math.random()*RandMax - 2*RandMax);` -- otherwise you are either getting all positive or all negative values depending on the sign of `RandMax` – Cris Stringfellow Mar 12 '13 at 16:03
  • @user2161457 I thought you were trying to take the skew out of the results. I provided those links so you could see what *causes* the skew so you can avoid it. – Aaron Blenkush Mar 12 '13 at 16:07
  • @AaronBlenkush Well, I am trying to avoid the unidirectional skew towards one sign. What should happen is it is skewed bidirectionally where 50% of the values are "RandMax/2" and 50% of the values are "-RandMax/2", and the average is 0. What is happening is that we are seeing consistently more "-RandMax/2" – user2161457 Mar 12 '13 at 16:11
  • @CrisStringfellow I don't think that will work... When Math.random() returns .5, the result of the calculation sh'ould be 0. With your equation the result of the calculation is .5*RandMax - 2*RandMax = -1.5*RandMax – user2161457 Mar 12 '13 at 16:13
  • @user2161457 you are doing linear transform shift and scale wrong. You need to learn that. http://stackoverflow.com/questions/929103/convert-a-number-range-to-another-range-maintaining-ratio – Cris Stringfellow Mar 12 '13 at 16:17
  • That's not what I'm trying to do. I'm simply taking the average of a group of random numbers between two specific values. No change in scale, no conversion of values. – user2161457 Mar 12 '13 at 16:20
  • You're formula looks sound (assuming that the magnitude of `RandMin` and `RandMax` will always be equal). Perhaps you should take this to http://math.stackexchange.com :-) – Aaron Blenkush Mar 12 '13 at 16:54

1 Answers1

2

Due to the floating point standard that Javascript implements, doing arithmetic with decimal values is buggy to say the least...

One work around is to convert the decimals to integers by multiplying by 100, doing the math then dividing by 100.

This only works well if you have at most 2 decimals places. If you require more precision than that, I would recommend a language other than Javascript for that part.

Tutan Ramen
  • 1,234
  • 1
  • 8
  • 27