While perhaps surprising at first glance—I know it caught me off-guard the first time I saw it—this is working as expected. I'll explain why.

When you query a patchset (or any agentset), those queries are run on the patchset in a random iteration order. So `[self] of (patch-set (patch 0 0) (patch 0 1))` will sometimes result in `[(patch 0 0) (patch 0 1)]`, and, other times, will result in `[(patch 0 1) (patch 0 0)]`. That is the first component of the problem.

Now, on to the second component: IEEE floating point math. The IEEE standard is followed for representing floating point numbers in essentially every significant programming language. However, one of the nuances of the IEEE representation is that the order in which operations are applied matters. Usually, you don't start to see this until you have a very precise number (i.e. with a lot of digits after the decimal point). For example, here's a brief session I just did in the Haskell REPL:

ghci> let x = 0.000000000000000001
ghci> let y = 0.0000000000000000094
ghci> let z = 0.000000000000000003
ghci> x * y * z
2.82e-53
ghci> y * z * x
2.8199999999999994e-53

Humbug.  Let's ask Scala:

scala> val x = 0.000000000000000001
x: Double = 1.0E-18

scala> val y = 0.0000000000000000094
y: Double = 9.4E-18

scala> val z = 0.000000000000000003
z: Double = 3.0E-18

scala> x * y * z
res0: Double = 2.82E-53

scala> y * z * x
res1: Double = 2.8199999999999994E-53

Okay, enough with the weird languages. Let's ask a mainstream language; let's ask JavaScript:

jjs> var x = 0.000000000000000001
jjs> var y = 0.0000000000000000094
jjs> var z = 0.000000000000000003
jjs> x * y * z
2.82e-53
jjs> y * z * x
2.8199999999999994e-53

Welp... at least they're all consistently wrong.

As it turns out, this otherwise unexpected (and, frankly, mathematical law breaking) behavior is, for example, why many people urge avoiding floating point numbers <http://stackoverflow.com/a/3730040/5288538> for representing amounts of money in software; sometimes, little bits of money here or there just disappear.

So what we have is that patchsets are iterated over randomly, and the order in which math operations are applied matters. Therefore, it is predictable, then, that asking the same agentset to perform the same mathematical operations multiple times will sometimes lead to very, very slightly different results.

As for solutions to this problem, indeed, using `precision` is a way to deal with it. Another option would be to sort the values before averaging them, since that would lead to a consistent ordering of the numbers, and, therefore, a consistent order of mathematical operations.

On 09/08/2016 10:26 PM, Phang wrote:

Dear All,

I have a persistent problem that some of you might have encountered and I am hoping if there could be some that could help me.

I am developing a relatively simple Cellular Automata. Model runs fine except when I ask patches to calculate mean (or even sum) of more than 8 neighbors. The problem appears that the decimal points usually 10th decimal place onwards keeps changing (EVEN) after simulation has stopped running! As a matter of fact, when I calculate mean just after initialization (therefore only SETUP, but before GO) at tick = 0, I would get constantly-changing values for the calculation output. This is quite weird to me and I have tried a few other PCs. Mac and LINUX not yet, but I do not expect problem to be that complicated.

Naturally, I used the native in-radius function to increase neighborhood sizes (in radial fashion) and also workarounds such as patches-at to create a larger Von Neumann neighborhood, but the same problems occur. Problem is avoided when native neighbor and neighbor4 functions are used.

I know I could potentially use Precision to constrain the values, but I realised that at the back (when i did a check) the values are still changing.


Deeply appreciate any insight on this,

Best Regards,

Phang
--
You received this message because you are subscribed to the Google Groups "netlogo-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected] <mailto:[email protected]>. For more options, visit https://groups.google.com/d/optout <https://urldefense.proofpoint.com/v2/url?u=https-3A__groups.google.com_d_optout&d=CwMFaQ&c=yHlS04HhBraes5BQ9ueu5zKhE7rtNXt_d012z2PA6ws&r=sxGjFFyk2A6rYHwAdDtnqeTKj3cEcXDGDo_G9va2ruI&m=8G_vRa06ok9y5eR6o0ZRbvNWLW9o5qM16EUIsVV3Y5U&s=UVSbYh6DGUqGshYj1SfQG-2YlXYfzc47xw3xWxc_l5k&e=>.

--
You received this message because you are subscribed to the Google Groups 
"netlogo-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to