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.