[GRASS-user] r.fuzzy.system help with defuzzification

Ken Mankoff mankoff at gmail.com
Mon Aug 31 12:12:53 PDT 2020


Hello,

https://grass.osgeo.org/grass78/manuals/addons/r.fuzzy.system.html

I'd like to use the =r.fuzzy.system= addons for GRASS, but am having trouble understanding the output. I'm concerned there is a bug. Below is a minimum example I've created to demonstrate the issue. If anyone on this list has experience with these modules or interest in helping getting their documentation improved so that they are easier to use, I can take the lead but would benefit from some help with this.

I have already improved some of the incorrect docs for these addons (see https://github.com/OSGeo/grass-addons/pull/175 ) but am now returning to a bug I opened a few months ago here https://github.com/OSGeo/grass-addons/issues/176

I'm not 100 % certain there is a bug - I could be using or interpreting the results incorrectly. I hope that is the case and this is a simple fix. If code changes are required, I will try to implement them, but would be grateful for pointers about what/where if someone else sees something I have not yet noticed. I am open to including collaborators as co-authors on a paper I'm writing if the effort needed to get this working and the contribution are significant.

Here (and the GitHub issue above) is the best way I can demonstrate the issue:


* GRASS Fuzzy Code Test

+ Four-cell raster map foo = [1, 2, 3, 4]
  + Foo is "low" when 1, "hi" when 4, and linear change between
  + foo_lo = [1, 0.66, 0.33, 0]
  + foo_hi = [0, 0.33, 0.66, 1]
+ Output is "sad" when foo is "lo", "happy" when foo is "hi", and linear between
  + Expected output:
    + out values = [1, 0.66, 0.33, 0]
    + out label: [sad=1 happy=0; sad=0.66 happy=0.33; sad=0.33 happy=0.66; sad=0 happy=1]

** Summary

Results from 
#+BEGIN_SRC bash
r.fuzzy.system -m maps=fuzzy.maps rules=fuzzy.rules output=out res=10
r.stats -1l out
#+END_SRC

Are:

#+RESULTS:
| 0.63636363 | sad=1.00 | happy=1.00 |
| 0.54545456 | sad=1.00 | happy=1.00 |
| 0.36363637 | sad=1.00 | happy=1.00 |
| 0.27272728 | sad=1.00 | happy=1.00 |

I can see that I've encoded sadness, presumably because that was listed first in the fuzzy.maps __OUTPUT__ (that file contents is shown below), but both sad=1.0 and happy=1.0 seems incorrect to me.


** Set up domain and helper functions

#+BEGIN_SRC bash :results verbatim
grass -c ./G_fuzzy

export GRASS_OVERWRITE=1
export GRASS_VERBOSE=0
g.region w=0 s=0 e=4 n=1 res=1 -pa -s
#+END_SRC

** Define data

#+BEGIN_SRC bash
r.mapcalc "foo = float(col())"
r.stats -1 foo
#+END_SRC

#+RESULTS:
| 1 |
| 2 |
| 3 |
| 4 |


** Set up rules

#+BEGIN_SRC conf :tangle fuzzy.maps
% foo
$ lo {right; 1,4; linear; 0; 1}
$ hi {left; 1,4; linear; 0; 1}

% _OUTPUT_ 
$ sad {left; 0,1; linear; 0;1}
$ happy {right; 0,1; linear; 0;1}
#+END_SRC

#+BEGIN_SRC conf :tangle fuzzy.rules
$ happy { foo = hi }
$ sad { foo = lo }
#+END_SRC

** Run the fuzzy system with pixel-level debug output

#+BEGIN_SRC bash :results verbatim
r.fuzzy.system -m maps=fuzzy.maps rules=fuzzy.rules output=out res=10 coors=0.5,0.5
echo " "
r.fuzzy.system -m maps=fuzzy.maps rules=fuzzy.rules output=out res=10x coors=3.5,0.5
#+END_SRC

#+RESULTS:
#+begin_example
ANTECEDENT happy: 0.000
ANTECEDENT sad: 1.000
RESULT (defuzzified):  0.636
UNIVERSE,happy,sad,AGREGATE 
0.000,0.000,0.000,0.000
0.091,0.000,0.091,0.091
0.182,0.000,0.182,0.182
0.273,0.000,0.273,0.273
0.364,0.000,0.364,0.364
0.455,0.000,0.455,0.455
0.545,0.000,0.545,0.545
0.636,0.000,0.636,0.636
0.727,0.000,0.727,0.727
0.818,0.000,0.818,0.818
0.909,0.000,0.909,0.909

ANTECEDENT happy: 1.000
ANTECEDENT sad: 0.000
RESULT (defuzzified):  0.273
UNIVERSE,happy,sad,AGREGATE 
0.000,1.000,0.000,1.000
0.091,0.909,0.000,0.909
0.182,0.818,0.000,0.818
0.273,0.727,0.000,0.727
0.364,0.636,0.000,0.636
0.455,0.545,0.000,0.545
0.545,0.455,0.000,0.455
0.636,0.364,0.000,0.364
0.727,0.273,0.000,0.273
0.818,0.182,0.000,0.182
0.909,0.091,0.000,0.091
#+end_example


** Run the fuzzy system to get raster output

#+BEGIN_SRC bash
r.fuzzy.system -m maps=fuzzy.maps rules=fuzzy.rules output=out res=10
#+END_SRC

#+RESULTS:

Test the intermediate result from =-m= flag.

#+BEGIN_SRC bash
r.stats -1 out_sad
#+END_SRC

#+RESULTS:
|          1 |
| 0.66666669 |
| 0.33333334 |
|          0 |

#+BEGIN_SRC bash
r.stats -1 out_happy
#+END_SRC

#+RESULTS:
|          0 |
| 0.33333334 |
| 0.66666669 |
|          1 |

Now inspect the final result

#+BEGIN_SRC bash :results verbatim
r.stats -1l out
#+END_SRC

#+RESULTS:
: 0.63636363 sad=1.00 happy=1.00
: 0.54545456 sad=1.00 happy=1.00
: 0.36363637 sad=1.00 happy=1.00
: 0.27272728 sad=1.00 happy=1.00

+ The intermediate results, =out_sad= and =out_happy= make sense, but the final result does not.
+ This suggests there is an issue with the defuzzification step. Let's try other methods.

#+BEGIN_SRC bash :results verbatim
r.fuzzy.system -m maps=fuzzy.maps rules=fuzzy.rules output=out res=10 defuz=bisector imp=minimum
r.stats -1l out
#+END_SRC

#+RESULTS:
: 
: 0.63636363 sad=1.00 happy=1.00
: 0.54545456 sad=1.00 happy=1.00
: 0.36363637 sad=1.00 happy=1.00
: 0.27272728 sad=1.00 happy=1.00

Expected results:

Output value = [1,0.6, 0.3, 0] # can achieve close to 1 if we increase =res= option to =r.fuzzy.system=
Output label = [sad=1 happy=0; sad=0 happy=1]
  Optionally, output label = [sad=<near 1> happy=<near 0>; sad=<near 0> happy=<near 1>]


Any suggestions will be greatly appreciated.

Regards,

  -k.


More information about the grass-user mailing list