[GRASS-SVN] r45422 - in grass-addons/grass7/raster: . r.fuzzy
r.fuzzy/r.fuzzy.logic r.fuzzy/r.fuzzy.set r.fuzzy/r.fuzzy.system
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Feb 17 14:45:09 EST 2011
Author: jarekj71
Date: 2011-02-17 11:45:09 -0800 (Thu, 17 Feb 2011)
New Revision: 45422
Added:
grass-addons/grass7/raster/r.fuzzy/
grass-addons/grass7/raster/r.fuzzy/Makefile
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/Makefile
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/local_proto.h
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/logic.c
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/main.c
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/r.fuzzy.logic.html
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/Makefile
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/boundary.png
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/fuzzy.c
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/local_proto.h
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/main.c
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/r.fuzzy.set.html
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/set.png
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/shape.png
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/Makefile
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/f_result.png
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/flood.map
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/flood.rul
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/fuzzylogic.c
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/helpers.c
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/io.c
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/local_proto.h
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/main.c
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/map_parser.c
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/r.fuzzy.system.html
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/rule_parser.c
grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/system.c
Log:
Initial import
Added: grass-addons/grass7/raster/r.fuzzy/Makefile
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/Makefile (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/Makefile 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+SUBDIRS = \
+ r.fuzzy.set \
+ r.fuzzy.logic \
+ r.fuzzy.system \
+
+include $(MODULE_TOPDIR)/include/Make/Dir.make
+
+default: parsubdirs
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/Makefile
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/Makefile (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/Makefile 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../../..
+
+PGM = r.fuzzy.logic
+
+LIBES = $(RASTERLIB) $(GISLIB) $(MATHLIB)
+DEPENDENCIES = $(RASTERDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/local_proto.h
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/local_proto.h (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/local_proto.h 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/glocale.h>
+
+#define _AND 1
+#define _OR 2
+#define _NOT 3
+#define _IMP 4
+
+#define ZADEH 1
+#define PRODUCT 2
+#define DRASTIC 3
+#define LUKASIEWICZ 4
+#define FODOR 5
+#define HAMACHER 6
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+
+float f_and(float cellx, float celly, int family);
+float f_or(float cellx, float celly, int family);
+float f_imp(float cellx, float celly, int family);
+float f_not(float cellx, int family);
+
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/logic.c
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/logic.c (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/logic.c 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,105 @@
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+float f_and(float x, float y, int family) {
+
+ switch (family) {
+
+ case ZADEH:
+ return MIN(x,y);
+ break;
+
+ case PRODUCT:
+ return x*y;
+ break;
+
+ case DRASTIC:
+ return MAX(x, y) == 1 ? MIN(x, y) : 0;
+ break;
+
+ case LUKASIEWICZ:
+ return MAX((x+y-1),0);
+ break;
+
+ case FODOR:
+ return (x+y)>1 ? MIN(x,y) : 0;
+ break;
+
+ case HAMACHER:
+ return (x==y==0) ? 0 : (x*y)/((x+y)-x*y);
+ break;
+
+
+
+ }
+ return -1; /* error */
+}
+
+float f_or(float x, float y, int family) {
+ float b;
+ switch (family) {
+
+ case ZADEH:
+ return MAX(x,y);
+ break;
+
+ case PRODUCT:
+ return x + y -x * y;
+ break;
+
+ case DRASTIC:
+ return (MIN(x, y) == 0) ? MAX(x, y) : 1;
+ break;
+
+ case LUKASIEWICZ:
+ return MIN((x+y),1);
+ break;
+
+ case FODOR:
+ return (x+y<1) ? MAX(x,y) : 1;
+ break;
+
+ case HAMACHER:
+ return (x+y)/(1+x*y);
+ break;
+ }
+ return -1; /* error */
+}
+
+float f_imp(float x, float y, int family) {
+
+ switch (family) {
+
+ case ZADEH:
+ return (x <= y) ? 1 : y;
+ break;
+
+ case PRODUCT:
+ return MIN(y/x,1);
+ break;
+
+ case DRASTIC:
+ return -1; /* not avaialble */
+ break;
+
+ case LUKASIEWICZ:
+ return MIN((1-x+y),1);
+ break;
+
+ case FODOR:
+ return (x<=y) ? 1 : MAX(1-x,y);
+ break;
+ }
+ return -1; /* error */
+}
+
+float f_not(float x, int family) {
+
+ if (family==HAMACHER)
+ return (1-x)/(1+x);
+ else
+ return ((1-x)<0 || (1-x)>1) ? -1 : 1-x;
+}
+
+
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/main.c
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/main.c (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/main.c 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,235 @@
+/* ***************************************************************************
+ *
+ * MODULE: r.fuzzy.logic
+ * AUTHOR(S): Jarek Jasiewicz <jarekj amu.edu.pl>
+ * PURPOSE: Peroforms logical operatations on membership images created with
+ * r.fuzzy or dofferent method. Use families for fuzzy logic
+ * COPYRIGHT: (C) 1999-2010 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ****************************************************************************
+ */
+
+#define MAIN
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+int main(int argc, char *argv[])
+{
+
+ struct GModule *module;
+ struct Option *par_inputx,
+ *par_inputy,
+ *par_output,
+ *par_operation,
+ *par_family;
+
+ struct Cell_head cellhdx;
+ struct Cell_head cellhdy;
+ struct FPRange membership_range;
+ struct History history;
+
+ char *mapsetx, *mapsety;
+ char *inputx, *inputy;
+ char *output;
+ int nrows, ncols;
+ int row, col;
+ int infdx, infdy, outfd;
+ void *in_bufx, *in_bufy;
+ unsigned char *out_buf;
+ float tmp;
+ DCELL c_min, c_max;
+ int family, operator;
+
+ G_gisinit(argv[0]);
+
+ par_inputx = G_define_standard_option(G_OPT_R_INPUT);
+ par_inputx->description = _("x operand (membership map)");
+ par_inputx->key = "xmap";
+
+ par_inputy = G_define_standard_option(G_OPT_R_INPUT);
+ par_inputy->description = _("y operand (membership map)");
+ par_inputy->key = "ymap";
+ par_inputy->required = NO;
+
+ par_output = G_define_standard_option(G_OPT_R_OUTPUT);
+ par_output->description = _("Resulting map");
+
+ par_operation=G_define_option();
+ par_operation->key = "operator";
+ par_operation->type = TYPE_STRING;
+ par_operation->options = "AND,OR,NOT,IMP";
+ par_operation->answer = "AND";
+ par_operation->multiple = NO;
+ par_operation->required = YES;
+ par_operation->description = _("Fuzzy logic operation");
+
+ par_family=G_define_option();
+ par_family->key = "family";
+ par_family->type = TYPE_STRING;
+ par_family->options = "Zadeh,product,drastic,Lukasiewicz,Fodor,Hamacher";
+ par_family->answer = "Zadeh";
+ par_family->multiple = NO;
+ par_family->required = YES;
+ par_family->description = _("Fuzzy logic family");
+
+ if (G_parser(argc, argv))
+ exit(EXIT_FAILURE);
+
+ inputx=par_inputx->answer;
+ inputy=par_inputy->answer;
+ output=par_output->answer;
+
+ if (!strcmp(par_operation->answer, "AND"))
+ operator=_AND;
+ else if (!strcmp(par_operation->answer, "OR"))
+ operator=_OR;
+ else if (!strcmp(par_operation->answer, "NOT"))
+ operator=_NOT;
+ else if (!strcmp(par_operation->answer, "IMP"))
+ operator=_IMP;
+
+ if (!strcmp(par_family->answer, "Zadeh"))
+ family=ZADEH;
+ else if (!strcmp(par_family->answer, "product"))
+ family=PRODUCT;
+ else if (!strcmp(par_family->answer, "drastic"))
+ family=DRASTIC;
+ else if (!strcmp(par_family->answer, "Lukasiewicz"))
+ family=LUKASIEWICZ;
+ else if (!strcmp(par_family->answer, "Fodor"))
+ family=FODOR;
+ else if (!strcmp(par_family->answer, "Hamacher"))
+ family=HAMACHER;
+
+ if(operator == _NOT && inputy)
+ G_warning("Negation is unary operaton ymap is ignored");
+
+ if(operator != _NOT && !inputy)
+ G_fatal_error("For binary operation (AND, OR, IMP) ymap is required");
+
+ if(family == DRASTIC && operator == _IMP)
+ G_fatal_error("implication is not available for <drastic> family");
+
+ /* end of interface */
+
+ mapsetx = (char *)G_find_raster2(inputx, "");
+
+ if (mapsetx == NULL)
+ G_fatal_error(_("Raster map <%s> not found"), inputx);
+
+ infdx = Rast_open_old(inputx, mapsetx);
+ Rast_get_cellhd(inputx, mapsetx, &cellhdx);
+
+ if (Rast_map_type(inputx, mapsetx) != FCELL_TYPE)
+ G_fatal_error(_("<%s> is not of type CELL"), inputx);
+
+ Rast_init_fp_range(&membership_range);
+ Rast_read_fp_range(inputx,mapsetx,&membership_range);
+ Rast_get_fp_range_min_max(&membership_range, &c_min, &c_max);
+ if(c_min<0 || c_max>1)
+ G_fatal_error("Membership out of range");
+
+ in_bufx = Rast_allocate_buf(FCELL_TYPE);
+
+ if(inputy) {
+
+ mapsety = (char *)G_find_raster2(inputy, "");
+
+ if (mapsety == NULL)
+ G_fatal_error(_("Raster map <%s> not found"), inputy);
+
+ infdy = Rast_open_old(inputy, mapsety);
+ Rast_get_cellhd(inputy, mapsety, &cellhdy);
+
+ if (Rast_map_type(inputy, mapsety) != FCELL_TYPE);
+ G_fatal_error(_("<%s> is not of type CELL"), inputy);
+
+ Rast_init_fp_range(&membership_range);
+ Rast_read_fp_range(inputy,mapsety,&membership_range);
+ Rast_get_fp_range_min_max(&membership_range, &c_min, &c_max);
+ if(c_min<0 || c_max>1)
+ G_fatal_error("Membership out of range");
+
+
+ in_bufy = Rast_allocate_buf(FCELL_TYPE);
+
+ } /* end if inputy */
+
+ nrows = Rast_window_rows();
+ ncols = Rast_window_cols();
+
+ outfd = Rast_open_new(output, FCELL_TYPE);
+ out_buf = Rast_allocate_buf(FCELL_TYPE);
+
+
+ /* binary processing */
+ for (row = 0; row < nrows; row++) {
+ G_percent(row, nrows, 2);
+
+ FCELL fx, fy=0;
+
+ Rast_get_row(infdx, in_bufx, row, FCELL_TYPE);
+
+ if(inputy)
+ Rast_get_row(infdy, in_bufy, row, FCELL_TYPE);
+
+ for (col = 0; col < ncols; col++) {
+
+ fx = ((FCELL *) in_bufx)[col];
+ if(inputy)
+ fy = ((FCELL *) in_bufy)[col];
+
+ if (Rast_is_f_null_value(&fx) || Rast_is_f_null_value(&fy))
+ Rast_set_f_null_value(&tmp, 1);
+
+ else
+
+ switch (operator) {
+ case _AND:
+ //if((row+col)%100==0)
+ if(0>(tmp = f_and(fx,fy,family)))
+ G_warning("Cannot determine result at row %d, col %d", row,col);
+ break;
+
+ case _OR:
+ if(0>(tmp=f_or(fx,fy,family)))
+ G_warning("Cannot determine result at row %d, col %d", row,col);
+ break;
+
+ case _IMP:
+ if((tmp=f_imp(fx,fy,family))<0)
+ G_warning("Cannot determine result at row %d, col %d", row,col);
+ break;
+
+ case _NOT:
+ if((tmp=f_not(fx, family))<0)
+ G_warning("Cannot determine result at row %d, col %d", row,col);
+ break;
+ } /* end switch */
+
+ ((FCELL *) out_buf)[col] = tmp;
+ }
+ Rast_put_row(outfd, out_buf, FCELL_TYPE);
+ } /* end for row */
+
+ G_free(in_bufx);
+ Rast_close(infdx);
+
+ if(inputy) {
+ G_free(in_bufy);
+ Rast_close(infdy);
+ }
+
+ G_free(out_buf);
+ Rast_close(outfd);
+
+ Rast_short_history(output, "raster", &history);
+ Rast_command_history(&history);
+ Rast_write_history(output, &history);
+
+ exit(EXIT_SUCCESS);
+}
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/r.fuzzy.logic.html
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/r.fuzzy.logic.html (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.logic/r.fuzzy.logic.html 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,62 @@
+<h2>OPTIONS</h2>
+<DL>
+<DT><b>xmap</b></DT>
+<DD>Name of input x membership operand. This map must be of type FCELL with range 0 :1 and may require null values. Otherwise program will print error message and stops.
+</DD>
+<DT><b>xmap</b></DT>
+<DD>Name of input y membership operand. This map must be of type FCELL with range 0 :1 and may require null values. Otherwise program will print error message and stops. This map is optional bit is required for all operation except NOT
+</DD>
+<DT><b>operator</b></DT>
+<DD>A fuzzy set operators are generalization of crisp operators. There is more than one possible generalization of every opeartor. There are three operations: fuzzy complements, fuzzy intersections, and fuzzy unions. Addational implication operator is also provided.
+<ul>
+<li>fuzzy intersection (<B>AND</B>) use T-norm of given family for calculation;
+<li>fuzzy union (<B>OR</B>) use T-conorm of given family for calculation;
+<li>fuzzy complement (<B>NOT</B>) fuzzy negation ussualy 1-x;
+<li>fuzzy implication (<B>IMP</B>) use residuum of given family if available;
+</ul>
+</DD>
+<DT><b>family</b></DT>
+<DD>T-norms, T-conorms and residuals are a generalization of the two-valued logical conjunction, disjunction and implication used by boolean logic, for fuzzy logics. Because there is more than one possible generalisation of logial operations, r.fuzzy.logic provides 6 most popular families for fuzzy operations:
+<ul>
+<li><b>Zadeh</b> with minimum (Godel) t-norm and maximum T-conorm;
+<li><b>product</b> with product T-norm and probabilistic sum as T-conorm;
+<li><b>drastic</b> with drastic T-norm and drastic T-conorm;
+<li><b>Łukasiewicz</b> with Łukasiewicz T-norm and bounded sum as a T-conorm;
+<li><b>Fodor</b> with nilpotent minimum as T-norm and nilpotent maximum as T-conorm;
+<li><b>Hamacher</b> (simplified) with Hamacher product as T-norm and Einstein sum as T-conorm;
+</ul>
+There is no residuum for drastic and Hamacher families.
+For more details see <a href="http://www.jstatsoft.org/v31/i02">Meyer D, Hornik K (2009)</a>; <a href="http://en.wikipedia.org/wiki/T-norm">T-norms</a>;
+</DD>
+</DL>
+<h2>OUTPUTS</h2>
+<DL>
+<DT><b>output</b></DT>
+<DD>Map containing result of two-values operations. Multivalued operations will be avaialbel in the future. Map is always of type FCELLS and contains values from 0 (no membership) to 1 (full membership). Values between 0 and 1 indicate partial membership</DD>
+</DL>
+<h2>SEE ALSO</h2>
+<em>
+<a href="r.fuzzy.html">r.fuzzy</a>,
+<a href="r.mapcalc.html">r.mapcalc</a>,
+</em>
+
+
+
+<h2>REFERENCES</h2>
+
+Zadeh, L.A. (1965). "Fuzzy sets". Information and Control 8 (3): 338–353. doi:10.1016/S0019-9958(65)90241-X. ISSN 0019-9958.<P>
+
+Novák, Vilém (1989). Fuzzy Sets and Their Applications. Bristol: Adam Hilger. ISBN 0-85274-583-4.<P>
+
+Klir, George J.; Yuan, Bo (1995). Fuzzy sets and fuzzy logic: theory and applications. Upper Saddle River, NJ: Prentice Hall PTR. ISBN 0-13-101171-5.<P>
+
+Klir, George J.; St Clair, Ute H.; Yuan, Bo (1997). Fuzzy set theory: foundations and applications. Englewood Cliffs, NJ: Prentice Hall. ISBN 0133410587.<P>
+
+Meyer D, Hornik K (2009a). \Generalized and Customizable Sets in R." Journal of Statistical Software, 31(2), 1{27. URL http://www.jstatsoft.org/v31/i02/.<P>
+
+Meyer D, Hornik K (2009b). sets: Sets, Generalized Sets, and Customizable Sets. R~package version~1.0, URL http://CRAN.R-project.org/package=sets.<P>
+
+<h2>AUTHOR</h2>
+Jarek Jasiewicz
+
+
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/Makefile
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/Makefile (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/Makefile 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,11 @@
+MODULE_TOPDIR = ../../..
+
+PGM = r.fuzzy.set
+
+LIBES = $(RASTERLIB) $(GISLIB) $(MATHLIB)
+DEPENDENCIES = $(RASTERDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
+
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/boundary.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/boundary.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/fuzzy.c
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/fuzzy.c (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/fuzzy.c 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,52 @@
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+float fuzzy (FCELL cell) {
+
+ float x, m;
+
+ if (!side) { /* both left and right */
+
+ if (cell <= p[0] || cell >= p[3])
+ return 0.;
+ if (cell >= p[1] && cell <= p[2])
+ return 1.;
+
+ x = (cell<p[1]) ? (cell-p[0])/(p[1]-p[0])
+ : (p[3]-cell)/(p[3]-p[2]);
+ }
+
+ if (side) { /* left: 1 OR right: 2 */
+
+ if (cell <= p[0])
+ return (side == 1) ? 0. : 1.;
+ if (cell >= p[1])
+ return (side == 1) ? 1. : 0.;
+
+ x = (side == 1) ? (cell-p[0])/(p[1]-p[0])
+ : (p[1]-cell)/(p[1]-p[0]);
+ }
+
+ if (type == LINEAR)
+ return x;
+
+ if (type == JSHAPE) {
+ m = (shape < 0) ? pow(2,1+shape)
+ : pow(2,exp(2*shape));
+ return pow(tan(x * PI4),m);
+ }
+
+ if (type == GSHAPE) {
+ m = (shape > 0) ? pow(2,1-shape)
+ : pow(2,exp(-2*shape));
+ return pow(tan(x * PI4),1/m);
+ }
+
+ if(type==SSHAPE) {
+ m = pow(2,exp(2*abs(shape)));
+ return (shape < 0) ? pow(1-cos(x*PI2),m)
+ : pow(sin(x*PI2),m);
+ }
+
+return -1; /* error */
+}
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/local_proto.h
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/local_proto.h (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/local_proto.h 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,36 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <grass/raster.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+/*
+PI2= PI/2
+PI4= PI/4
+*/
+#ifndef PI2
+ #define PI2 (2*atan(1))
+#endif
+
+#ifndef PI4
+ #define PI4 (atan(1))
+#endif
+
+
+#define LINEAR 0
+#define SSHAPE 1
+#define JSHAPE 2
+#define GSHAPE 3
+
+#define BOTH 0
+#define LEFT 1
+#define RIGHT 2
+
+char *input, *output;
+float shape, height;
+int type, side;
+double p[4]; /* inflection points */
+int num_points;
+
+float fuzzy (FCELL cell);
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/main.c
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/main.c (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/main.c 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,232 @@
+/* ***************************************************************************
+ *
+ * MODULE: r.fuzzy.set
+ * AUTHOR(S): Jarek Jasiewicz <jarekj amu.edu.pl>
+ * PURPOSE: Calculate membership value of any raster map according user's rules
+ * COPYRIGHT: (C) 1999-2010 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ****************************************************************************
+ */
+
+#define MAIN
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+int main(int argc, char *argv[])
+{
+ struct GModule *module;
+ struct Option *par_input,
+ *par_output,
+ *par_points,
+ *par_side,
+ *par_type,
+ *par_height,
+ *par_shape;
+
+ struct Cell_head cellhd;
+ struct History history;
+
+
+ char *mapset;
+ int nrows, ncols;
+ int row, col;
+ int infd, outfd;
+ void *in_buf;
+ unsigned char *out_buf;
+ RASTER_MAP_TYPE raster_type;
+ FCELL tmp=0;
+
+ G_gisinit(argv[0]);
+
+ par_input = G_define_standard_option(G_OPT_R_INPUT);
+ par_input->description = _("Raster map to be fuzzified");
+
+ par_output = G_define_standard_option(G_OPT_R_OUTPUT);
+ par_output->description = _("Membership map");
+
+ par_points=G_define_option();
+ par_points->key = "points";
+ par_points->type = TYPE_STRING;
+ par_points->answer = "a,b[,c,d]";
+ par_points->multiple = YES;
+ par_points->required = YES;
+ par_points->description = _("Inflection points: a,b[,c,d]");
+
+ par_side=G_define_option();
+ par_side->key = "side";
+ par_side->type = TYPE_STRING;
+ par_side->options = "both,left,right";
+ par_side->answer = "both";
+ par_side->multiple = NO;
+ par_side->required = YES;
+ par_side->description = _("Fuzzy range");
+
+ par_type=G_define_option();
+ par_type->key = "boundary";
+ par_type->type = TYPE_STRING;
+ par_type->options = "Linear,S-shaped,J-shaped,G-shaped";
+ par_type->answer = "S-shaped";
+ par_type->multiple = NO;
+ par_type->required = YES;
+ par_type->description = _("Type of fuzzy boundaries");
+ par_type->guisection = _("Default options");
+
+ par_shape=G_define_option();
+ par_shape->key = "shape";
+ par_shape->type = TYPE_DOUBLE;
+ par_shape->options = "-1,1";
+ par_shape->answer = "0.";
+ par_shape->multiple = NO;
+ par_shape->required = YES;
+ par_shape->description = _("Shape modifier: -1 to 1");
+ par_shape->guisection = _("Default options");
+
+ par_height=G_define_option();
+ par_height->key = "height";
+ par_height->type = TYPE_DOUBLE;
+ par_height->options = "0,1";
+ par_height->answer = "1.";
+ par_height->multiple = NO;
+ par_height->required = YES;
+ par_height->description = _("Membership height: 0 to 1");
+ par_height->guisection = _("Default options");
+
+ if (G_parser(argc, argv))
+ exit(EXIT_FAILURE);
+
+ input=par_input->answer;
+ output=par_output->answer;
+
+ if (!strcmp(par_type->answer, "Linear"))
+ type=LINEAR;
+ else if (!strcmp(par_type->answer, "S-shaped"))
+ type=SSHAPE;
+ else if (!strcmp(par_type->answer, "J-shaped"))
+ type=JSHAPE;
+ else if (!strcmp(par_type->answer, "G-shaped"))
+ type=GSHAPE;
+
+ if (!strcmp(par_side->answer, "both"))
+ side=BOTH;
+ else if (!strcmp(par_side->answer, "left"))
+ side=LEFT;
+ else if (!strcmp(par_side->answer, "right"))
+ side=RIGHT;
+
+ shape = atof(par_shape->answer);
+ if(shape<-1. || shape>1.)
+ G_fatal_error(_("Shape modifier must be between -1 and 1 but is %f"),shape);
+
+ height = atof(par_height->answer);
+ if(height>1 || height<0)
+ G_fatal_error(_("Heght modifier must be between 0 and 1 but is %f"),height);
+
+ num_points=sscanf(par_points->answer,
+ "%lf,%lf,%lf,%lf",
+ &p[0], &p[1], &p[2], &p[3]);
+
+ if(!side && num_points != 4)
+ G_fatal_error(_("Wrong number of values: got %d but need 4"),
+ num_points);
+
+ if(side && num_points != 2)
+ G_fatal_error(_("Wrong number of values: got %d but need 2"),
+ num_points);
+
+ if (num_points==2) {
+ if( p[0]>p[1])
+ G_fatal_error(_("Point sequence must be: a <= b"));
+ } else {
+ if( p[0]>p[1]||p[1]>p[2]||p[2]>p[3])
+ G_fatal_error(_("Point sequence must be: a <= b; b <= c; c <= d;"));
+ }
+
+ /* end of interface */
+
+ mapset = (char *)G_find_raster2(input, "");
+
+ if (mapset == NULL)
+ G_fatal_error(_("Raster map <%s> not found"), input);
+
+ infd = Rast_open_old(input, mapset);
+ Rast_get_cellhd(input, mapset, &cellhd);
+
+ nrows = Rast_window_rows();
+ ncols = Rast_window_cols();
+ raster_type = Rast_map_type(input,mapset);
+
+ outfd = Rast_open_new(output, FCELL_TYPE);
+
+ in_buf = Rast_allocate_buf(raster_type);
+ out_buf = Rast_allocate_buf(FCELL_TYPE);
+
+ /* processing */
+ for (row = 0; row < nrows; row++) {
+ G_percent(row, nrows, 2);
+ CELL c;
+ FCELL f;
+ DCELL d;
+
+ Rast_get_row(infd, in_buf, row, raster_type);
+
+ for (col = 0; col < ncols; col++) {
+
+ switch (raster_type) {
+
+ case CELL_TYPE:
+ c = ((CELL *) in_buf)[col];
+ if(Rast_is_null_value(&c,CELL_TYPE))
+ Rast_set_f_null_value(&tmp, 1);
+ else {
+ if(0>(tmp = fuzzy((FCELL) c)))
+ G_warning("Cannot determine memebership at row %d, col %d", row,col);
+ ((FCELL *) out_buf)[col] = tmp;
+ }
+ break;
+
+ case FCELL_TYPE:
+ f = ((FCELL *) in_buf)[col];
+ if(Rast_is_null_value(&f,FCELL_TYPE))
+ Rast_set_f_null_value(&tmp, 1);
+ else {
+ tmp = fuzzy((FCELL) f);
+ if(0>(tmp = fuzzy((FCELL) f)))
+ G_warning("Cannot determine memebership at row %d, col %d", row,col);
+ ((FCELL *) out_buf)[col] = tmp;
+ }
+ break;
+
+ case DCELL_TYPE:
+ d = ((DCELL *) in_buf)[col];
+ if(Rast_is_null_value(&d,DCELL_TYPE))
+ Rast_set_f_null_value(&tmp, 1);
+ else {
+ if(0>(tmp = fuzzy ((FCELL) d)))
+ G_warning("Cannot determine memebership at row %d, col %d", row,col);
+ ((FCELL *) out_buf)[col] = tmp;
+ }
+ break;
+ }
+ }
+ Rast_put_row(outfd, out_buf, FCELL_TYPE);
+ } /* end for */
+
+ G_free(in_buf);
+ G_free(out_buf);
+
+ Rast_close(infd);
+ Rast_close(outfd);
+
+ Rast_short_history(output, "raster", &history);
+ Rast_command_history(&history);
+ Rast_write_history(output, &history);
+
+ exit(EXIT_SUCCESS);
+}
+
+
+
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/r.fuzzy.set.html
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/r.fuzzy.set.html (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/r.fuzzy.set.html 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,116 @@
+<h2>OPTIONS</h2>
+<DL>
+<DT><b>input</b></DT>
+<DD>Name of input raster map to be fuzified. This map may be of any type and may require null values.
+</DD>
+<DT><b>points</b></DT>
+<DD>A list containing 4 (A,B,C,D) or 2 A,B) points defining set boundaries. Points must not to be in map range, but it may lead to only 0 o 1 membership for the whole map. For "both" side parameters range between A and D defines base, but range between B and C core of the fuzzy set. Between A and B and C and D are set's boundaries. If side is "both" it require 4 points, else 2 points.
+<center>
+<h3>Fuzzy set definition:</h3>
+<img src="set.png" border=1>
+</center>
+</DD>
+<DT><b>side</b></DT>
+<DD>Option indicate if set is fuzzified of both sides (both), left or right side. See description for details.
+<center>
+<h3>Boundary definition:</h3>
+<img src=boundary.png border=1><br>
+</center>
+</DD>
+</DL>
+
+<h2>OUTPUTS</h2>
+<DL>
+<DT><b>output</b></DT>
+<DD>Map containing membership value of original map. Map is alvays of type FCELLS and contains values from 0 (no membership) to 1 (full membership). Values between 0 and 1 indicate partial membership</DD>
+</DL>
+<h2>FUZZY SET PARAMETERS</h2>
+<DL>
+<DT><b>boundary</b></DT>
+<DD>Parameter definied the shape of the fuzzy boundary. The default and most popular is S-shaped, linear, J-shaped and G-shaped boundaries are also available. The same boundaires are appled to the both sides.</DD>
+
+<DT><b>shape</b></DT>
+<DD>Optional shape modifier. Range from -1 to 1. The default value is 0 and shoud not be changed in most of the time. The negative values indicate more dilatant set, the positive values more concentrate set. See description for details.
+<center>
+<h3>Impact of shape parameter on shape boundary:</h3>
+<img src=shape.png border=1>
+</center>
+</DD>
+<DT><b>height</b></DT>
+<DD>Optional height modifier. Range from 0 to 1. The default value is 1 and indicate full membership beteen points B and C. If height is lesser than one the maximum memebrship is equal to height. See image: Fuzzy set definition.</DD>
+</DL>
+
+<h2>DESCRIPTION</h2>
+
+<H4>Definition of fuzzy set</H4>
+Fuzzy sets are sets whose elements have degrees of membership. Zadeh (1965) introduced Fuzzy sets as an extension of the classical notion of set. Classical membership of elements in a set are binary terms: an element either belongs or does not belong to the set. Fuzzy set theory use the gradual assessment of the membership of elements in a set. A membership function valued in the real unit interval [0, 1]. Classical sets, are special cases of the membership functions of fuzzy sets, if the latter only take values 0 or 1. Classical sets are in fuzzy set theory usually called crisp sets. The fuzzy set theory can be used in a wide range of domains in which information is imprecise, such as most of the GIS operations.
+
+
+<h2>NOTES</H2>
+<H4>Calculation of boundary shape</H4>
+Depending on type of the boundary different equation are used to determine its shape:
+<P>
+<B>Linear:</B> the membership is calculated according following equation:<br>
+<pre><code>
+value <= A -> x = 0
+A< value > B -> x = (value-A)/(B-A)
+B <= value >= C -> x = 1
+C< value > D -> x = (D-value)/(D-C)
+value >= D -> x = 0
+
+where x: membership
+</code></pre>
+<P>
+<B>S-shaped:</B> it use following equation:
+<pre><code>
+sin(x * Pi/2)^m (for positive shape parameter)
+1-cos(x * Pi/2)^m (for nagative shape parameter)
+
+where x: membership, and
+m = 2^exp(2,shape) (for positive shape parameter)
+m = 2^(1+shape) (for negative shape parameter)
+where m: shape parameter.
+</code></pre>
+
+For default shape parameter = 0 m is = 2 whcich is most common parameter for that equation.
+
+<P>
+<B>G-shaped and J shaped:</B> it use following equations:
+<pre><code>
+tan(x * Pi/4)^m (for J-shaped)
+tan(x * Pi/4)^1/m (for G-shaped)
+
+where x: membership, and
+m = 2^exp(2,shape) (for positive shape parameter)
+m = 2^(1+shape) (for negative shape parameter)
+where m: shape parameter.
+</code></pre>
+
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.fuzzy.logic.html">r.fuzzy.logic</a>,
+<a href="r.mapcalc.html">r.mapcalc</a>,
+</em>
+
+
+
+<h2>REFERENCES</h2>
+
+<P>Zadeh, L.A. (1965). "Fuzzy sets". Information and Control 8 (3): 338–353. doi:10.1016/S0019-9958(65)90241-X. ISSN 0019-9958.</P>
+
+<P>Novák, Vilém (1989). Fuzzy Sets and Their Applications. Bristol: Adam Hilger. ISBN 0-85274-583-4.</P>
+
+<P>Klir, George J.; Yuan, Bo (1995). Fuzzy sets and fuzzy logic: theory and applications. Upper Saddle River, NJ: Prentice Hall PTR. ISBN 0-13-101171-5.</P>
+
+<P>Klir, George J.; St Clair, Ute H.; Yuan, Bo (1997). Fuzzy set theory: foundations and applications. Englewood Cliffs, NJ: Prentice Hall. ISBN 0133410587.</P>
+
+<P>Meyer D, Hornik K (2009a). \Generalized and Customizable Sets in R." Journal of Statistical Software, 31(2), 1{27. URL http://www.jstatsoft.org/v31/i02/.</P>
+
+Meyer D, Hornik K (2009b). sets: Sets, Generalized Sets, and Customizable Sets. R~package version~1.0, URL http://CRAN.R-project.org/package=sets.<P>
+
+<h2>AUTHOR</h2>
+Jarek Jasiewicz
+
+
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/set.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/set.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/shape.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.set/shape.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/Makefile
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/Makefile (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/Makefile 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../../..
+
+PGM = r.fuzzy.system
+
+LIBES = $(RASTERLIB) $(GISLIB) $(MATHLIB)
+DEPENDENCIES = $(RASTERDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/f_result.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/f_result.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/flood.map
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/flood.map (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/flood.map 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,25 @@
+#flood.map
+
+ %elevation
+$ low {right; 2,4; sshaped; 0; 1}
+$ moderate {both; 2,4,5,10; sshaped; 0; 1}
+$ high {left; 5,10; sshaped; 0; 1}
+
+ %distance
+$ near {right; 30,70; sshaped; 0; 1}
+$ medium {both; 30,70,100,150; sshaped; 0; 1}
+$ far {both; 100,150,200,300; sshaped; 0; 1}
+$ veryfar {left; 200,300; sshaped; 0; 1}
+
+ %accum_abs
+$ low {right; 500,5000; sshaped; 0; 1}
+$ $ high {left; 500,5000; sshaped; 0; 1}
+
+#output map
+
+ %_OUTPUT_
+$ none {both; 0,20,20,40; linear; 0;1}
+$ small {both; 20,40,40,60; linear; 0;1}
+$ moderate {both; 40,60,60,80; linear; 0;1}
+$ high {both; 60,80,80,100; linear; 0;1}
+$ veryhigh {both; 80,100,100,120; linear; 0;1}
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/flood.rul
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/flood.rul (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/flood.rul 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,6 @@
+#flood.rul
+$ none {distance = veryfar | elevation = high}
+$ small {distance ~ near & accum_abs = high}
+$ moderate {(distance = medium | distance = far) & (elevation = low | elevation = moderate)}
+$ high {(distance = medium & elevation = low)|(distance = near & elevation = moderate)}
+$ veryhigh {distance = near & elevation = low}
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/fuzzylogic.c
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/fuzzylogic.c (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/fuzzylogic.c 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,134 @@
+#include "local_proto.h"
+
+float fuzzy(FCELL cell, SETS * set)
+{
+
+ float x;
+
+ if (!set->side) { /* both left and right */
+
+ if (cell <= set->points[0] || cell >= set->points[3])
+ return 0.;
+ if (cell >= set->points[1] && cell <= set->points[2])
+ return 1.;
+
+ x = (cell <
+ set->points[1]) ? (cell - set->points[0]) / (set->points[1] -
+ set->points[0])
+ : (set->points[3] - cell) / (set->points[3] - set->points[2]);
+ }
+
+ if (set->side) { /* left: 1 OR right: 2 */
+
+ if (cell <= set->points[0])
+ return (set->side == 1) ? 0. : 1.;
+ if (cell >= set->points[1])
+ return (set->side == 1) ? 1. : 0.;
+
+ x = (set->side ==
+ s_LEFT) ? (cell - set->points[0]) / (set->points[1] -
+ set->points[0])
+ : (set->points[1] - cell) / (set->points[1] - set->points[0]);
+ }
+
+ switch (set->shape) {
+ case s_LINEAR:
+ break;
+ case s_SSHAPE:
+ x = pow(sin(x * PI2), 2);
+ break;
+ case s_JSHAPE:
+ x = pow(tan(x * PI4), 2);
+ break;
+ case s_GSHAPE:
+ x = pow(tan(x * PI4), 1 / 2.);
+ break;
+ }
+
+ if (set->hedge)
+ x = (set->hedge > 0) ? pow(x, pow(2, set->hedge)) : pow(x,
+ pow(0.5,
+ (-set->
+ hedge)));
+
+ if (set->height < 1)
+ x = x * set->height;
+
+ return (x >= 0 && x <= 1) ? x : -1;
+}
+
+float f_and(float x, float y, logics family)
+{
+ switch (family) {
+
+ case l_ZADEH:
+ return MIN(x, y);
+ break;
+
+ case l_PRODUCT:
+ return x * y;
+ break;
+
+ case l_DRASTIC:
+ return MAX(x, y) == 1 ? MIN(x, y) : 0;
+ break;
+
+ case l_LUKASIEWICZ:
+ return MAX((x + y - 1), 0);
+ break;
+
+ case l_FODOR:
+ return (x + y) > 1 ? MIN(x, y) : 0;
+ break;
+
+ case l_HAMACHER:
+ return (x == 0||y == 0) ? 0 : (x * y) / ((x + y) - x * y);
+ break;
+
+
+
+ }
+ return -1; /* error */
+}
+
+float f_or(float x, float y, logics family)
+{
+
+ switch (family) {
+
+ case l_ZADEH:
+ return MAX(x, y);
+ break;
+
+ case l_PRODUCT:
+ return x + y - x * y;
+ break;
+
+ case l_DRASTIC:
+ return (MIN(x, y) == 0) ? MAX(x, y) : 1;
+ break;
+
+ case l_LUKASIEWICZ:
+ return MIN((x + y), 1);
+ break;
+
+ case l_FODOR:
+ return (x + y < 1) ? MAX(x, y) : 1;
+ break;
+
+ case l_HAMACHER:
+ return (x + y) / (1 + x * y);
+ break;
+ }
+ return -1; /* error */
+}
+
+
+float f_not(float x, logics family)
+{
+
+ if (family == l_HAMACHER)
+ return (1 - x) / (1 + x);
+ else
+ return ((1 - x) < 0 || (1 - x) > 1) ? -1 : 1 - x;
+}
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/helpers.c
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/helpers.c (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/helpers.c 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,270 @@
+#include "local_proto.h"
+
+int get_nsets(FILE * fd, fpos_t position)
+/* get number of maps (setd) used in analysis */
+{
+
+ int nsets = 0;
+
+ fsetpos(fd, &position);
+ char buf[500];
+
+ fgetpos(fd, &position);
+
+
+ while (fgets(buf, sizeof buf, fd)) {
+ G_strip(buf);
+
+ if (*buf == '#' || *buf == 0 || *buf == '\n')
+ continue;
+
+ if (*buf == '$')
+ nsets++;
+
+ if (*buf == '%')
+ break;
+ }
+ fsetpos(fd, &position);
+ return nsets;
+}
+
+
+int char_strip(char *buf, char rem)
+/* remove spaces, tabs and one addational character */
+{
+ register char *a, *b;
+
+ for (a = b = buf; *a == rem || *a == ' ' || *a == '\t'; a++);
+ if (a != b)
+ while ((*b++ = *a++));
+
+ return 0;
+}
+
+int char_copy(const char *buf, char *res, int start, int stop)
+/* copy part of the string to another string */
+{
+ register int i, j;
+
+ for (i = start, j = 0; i < stop; res[j++] = buf[i++]) ;
+ res[j] = '\0';
+
+ return 0;
+}
+
+
+int get_universe(void)
+{
+ int i, j;
+ float min = 100000000., max = 0;
+
+ resolution += 1;
+
+ for (i = 0; i < nmaps; ++i) {
+ if (s_maps[i].output)
+ break;
+ }
+ output_index = i;
+
+ for (j = 0; j < s_maps[i].nsets; ++j) {
+
+ min = (s_maps[i].sets[j].points[0] < min) ?
+ s_maps[i].sets[j].points[0] : min;
+
+ if (s_maps[i].sets[j].side)
+ max = (s_maps[i].sets[j].points[1] > max) ?
+ s_maps[i].sets[j].points[1] : max;
+ else
+ max = (s_maps[i].sets[j].points[3] > max) ?
+ s_maps[i].sets[j].points[3] : max;
+ }
+
+
+ universe = (float *)G_calloc(resolution, sizeof(float));
+ for (i = 0; i < resolution; ++i)
+ universe[i] = min + ((max - min) / resolution) * i;
+
+/* visual output */
+
+ return 0;
+}
+
+void process_coors(char *answer)
+{
+
+ struct Cell_head window;
+ double x, y;
+ int i, j;
+ int r, c;
+ int num_points;
+ float result;
+
+ visual_output = (float **)G_malloc(resolution * sizeof(float *));
+
+ for (j = 0; j < nrules; ++j)
+ for (i = 0; i < resolution; ++i) {
+ visual_output[i] = (float *)G_calloc(nrules + 2, sizeof(float));
+ visual_output[i][0] = universe[i];
+ }
+
+ Rast_get_window(&window);
+ num_points = sscanf(answer, "%lf,%lf", &x, &y);
+
+ c = (int)Rast_easting_to_col(x, &window);
+ r = (int)Rast_northing_to_row(y, &window);
+
+ get_rows(r);
+ get_cells(c);
+
+ result = implicate(); /* jump to different function */
+
+ for (i = 0; i < nrules; ++i)
+ fprintf(stdout, "ANTECEDENT %s: %5.3f\n", s_rules[i].outname,
+ antecedents[i]);
+
+ fprintf(stdout, "RESULT (deffuzified): %5.3f\n", result);
+
+ fprintf(stdout, "UNIVERSE,");
+ for (i = 0; i < nrules; ++i)
+ fprintf(stdout, "%s,", s_rules[i].outname);
+ fprintf(stdout, "AGREGATE \n");
+
+ for (i = 0; i < resolution; ++i)
+ for (j = 0; j < nrules + 2; ++j) {
+ fprintf(stdout, "%5.3f", visual_output[i][j]);
+ if (j < nrules + 1)
+ fprintf(stdout, ",");
+ else
+ fprintf(stdout, "\n");
+ }
+
+ for (i = 0; i < nmaps; ++i) {
+ G_free(s_maps[i].sets);
+ if (s_maps[i].output)
+ continue;
+ G_free(s_maps[i].in_buf);
+ Rast_close(s_maps[i].cfd);
+ }
+
+ for (j = 0; j < nrules; ++j)
+ G_free(visual_output[j]);
+ G_free(visual_output);
+
+ G_free(antecedents);
+ G_free(s_maps);
+ G_free(s_rules);
+
+ exit(EXIT_SUCCESS);
+}
+
+
+void show_membership(void) {
+ int i,j,k;
+ STRING cur_mapset;
+ struct FPRange map_range;
+ DCELL min, max;
+ float* map_universe;
+
+ resolution=resolution+1;
+ map_universe = (float *)G_calloc(resolution, sizeof(float));
+
+ for(i=0;i<nmaps;++i) {
+
+ if(s_maps[i].output)
+ continue;
+ Rast_init_fp_range(&map_range);
+ cur_mapset = (STRING)G_find_raster2(s_maps[i].name, "");
+ Rast_read_fp_range(s_maps[i].name,cur_mapset,&map_range);
+ Rast_get_fp_range_min_max(&map_range,&min, &max);
+
+ for (k = 0; k < resolution; ++k)
+ map_universe[k] = min + ((max - min) / resolution) * k;
+
+ fprintf(stdout,"#MAP: %s \n",s_maps[i].name);
+
+ fprintf(stdout,"value,");
+ for(j=0;j<s_maps[i].nsets;++j) {
+ fprintf(stdout,"%s",s_maps[i].sets[j].setname);
+ if (j < s_maps[i].nsets-1)
+ fprintf(stdout, ",");
+ else
+ fprintf(stdout, "\n");
+ }
+
+ for(k=0;k<resolution;++k) {
+ fprintf(stdout,"%5.3f,",map_universe[k]);
+ for(j=0;j<s_maps[i].nsets;++j) {
+ fprintf(stdout,"%5.3f",
+ fuzzy(map_universe[k],&s_maps[i].sets[j]));
+ if (j < s_maps[i].nsets-1)
+ fprintf(stdout, ",");
+ else
+ fprintf(stdout, "\n");
+ }
+ }
+ }
+
+ G_free(map_universe);
+
+ for (i = 0; i < nmaps; ++i)
+ G_free(s_maps[i].sets);
+
+ G_free(s_maps);
+ G_free(s_rules);
+
+ exit(EXIT_SUCCESS);
+
+}
+
+int set_cats(void)
+{
+struct Categories cats;
+float fmin, fmax;
+int cmin, cmax;
+int i, j;
+
+fmin=universe[0];
+fmax=universe[resolution];
+cmin=(int)universe[0];
+cmax=(int)universe[resolution];
+double tmp1, tmp2;
+float fuzzy_val=0;
+char buf[200];
+float rang;
+
+rang=(universe[0]+universe[1])/2.;
+Rast_read_cats(output, G_mapset(), &cats);
+Rast_set_cats_title("Result membership", &cats);
+
+ for (i=0;i<resolution;++i) {
+ strcpy(buf,"");
+ for (j=0; j<s_maps[output_index].nsets; ++j) {
+ fuzzy_val=fuzzy(universe[i],&s_maps[output_index].sets[j]);
+
+ if(universe[i]<s_maps[output_index].sets[1].points[0] ||
+ universe[i]>s_maps[output_index].sets[s_maps[output_index].nsets-2].points[3])
+ fuzzy_val=1;
+ if (fuzzy_val>0.)
+ sprintf(buf,"%s %s=%2.2f", buf, s_maps[output_index].sets[j].setname,fuzzy_val);
+ }
+
+ tmp1=(double)universe[i]-rang;
+ tmp2=(double)universe[i]+rang;
+ if(i==0) tmp1=(double)universe[i];
+ if(i==resolution) tmp2=(double)universe[i];
+ Rast_set_d_cat(&tmp1, &tmp2, buf, &cats);
+ }
+Rast_write_cats(output, &cats);
+Rast_free_cats(&cats);
+return 0;
+}
+
+
+/* not in use yet
+void set_colors(void) {
+struct Colors colors;
+Rast_init_colors(&colors);
+Rast_add_d_color_rule(&val1, 255, 255, 255, &val2, 255, 255, 0, &colors);
+Rast_write_colors(output, G_mapset(), &colors);
+}
+*/
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/io.c
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/io.c (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/io.c 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,108 @@
+#include "local_proto.h"
+
+int open_maps(void)
+{
+
+ int i;
+ char *mapset;
+ struct Cell_head cellhd;
+
+ for (i = 0; i < nmaps; ++i) {
+ if (s_maps[i].output) {
+ s_maps[i].in_buf = NULL;
+ continue;
+ }
+ mapset = (char *)G_find_raster2(s_maps[i].name, "");
+
+ if (mapset == NULL)
+ G_fatal_error(_("Raster map <%s> not found"), s_maps[i].name);
+
+ s_maps[i].cfd = Rast_open_old(s_maps[i].name, mapset);
+ Rast_get_cellhd(s_maps[i].name, mapset, &cellhd);
+
+ s_maps[i].raster_type = Rast_map_type(s_maps[i].name,mapset);
+ s_maps[i].in_buf = Rast_allocate_buf(s_maps[i].raster_type);
+ }
+ return 0;
+}
+
+int get_rows(int row)
+{
+ int i;
+
+ for (i = 0; i < nmaps; ++i) {
+ if (s_maps[i].output)
+ continue;
+ Rast_get_row(s_maps[i].cfd, s_maps[i].in_buf, row,
+ s_maps[i].raster_type);
+ }
+ return 0;
+}
+
+int get_cells(int col)
+{
+ int i;
+ CELL c;
+ FCELL f;
+ DCELL d;
+
+ for (i = 0; i < nmaps; ++i) {
+
+ if (s_maps[i].output)
+ continue;
+
+ switch (s_maps[i].raster_type) {
+
+ case CELL_TYPE:
+ c = ((CELL *) s_maps[i].in_buf)[col];
+ if (Rast_is_null_value(&c, CELL_TYPE))
+ return 1;
+ else
+ s_maps[i].cell = (DCELL) c;
+ break;
+
+ case FCELL_TYPE:
+ f = ((FCELL *) s_maps[i].in_buf)[col];
+ if (Rast_is_null_value(&f, FCELL_TYPE))
+ return 1;
+ else
+ s_maps[i].cell = (DCELL) f;
+ break;
+
+ case DCELL_TYPE:
+ d = ((DCELL *) s_maps[i].in_buf)[col];
+ if (Rast_is_null_value(&d, DCELL_TYPE))
+ return 1;
+ else
+ s_maps[i].cell = (DCELL) d;
+ break;
+ }
+ } /* end for */
+
+ return 0;
+}
+
+int create_output_maps(void)
+{
+
+ STRING connector = "_";
+ int i;
+
+ m_outputs = (OUTPUTS *) G_malloc(nrules * sizeof(OUTPUTS));
+
+ for (i = 0; i < nrules; ++i) {
+ strcpy(m_outputs[i].output_name, output);
+ strcat(m_outputs[i].output_name, connector);
+ strcat(m_outputs[i].output_name, s_rules[i].outname);
+
+ if ((m_outputs[i].ofd =
+ Rast_open_new(m_outputs[i].output_name, FCELL_TYPE)) < 0)
+ G_fatal_error(_("Unable to create raster map <%s>"),
+ m_outputs[i].output_name);
+
+ m_outputs[i].out_buf = Rast_allocate_f_buf();
+
+ }
+return 0;
+}
+
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/local_proto.h
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/local_proto.h (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/local_proto.h 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,196 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/glocale.h>
+
+#ifdef MAIN
+# define GLOBAL
+#else
+# define GLOBAL extern
+#endif
+
+/*
+ PI2= PI/2
+ PI4= PI/4
+ */
+#ifndef PI2
+#define PI2 (2*atan(1))
+#endif
+
+#ifndef PI4
+#define PI4 (atan(1))
+#endif
+
+#define STACKMAX 50
+#define VARMAX 31
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+
+typedef char *STRING;
+
+typedef enum
+{
+ l_ZADEH,
+ l_PRODUCT,
+ l_DRASTIC,
+ l_LUKASIEWICZ,
+ l_FODOR,
+ l_HAMACHER
+} logics;
+
+typedef enum
+{
+ s_LINEAR,
+ s_SSHAPE,
+ s_JSHAPE,
+ s_GSHAPE
+} shapes;
+
+typedef enum
+{
+ s_BOTH,
+ s_LEFT,
+ s_RIGHT
+} sides;
+
+typedef enum
+{
+ i_MIN,
+ i_PROD
+} implications;
+
+typedef enum
+{
+ d_CENTEROID,
+ d_BISECTOR,
+ d_MINOFHIGHEST,
+ d_MAXOFHIGHEST,
+ d_MEANOFHIGHEST
+} defuzz;
+
+typedef enum
+{
+ E, /* ERROR */
+ S, /* SHIFT */
+ R, /* REDUCE */
+ A /* ACCEPT */
+} actions;
+
+typedef enum
+{
+ t_START, /* { */
+ t_AND, /* & */
+ t_OR, /* | */
+ t_IS_NOT, /* ~ */
+ t_IS, /* = */
+ t_LBRC, /* ( */
+ t_RBRC, /* ) */
+ t_STOP, /* } */
+ t_size, /* number of tokens */
+ t_VAL /* value a product of MAP and VARIABLE */
+} tokens;
+
+typedef struct
+{ /* membership definition */
+ char setname[21];
+ sides side;
+ float points[4];
+ shapes shape;
+ int hedge;
+ float height;
+} SETS;
+
+typedef struct
+{
+ char name[30];
+ int nsets;
+ int output; /* is output map? */
+ RASTER_MAP_TYPE raster_type;
+ fpos_t position;
+ void *in_buf;
+ DCELL cell;
+ int cfd; /* file descriptor */
+ SETS *sets;
+} MAPS;
+
+typedef struct
+{
+ DCELL *value;
+ SETS *set;
+ char oper;
+} VALUES;
+
+
+typedef struct /* stores queues with rules */
+{
+ char outname[20];
+ int output_set_index;
+ char parse_queue[STACKMAX][VARMAX]; /* original rule */
+ int work_queue[STACKMAX]; /* symbols of values and operators */
+ VALUES value_queue[STACKMAX]; /* pointers to values, operators and sets */
+ float weight;
+} RULES;
+
+typedef struct _outs
+{
+ char output_name[52];
+ int ofd; /* output file descriptor */
+ FCELL *out_buf;
+} OUTPUTS;
+
+
+STRING var_name_file;
+STRING rule_name_file;
+STRING output;
+MAPS *s_maps;
+RULES *s_rules;
+OUTPUTS *m_outputs;
+float **visual_output;
+float *universe;
+float *antecedents;
+float *agregate;
+int nmaps, nrules, output_index, multiple, membership_only, coor_proc;
+int resolution;
+implications implication;
+defuzz defuzzyfication;
+logics family;
+
+char **rules;
+
+int char_strip(char *buf, char rem);
+int char_copy(const char *buf, char *res, int start, int stop);
+int get_nsets(FILE * fd, fpos_t position);
+int get_universe(void);
+int set_cats(void);
+
+int parse_map_file(STRING file);
+int parse_rule_file(STRING file);
+int parser(void);
+int open_maps(void);
+int create_output_maps(void);
+int get_rows(int row);
+int get_cells(int col);
+
+int HERE;
+int parse_sets(SETS * set, char buf[], const char mapname[]);
+int parse_rules(int rule_num, int n, char buf[]);
+void process_coors(char *answer);
+void show_membership(void);
+
+float implicate(void);
+float parse_expression(int n);
+float defuzzify(int defuzzification, float max_agregate);
+
+float f_and(float cellx, float celly, logics family);
+float f_or(float cellx, float celly, logics family);
+float f_not(float cellx, logics family);
+float fuzzy(FCELL cell, SETS * set);
+
+int parse(void);
+void display(void);
+
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/main.c
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/main.c (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/main.c 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,250 @@
+/* ***************************************************************************
+ *
+ * MODULE: r.fuzzy.system
+ * AUTHOR(S): Jarek Jasiewicz <jarekj amu.edu.pl>
+ * PURPOSE: Full fuzzy logic standalone classification system with few fuzzy logic families
+ * implication and defuzzification and methods.
+ * COPYRIGHT: (C) 1999-2010 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ *************************************************************************** */
+
+#define MAIN
+#include "local_proto.h"
+
+int main(int argc, char **argv)
+{
+ struct Option *file_vars,
+ *file_rules,
+ *par_family,
+ *par_resolution,
+ *par_defuzzify, *par_implication, *in_coor_opt, *opt_output;
+
+ struct History history;
+
+ struct Flag *out_multiple, *out_membership;
+
+ int nrows, ncols;
+ int row, col;
+ int outfd;
+ float tmp;
+ FCELL *out_buf;
+
+ int i, j, n;
+
+ G_gisinit(argv[0]);
+
+ file_vars = G_define_standard_option(G_OPT_F_INPUT);
+ file_vars->key = "maps";
+ file_vars->required = YES;
+ file_vars->description = _("Name of fuzzy variable file");
+
+ file_rules = G_define_standard_option(G_OPT_F_INPUT);
+ file_rules->key = "rules";
+ file_rules->required = NO;
+ file_rules->description = _("Name of rules file");
+
+ par_family = G_define_option();
+ par_family->key = "family";
+ par_family->type = TYPE_STRING;
+ par_family->options = "Zadeh,product,drastic,Lukasiewicz,Fodor,Hamacher";
+ par_family->answer = "Zadeh";
+ par_family->required = YES;
+ par_family->description = _("Fuzzy logic family");
+ par_family->guisection = _("Advanced options");
+
+ par_defuzzify = G_define_option();
+ par_defuzzify->key = "defuz";
+ par_defuzzify->type = TYPE_STRING;
+ par_defuzzify->options = "centroid,bisector,min_of_highest,max_of_highest,mean_of_highest";
+ par_defuzzify->answer = "bisector";
+ par_defuzzify->required = YES;
+ par_defuzzify->description = _("Defuzzyfication method");
+ par_defuzzify->guisection = _("Advanced options");
+
+ par_implication = G_define_option();
+ par_implication->key = "imp";
+ par_implication->type = TYPE_STRING;
+ par_implication->options = "minimum,product";
+ par_implication->answer = "minimum";
+ par_implication->required = YES;
+ par_implication->description = _("Implication method");
+ par_implication->guisection = _("Advanced options");
+
+ par_resolution = G_define_option();
+ par_resolution->key = "res";
+ par_resolution->type = TYPE_INTEGER;
+ par_resolution->answer = "100";
+ par_resolution->required = YES;
+ par_resolution->description = _("Universe resolution");
+ par_resolution->guisection = _("Advanced options");
+
+ in_coor_opt = G_define_option(); /* input coordinates de outlet */
+ in_coor_opt->key = "coors";
+ in_coor_opt->type = TYPE_STRING;
+ in_coor_opt->key_desc = "x,y";
+ in_coor_opt->answer = NULL;
+ in_coor_opt->required = NO;
+ in_coor_opt->multiple = NO;
+ in_coor_opt->description =
+ "Coordinate of cell for detail data (print end exit)";
+ in_coor_opt->guisection = _("Visual Output");
+
+ out_membership = G_define_flag();
+ out_membership->key = 'o';
+ out_membership->description =
+ _("Print only membership values and exit");
+ out_membership->guisection = _("Visual Output");
+
+ out_multiple = G_define_flag();
+ out_multiple->key = 'm';
+ out_multiple->description =
+ _("Create addational fuzzy output maps for every rule");
+
+
+ opt_output = G_define_standard_option(G_OPT_R_OUTPUT);
+ opt_output->description = _("Name of output file");
+ opt_output->required = NO;
+
+ if (G_parser(argc, argv))
+ exit(EXIT_FAILURE);
+
+ var_name_file = file_vars->answer;
+ rule_name_file = file_rules->answer;
+ output = opt_output->answer;
+ multiple = (out_multiple->answer != 0);
+ membership_only = (out_membership->answer != 0);
+ coor_proc = (in_coor_opt->answer) ? 1 : 0;
+
+ if(!membership_only & (!output | !rule_name_file))
+ G_fatal_error(_("for standard analysis both output and rule file are required"));
+
+ resolution = atoi(par_resolution->answer);
+ if (resolution < 10)
+ G_fatal_error(_("Universe resolution too small, choose greater value"));
+ if (resolution > 500)
+ G_warning(_("Universe resolution is very high, computation may take a long time"));
+
+ if (!strcmp(par_family->answer, "Zadeh"))
+ family = l_ZADEH;
+ else if (!strcmp(par_family->answer, "product"))
+ family = l_PRODUCT;
+ else if (!strcmp(par_family->answer, "drastic"))
+ family = l_DRASTIC;
+ else if (!strcmp(par_family->answer, "Lukasiewicz"))
+ family = l_LUKASIEWICZ;
+ else if (!strcmp(par_family->answer, "Fodor"))
+ family = l_FODOR;
+ else if (!strcmp(par_family->answer, "Hamacher"))
+ family = l_HAMACHER;
+
+ if (!strcmp(par_implication->answer, "minimum"))
+ implication = i_MIN;
+ else if (!strcmp(par_implication->answer, "product"))
+ implication = i_PROD;
+
+ if (!strcmp(par_defuzzify->answer, "centroid"))
+ defuzzyfication = d_CENTEROID;
+ else if (!strcmp(par_defuzzify->answer, "bisector"))
+ defuzzyfication = d_BISECTOR;
+ else if (!strcmp(par_defuzzify->answer, "min_of_highest"))
+ defuzzyfication = d_MINOFHIGHEST;
+ else if (!strcmp(par_defuzzify->answer, "max_of_highest"))
+ defuzzyfication = d_MAXOFHIGHEST;
+ else if (!strcmp(par_defuzzify->answer, "mean_of_highest"))
+ defuzzyfication = d_MEANOFHIGHEST;
+
+ nrows = Rast_window_rows();
+ ncols = Rast_window_cols();
+
+ parse_map_file(var_name_file);
+ if (membership_only)
+ show_membership();
+
+ parse_rule_file(rule_name_file);
+ get_universe();
+ open_maps();
+
+ antecedents = (float *)G_malloc(nrules * sizeof(float));
+ agregate = (float *)G_calloc(resolution, sizeof(float));
+ if (coor_proc)
+ process_coors(in_coor_opt->answer);
+
+ outfd = Rast_open_new(output, FCELL_TYPE);
+ out_buf = Rast_allocate_f_buf();
+
+ if (multiple)
+ create_output_maps();
+
+ G_message("Calculate...");
+
+ for (row = 0; row < nrows; ++row) {
+ G_percent(row, nrows, 2);
+ get_rows(row);
+ for (col = 0; col < ncols; ++col) {
+ if (get_cells(col)) {
+ Rast_set_f_null_value(&out_buf[col], 1);
+
+ if (multiple) {
+ for (i = 0; i < nrules; ++i)
+ Rast_set_f_null_value(&m_outputs[i].out_buf[col], 1);
+ }
+ }
+ else {
+ out_buf[col] = implicate();
+ if (out_buf[col] == -9999)
+ Rast_set_f_null_value(&out_buf[col], 1);
+
+ if (multiple) {
+ for (i = 0; i < nrules; ++i)
+ m_outputs[i].out_buf[col] = antecedents[i];
+ }
+ }
+ }
+ Rast_put_row(outfd, out_buf, FCELL_TYPE);
+
+ if (multiple)
+ for (i = 0; i < nrules; ++i)
+ Rast_put_row(m_outputs[i].ofd, m_outputs[i].out_buf, FCELL_TYPE);
+ }
+ G_percent(row, nrows, 2);
+
+ G_message("Close...");
+
+
+
+ Rast_close(outfd);
+ Rast_short_history(output, "raster", &history);
+ Rast_command_history(&history);
+ Rast_write_history(output, &history);
+ set_cats();
+ /* free */
+ for (i = 0; i < nmaps; ++i) {
+ G_free(s_maps[i].sets);
+ if (s_maps[i].output)
+ continue;
+ G_free(s_maps[i].in_buf);
+ Rast_close(s_maps[i].cfd);
+ }
+ G_free(antecedents);
+ G_free(agregate);
+ G_free(out_buf);
+ G_free(s_maps);
+ G_free(s_rules);
+
+ if (multiple)
+ for (i = 0; i < nrules; ++i) {
+ G_free(m_outputs[i].out_buf);
+ Rast_close(m_outputs[i].ofd);
+ Rast_short_history(m_outputs[i].output_name, "raster", &history);
+ Rast_command_history(&history);
+ Rast_write_history(m_outputs[i].output_name, &history);
+ }
+
+ G_message("Done!");
+ exit(EXIT_SUCCESS);
+
+}
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/map_parser.c
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/map_parser.c (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/map_parser.c 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,222 @@
+#include "local_proto.h"
+
+int parse_map_file(STRING file)
+{
+ FILE *fd;
+ int line = 0;
+ char buf[500];
+ STRING mapset;
+ char map[30];
+ int nmaps2 = 0, nsets = 0;
+ fpos_t init;
+ fpos_t position;
+ int set_num;
+
+ int i;
+
+ fd = fopen(file, "r");
+ if (!fd)
+ G_fatal_error(_("Cannot open map file '%s'"), file);
+
+ fgetpos(fd, &init);
+
+ nmaps = 0;
+ /* number of maps */
+ while (fgets(buf, sizeof buf, fd)) {
+ G_strip(buf);
+ if (*buf != '%')
+ continue;
+ nmaps++;
+ }
+ s_maps = (MAPS *) G_malloc(nmaps * sizeof(MAPS));
+ fsetpos(fd, &init); /* reset position */
+
+ while (fgets(buf, sizeof buf, fd)) {
+ line++;
+
+ G_strip(buf);
+ if (*buf == '#' || *buf == 0 || *buf == '\n')
+ continue;
+
+ if (*buf != '%' && *buf != '$')
+ G_fatal_error(_("Wrong syntax at line %d: line must start with <#>, <%> or <$> or be empty line"),
+ line);
+
+ if (*buf == '%') {
+
+ fgetpos(fd, &position);
+
+ sscanf(buf, "%[^\n]", map);
+ char_strip(map, '%');
+ G_strip(map);
+ mapset = (STRING)G_find_raster2(map, "");
+
+ if (mapset == NULL && strcmp(map, "_OUTPUT_"))
+ G_fatal_error(_("Raster map <%s> not found"), map);
+
+ if (!strcmp(map, "_OUTPUT_")) {
+ strcpy(s_maps[nmaps2].name, output);
+ s_maps[nmaps2].output=1;
+ } else {
+ strcpy(s_maps[nmaps2].name, map);
+ s_maps[nmaps2].output=0;
+ }
+ s_maps[nmaps2].position = position;
+ s_maps[nmaps2].nsets = get_nsets(fd, position);
+
+
+ if (!s_maps[nmaps2].nsets)
+ G_warning(_("map <%s> has no rules"), s_maps[nmaps2].name);
+
+ if (s_maps[nmaps2].nsets)
+ s_maps[nmaps2].sets =
+ (SETS *) G_malloc(s_maps[nmaps2].nsets * sizeof(SETS));
+
+ set_num = 0;
+ while (fgets(buf, sizeof buf, fd)) {
+ G_strip(buf);
+
+ if (*buf == '#' || *buf == 0 || *buf == '\n')
+ continue;
+ if (*buf == '%')
+ break;
+
+ parse_sets(&s_maps[nmaps2].sets[set_num++], buf,
+ s_maps[nmaps2].name);
+
+ }
+ fsetpos(fd, &position);
+
+ if (nmaps2++ > nmaps)
+ G_fatal_error(_("number of maps do not match"));
+
+ }
+
+ } /* end while */
+
+ fclose(fd);
+ return 0;
+}
+
+
+int parse_sets(SETS * set, char buf[], const char mapname[])
+{
+
+ char tmp[20];
+ int i;
+
+ char_strip(buf, '$');
+
+ { /* check length of fuzzy value (cannot be longer than 20) */
+ sscanf(buf, "%[^{] %[^\n]", tmp, buf);
+ G_strip(tmp);
+
+ if (strlen(tmp) < 21)
+ strcpy(set->setname, tmp);
+ else
+ G_fatal_error(_("Map: <%s>, Membership: <%s>: Value name cannot be longer than 20 chars, but has %d chars"),
+ mapname, tmp, (int)strlen(tmp));
+ } /* check length of fuzzy value */
+
+ { /* check if side is valid (both,left,right) */
+ int done = 1;
+ STRING sides[] = { "both", "left", "right" };
+
+ char_strip(buf, '{');
+ sscanf(buf, "%[^;] %[^\n]", tmp, buf);
+
+ done = 0;
+ for (i = 0; i < 3; ++i)
+ if (strcmp(tmp, sides[i]) == 0) {
+ done = 1;
+ break;
+ }
+
+ if (done)
+ set->side = i;
+ else
+ G_fatal_error(_(" Map: <%s>, Membership: <%s>: <side> parameter must be: <left,right,both> but is: <%s>"),
+ mapname, set->setname, tmp);
+ } /* end check if side is valid */
+
+
+ { /* check number of points and order. Point number limited to 10 chars including coma */
+ char p[11];
+ int npoints;
+
+ char_strip(buf, ';');
+ sscanf(buf, "%[^;] %[^\n]", tmp, buf);
+ char_strip(tmp, ';');
+
+ npoints = set->side ? 2 : 4;
+
+ for (i = 0; i < npoints; ++i) {
+ sscanf(tmp, "%[^,] %[^\n]", p, tmp);
+
+ if (tmp[0] != ',' && i < (npoints - 1))
+ G_fatal_error(_("Map: <%s>, Variable: <%s>: Require %d points but has %d"),
+ mapname, set->setname, npoints, i + 1);
+
+ if (sscanf(p, "%f", &set->points[i]) != 1)
+ G_fatal_error(_("Map: <%s>, Variable: <%s>: Points must be numeric but is: %s or space between '-' and digit"),
+ mapname, set->setname, p);
+
+ char_strip(tmp, ',');
+
+ if (i > 0 && (set->points[i] < set->points[i - 1]))
+ G_fatal_error(_("Map: <%s>, Membership: <%s>: Points sequence must be non-declining"),
+ mapname, set->setname);
+ }
+
+ } /* check number of points and order */
+
+
+ { /* check if shape is valid (linear,sshaped,jshaped,gshaped) */
+ int done = 1;
+ STRING shapes[] = { "linear", "sshaped", "jshaped", "gshaped" };
+
+ char_strip(buf, ';');
+ sscanf(buf, "%[^;] %[^\n]", tmp, buf);
+
+ done = 0;
+ for (i = 0; i < 4; ++i)
+ if (strcmp(tmp, shapes[i]) == 0) {
+ done = 1;
+ break;
+ }
+
+ if (done)
+ set->shape = i;
+ else
+ G_fatal_error(_(" Map: <%s>, Variable: <%s>: <shape> parameter must be: <linear,sshaped,jshaped,gshaped> but is: <%s>"),
+ mapname, set->setname, tmp);
+ } /* end check if shape is valid */
+
+
+ { /* check if hedge is valid (integer) */
+ char_strip(buf, ';');
+ sscanf(buf, "%[^;] %[^\n]", tmp, buf);
+
+ if (sscanf(tmp, "%d", &set->hedge) != 1)
+ G_fatal_error(_("Map: <%s>, variable: <%s>: Hedge must be numeric but is: %s or space between '-' and digit"),
+ mapname, set->setname, tmp);
+
+ } /* end check if hedge is valid */
+
+
+ { /* check if height is valid (float 0-1) */
+ char_strip(buf, ';');
+ sscanf(buf, "%[^}] %[^\n]", tmp, buf);
+
+ if (sscanf(tmp, "%f", &set->height) != 1)
+ G_fatal_error(_("Map: <%s>, Variable: <%s>: Height must be non-negative numeric lesser than 1 but is: %s"),
+ mapname, set->setname, tmp);
+
+ if (set->height <= 0 || set->height > 1)
+ G_fatal_error(_("Map: <%s>, Variable: <%s>: Height must be non-negative numeric lesser than 1 but is: %f"),
+ mapname, set->setname, set->height);
+
+ } /* end check if height is valid */
+
+ return 0;
+}
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/r.fuzzy.system.html
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/r.fuzzy.system.html (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/r.fuzzy.system.html 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,231 @@
+<h2>OPTIONS</h2>
+
+<DL>
+<DT><b>maps</b></DT>
+<DD>A text file containing maps name and fuzzy sets connected with map definition. Maps in text file must exist on a search path, except the output map. The name of output map name is the output name parameter. In map file outmput map is marked by special name <B>_OUTPUT_</B> If maps are in different mapsets the name require @. Map names in database cannot contain following symbols: <B> %,$ and #</B>. Every map name must start with map name identifier:<B> %</B>. Every set definition connected with cetrain map must follow the map name and must start with set identifier :<B> $</B>. The set definition must be in braces { } and requires parameters separated by semicolon. Any whitespaces like spaces, tabs, empty lines are allowed and may used to visual format of rule file.
+
+<PRE>$ set_name {side; points; boundary_shape; hedge; height }</PRE>
+<UL>
+<li><B>set_name</B>: Any name of the fuzzy set. Must not contain symbols: <i> %,$ and #</i>
+<li><B>side</B>: Option indicate if set is fuzzified of both sides (both), left or right side. Available: <i>both, left, right</i>.
+<li><B>points</B>: A list containing 4 (A,B,C,D) or 2 A,B) points separated by comma. Points definine location of sets of boundaries. Points may not to be in map range, but it may lead to only 0 o 1 membership for the whole map. For "both" side parameters range between A and D defines base, but range between B and C core of the fuzzy set. Between A and B and C and D are set's boundaries. If side is "both" it require 4 points, else 2 points. Points values must be not-decreasing.
+<li><B>shape</B>: Parameter definied the shape of the fuzzy boundary. Available: <i>sshaped, linear, jshaped, gshaped</i>. The same boundaires are appled to both sides of fuzzy set.
+<li><B>hedge</B>: Shape modifier the positive number means dilatation (power the fuzzy set by 2) the negative means concetration (square root of fuzzy set). The number means number of dilatation/concetration applied on fuzzy set.
+<li><B>height</B>: Height modifier. Range from 0 to 1. The value 1 and indicate full membership beteen points B and C. If height is lesser than one the maximum memebrship is equal to height.
+</UL>
+<P>An example of fuzzy sets definiton:
+<PRE>$ moderate {both; 90,100,120,130; sshaped; 0; 1}</PRE>
+
+<B>Special notes about sets definition for output map:</B><BR>
+These sets shall be created as triangular (both sides) sets with linear boundaries, without hedge and height modifiers:
+<PRE>$ moderate {both; 0,20,20,40; linear; 0; 1}</PRE>
+</DD>
+
+<DT><b>rules</b></DT>
+<DD>A text file containing rules for classification.Th typical fuzzy rule consists of one or more antecedents and one consequent:
+
+<PRE>IF elev IS high AND distance IS low THEN probability IS small
+
+where:
+antecetends: elev IS high; distance IS low
+consequent: probability IS small
+</PRE>
+
+The rule file has his own syntax. Because module creates only one result map, the map name is ommited. Every rule starts with $ and consist of consequent name and antecedents in braces { }. All maps and sets used in atecednets must be included in the maps file. At the begining of the calculation program checks if all names and sets are included in maps file. Names of the rules must be same as sets names of the output map. The rules file use following symbols:
+<UL>
+<li>IS is symbolised by <B>=</B>
+<li>IS NOT is symbolised by <B>~</B>
+<li>AND is symbolised by <B>&</B>
+<li>OR is symbolised by <B>|</B>
+<li>To specify the order of operators must use parentheses <B>()</B>.
+</UL>
+
+
+<P>An example of fuzzy rules definiton:
+<PRE>
+$ small {distance = high & elev = high}
+</PRE>
+
+</DD>
+</DL>
+<h2>ADVANCED OPTIONS</h2>
+In most cases default options shoud not be changed.
+<DL>
+<DT><b>family</b></DT>
+<DD>AND and OR operations in fuzzy logic are made with T-norms, T-conorms. T-norms, T-conorms are a generalization of the two-valued logical conjunction and disjunction used by boolean logic, for fuzzy logics. Because there is more than one possible generalisation of logial operations, r.fuzzy.system provides 6 most popular families for fuzzy operations:
+<ul>
+<li><b>Zadeh</b> with minimum (Godel) t-norm and maximum T-conorm;
+<li><b>product</b> with product T-norm and probabilistic sum as T-conorm;
+<li><b>drastic</b> with drastic T-norm and drastic T-conorm;
+<li><b>Lukasiewicz</b> with Lukasiewicz T-norm and bounded sum as a T-conorm;
+<li><b>Fodor</b> with nilpotent minimum as T-norm and nilpotent maximum as T-conorm;
+<li><b>Hamacher</b> (simplified) with Hamacher product as T-norm and Einstein sum as T-conorm;
+</ul>
+<P>
+<TABLE cellspacing=4>
+<TR><TH>Family</TH><TH> T-NORM (AND) </TH><TH>T CONORM (OR) </TH></TR>
+<TR><TD>ZADEH</TD><TD> MIN(x,y)</TD><TD>MAX(x,y)</TD></TR>
+<TR><TD>PRODUCT</TD><TD> x*y </TD><TD>x + y -x * y</TD></TR>
+<TR><TD>DRASTIC </TD><TD>IF MAX(x, y) == 1 THEN MIN(x, y) ELSE 0 </TD><TD>IF (MIN(x, y) == 0) THEN MAX(x, y) ELSE 1</TD></TR>
+<TR><TD>LUKASIEWICZ</TD><TD> MAX((x+y-1),0)</TD><TD> MIN((x+y),1)</TD></TR>
+<TR><TD>FODOR </TD><TD>IF (x+y)>1 THEN MIN(x,y) ELSE 0 </TD><TD>IF (x+y<1) THEN MAX(x,y) ELSE 1</TD></TR>
+<TR><TD>HAMACHER</TD><TD> IF (x==y==0) THEN 0 ELSE (x*y)/((x+y)-x*y)</TD><TD> (x+y)/(1+x*y)</TD></TR>
+</TABLE>
+</DD>
+<DT><b>imp: implication </b></DT>
+<DD>Imlication determines the method of reshapening of consequents (fuzzy set) by antecedents (single value) :
+<UL>
+<li><B>minimum</B> means the lowest value of the antecedtents and output set definition. It ussually creates trapezoidal consequent set definition.
+<li><B>product</B> means the multiplication of the antecedtents and output set definition. It ussually creates triangular consequent set definition.
+</UL>
+</DD>
+<DT><b>defuzz: deffuzyfication method</b></DT>
+<DD>Before deffuzification all consequents are agregated into one fuzzy set. Defuzzification is the process of conversion of aggregated fuzzy set into one crisp value. The r.fuzzy.system provides 5 methods of deffuzyfication:
+<UL>
+<li><B>centroid</B> center of mass of the fuzzy set (in practise weighted mean);
+<li><B>bisector</B> a value wchich divide fuzzy set on two parts of equal area;
+<li><B>min</B> min (right limit) of highest part of the set;
+<li><B>mean</B> mean (center) of highest part of the set;
+<li><B>max</B> max (left limit) of highest part of the set;
+</UL>
+</DD>
+<DT><b>res: universe resolution</b></DT>
+<DD>The universe is an interval between the lowest and highest values of consequent and agregated fuzzy sets. The resolution provides number of elements of these fuzzy sets. The minimum and maximum for univese is taken from the minimal and maximal values of fuzzy set definition of output map Because it has strong impact on computation time and precision of deffuzification, values lower than 30 may impact on precision of final result, but values above 200 may slow down computation time.
+</DD>
+</DL>
+<h2>VISUAL OUTPUT</h2>
+<DL>
+<DT><b>coordinates</b></DT>
+<DD>Coordinates of points for which output: universe, all consequents sets and agregate set. It is useful for visual presentation or detail analysis of fuzzy rules behaviour. In that cases calculations are peroforemd n=only for selected point.</DD>
+<DT><b>membership only flag</b></DT>
+<DD>Prints for all maps sat of values in map range (map universe) and values of fuzzy sets (linguistic values). Number of values is taken from resolution (default 100). This option is useful for visual control fuzzy set definitions for evrey map.</DD>
+</DL>
+
+<h2>OUTPUTS</h2>
+<DL>
+<DT><b>output</b></DT>
+<DD>Map containing deffuzified values. Map is always of type FCELLS and contains values defined in output universe. The output name must be the same as one of maps in maps definition file.
+</DD>
+<DT><b>multipe output flag</b></DT>
+<DD>This flag is used to create fuzzified maps for every rule. The name of the map consist of otput map name, '_' and rule name (for example: output=probs and rule name high, the map name: probs_high). Values of maps ranges from 0 to 1. If map with such name exists will be overwritten without warning.
+</DD>
+</DL>
+<h2>NOTES</H2>
+<H4>Calculation of boundary shape</H4>
+Depending on type of the boundary different equation are used to determine its shape:
+<P>
+<B>Linear:</B> the membership is calculated according following equation:<br>
+
+<pre><code>
+value <= A -> x = 0
+A< value > B -> x = (value-A)/(B-A)
+B <= value >= C -> x = 1
+C< value > D -> x = (D-value)/(D-C)
+value >= D -> x = 0
+</code></pre>
+<B>S-shaped, G-shaped and J shaped:</B> use following equation to sommoth boundary:
+<pre><code>
+sin(x * Pi/2)^2 (for S-shaped)
+tan(x * Pi/4)^2 (for J-shaped)
+tan(x * Pi/4)^0.5 (for G-shaped)
+
+where:
+x current fuzzy value
+A,B,C,D inflection point,
+</code></pre>
+
+<h2>EXAMPLE</H2>
+<P>
+Fuzzy sets are sets whose elements have degrees of membership. Zadeh (1965) introduced Fuzzy sets as an extension of the classical notion of set. Classical membership of elements in a set are binary terms: an element either belongs or does not belong to the set. Fuzzy set theory use the gradual membership of elements in a set. A membership function use values in the real unit interval [0, 1]. Classical sets, are special cases of the membership functions of fuzzy sets and only take values 0 or 1. Classical sets are in fuzzy set theory usually called crisp sets. The fuzzy set theory can be used in a wide range of domains in which information is imprecise, such as most of the GIS operations.
+<P>
+Suppose we want to determine the flood risk on some area (Spearfish dataset) using two maps: distance to streams and elevation above streams. We can write some common sense rules:
+<PRE>
+IF elevation IS low AND distance IS near THEN risk IS veryprobable
+IF elevation IS low OR distance IS near THEN risk IS probable
+IF elevation IS high AND distance IS far THEN risk IS unprobable
+</PRE>
+In clasical boolean sense, we would taken some limits of ideas "near" "far" etc, but what about walues near the limit? The fuzzy set uses partial memberships which abolish these restrictions. In that sense to set "near" belongs all areas with distance no more than 100 m with full membership and from 100 to 200 m with partial membership grater than 0. Over 200 m we can assume that is not near.
+This allow to formulate fuzzy rules for distance map:
+<PRE>
+near: BELOW 100 = 1; FROM 100 TO 200 = {1 TO 0}; ABOVE 200 = 0;
+</PRE>
+
+To recive final map program calculate partial fuzzy set for all rules and next agregate it into one fuzzy set. These fuzzy sets are created on value sequence called universe. Every set has the number of elements equal to universe resolution. Such set cannot be stored as map so finally is deffuzified with method choosen by user.
+<P>
+First we need two maps created with r.stream package:
+
+<PRE>
+r.stream.extract elevation=elevation.10m at PERMANENT threshold=2000 stream_rast=streams direction=dirs
+r.stream.order stream=streams dir=dirs horton=horton
+r.mapcalc "horton3=if(horton>2,horton,null())"
+r.stream.distance stream=streams dir=dirs dem=elevation.10m method=downstream distance=distance elevation=elevation
+</PRE>
+
+Next, to perform analysis we need two files: one with definition of map used in analysis and definition of fuzzy sets for every map, and second with fuzzy rules. For this example:
+
+<P>MAPS
+<PRE>
+#flood.map
+ %elevation
+$ low {right; 2,6; sshaped; 0; 1}
+$ high {left; 2,6; sshaped; 0; 1}
+ %distance
+$ near {right; 40,80; sshaped; 0; 1}
+$ far {left; 40,80; sshaped; 0; 1}
+#output map
+ %flood
+$ unprob {both; 0,20,20,40; linear; 0;1}
+$ prob {both; 20,40,40,60; linear; 0;1}
+$ veryprob {both; 40,60,60,80; linear; 0;1}
+
+</PRE>
+<P>RULES:
+<PRE>
+#flood.rul
+$ unprob {elevation = high & distance = far}
+$ prob {distance = near | elevation = low}
+$ veryprob {distance = near & elevation = low}
+</PRE>
+
+finally we need run r.fuzzy.system:
+<PRE>
+r.fuzzy.system maps=flood.map rules=flod.rul output=flood
+</PRE>
+
+Resulting map should look like this below. Yellow color means no risk, red high risk, green, blue end so on moderate risk.
+<CENTER><img src=f_result.png border=1></CENTER><br>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.fuzzy.logic.html">r.fuzzy.logic</a>,
+<a href="r.fuzzy.set.html">r.fuzzy.set</a>,
+<a href="r.mapcalc.html">r.mapcalc</a>,
+</em>
+
+
+
+<h2>REFERENCES</h2>
+
+Zadeh, L.A. (1965). "Fuzzy sets". Information and Control 8 (3): 338–353. doi:10.1016/S0019-9958(65)90241-X. ISSN 0019-9958.<P>
+
+Novák, Vilém (1989). Fuzzy Sets and Their Applications. Bristol: Adam Hilger. ISBN 0-85274-583-4.<P>
+
+Klir, George J.; Yuan, Bo (1995). Fuzzy sets and fuzzy logic: theory and applications. Upper Saddle River, NJ: Prentice Hall PTR. ISBN 0-13-101171-5.<P>
+
+Klir, George J.; St Clair, Ute H.; Yuan, Bo (1997). Fuzzy set theory: foundations and applications. Englewood Cliffs, NJ: Prentice Hall. ISBN 0133410587.<P>
+
+Meyer D, Hornik K (2009a). \Generalized and Customizable Sets in R." Journal of Statistical Software, 31(2), 1{27. URL http://www.jstatsoft.org/v31/i02/.<P>
+
+Meyer D, Hornik K (2009b). sets: Sets, Generalized Sets, and Customizable Sets. R~package version~1.0, URL http://CRAN.R-project.org/package=sets.<P>
+
+<h2>AUTHOR</h2>
+Jarek Jasiewicz
+
+
+
+<h2>SEE ALSO</h2>
+<em>
+<a href="r.fuzzy.html">r.fuzzy</a>,
+<a href="r.mapcalc.html">r.mapcalc</a>,
+</em>
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/rule_parser.c
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/rule_parser.c (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/rule_parser.c 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,309 @@
+#include "local_proto.h"
+
+int parse_rule_file(STRING file)
+{
+ FILE *fd;
+ char buf[1000];
+ char tmp[30];
+ STRING mapset;
+ char map[30];
+ fpos_t init;
+ int rule_num = 0;
+ int n = 0, i;
+
+ fd = fopen(file, "r");
+ if (!fd)
+ G_fatal_error(_("Cannot open rules file '%s'"), file);
+
+ fgetpos(fd, &init);
+
+ while (fgets(buf, sizeof buf, fd)) {
+ G_strip(buf);
+ if (*buf != '$')
+ continue;
+ nrules++;
+ }
+
+ s_rules = (RULES *) G_malloc((nrules) * sizeof(RULES));
+ rules = (char **)G_malloc((nrules) * sizeof(char *));
+ for (i = 0; i < nrules; ++i)
+ rules[i] = (char *)G_malloc(21 * sizeof(char));
+
+ fsetpos(fd, &init); /* reset position */
+
+ for (n = nmaps; n > 0; --n)
+ if (!strcmp(s_maps[n - 1].name, output))
+ break; /*max index of output map */
+
+ if (n == 0)
+ G_fatal_error(_("No defininition for output map: <%s> in map file"),
+ output);
+
+ while (fgets(buf, sizeof buf, fd)) {
+ G_strip(buf);
+ if (*buf != '$')
+ continue;
+
+ parse_rules(rule_num++, n, buf);
+
+ /* next rule */
+ }
+
+ for (i = 0; i < nrules; ++i)
+ G_free(rules[i]);
+ G_free(rules);
+ fclose(fd);
+ return 0;
+
+} /* END parse_rule_file */
+
+
+
+int parse_rules(int rule_num, int n, char buf[])
+{
+
+ int i, j, l, o;
+ int done = 1;
+ int stack_top;
+ char tmp[30];
+ char opr[] = { '=', '&', '|', '~', '(', ')', '{', '}' };
+
+ i = j = stack_top = 0; /* variables of the while loop */
+ char_strip(buf, '$');
+
+
+ { /* check the name of fuzzy value (must be defined in rules) */
+ int s, p;
+
+ sscanf(buf, "%[^{] %[^\n]", tmp, buf);
+ G_strip(buf);
+ G_strip(tmp);
+
+ for (p = 0; p <= rule_num; ++p)
+ strcpy(rules[p],"");
+
+ done = 1;
+ for (s = 0; s <= s_maps[n - 1].nsets; ++s) { /* output map */
+
+ if (!strcmp(s_maps[n - 1].sets[s].setname, tmp)) {
+
+ for (p = 0; p <= rule_num; ++p) /* check if values are unique */
+ if (!strcmp(tmp, rules[p]))
+ G_fatal_error(_("Variable value <%s> exist, Variable values must be unique"),
+ tmp);
+
+ strcpy(rules[rule_num], tmp);
+ done = 0;
+ break;
+ }
+ }
+ if (done)
+ G_fatal_error(_("Output map do not have variable value <%s>"),
+ tmp);
+ strcpy(s_rules[rule_num].outname, tmp);
+ s_rules[rule_num].output_set_index = s;
+
+ } /* check the name of fuzzy value */
+
+ /* ******************************************************************* */
+
+ { /* parse rule expression and create parse stack */
+
+
+ do {
+ for (o = 0; o < (sizeof opr); ++o) {
+ if (buf[i] == opr[o]) {
+ char_copy(buf, tmp, j, i);
+ if (i > 0) {
+ char_strip(tmp, buf[j]);
+ s_rules[rule_num].parse_queue[stack_top][0] = buf[j];
+ s_rules[rule_num].parse_queue[stack_top++][1] = '\0';
+ G_strip(tmp);
+ }
+ if (strlen(tmp)) /* is not blank */
+ strcpy(s_rules[rule_num].parse_queue[stack_top++],
+ tmp);
+
+ j = i;
+ break;
+ }
+ }
+ if (i > 999)
+ G_fatal_error(_("rule string is too long or lack of closing element"));
+
+ } while (buf[i++] != '}'); /* rule has been read */
+
+ strcpy(s_rules[rule_num].parse_queue[stack_top++], "}"); /* add closing element only if OK */
+
+
+ } /* end parse rule expression and create parse stack */
+
+ /* ******************************************************************* */
+
+
+/* { adding weight: not implemented yet
+
+ char local[900];
+ char weight[10];
+
+ sscanf(buf, "%[^}] %[^;]", local, weight);
+ char_strip(weight, '}');
+ G_strip(weight);
+ if (strlen(weight) == 0)
+ strcpy(weight, "1");
+ s_rules[rule_num].weight = atof(weight);
+ if (s_rules[rule_num].weight <= 0.)
+ G_fatal_error(_("Weight must be grater than 0 or non-number character"));
+
+ } */
+
+ { /* check if rule syntax is proper and map names and vars values exist */
+ int k;
+ int work_queue_pos = 0;
+ int lbrc = 0, rbrc = 0; /* left and right braces */
+
+ done = 1;
+ for (i = 0; i < stack_top; ++i) { /* most external loop */
+ if (*s_rules[rule_num].parse_queue[i] == '{') {
+
+ s_rules[rule_num].work_queue[work_queue_pos] = t_START;
+
+ if (i > 0)
+ G_fatal_error(_("line %d Syntax error near <%s %s>"),
+ rule_num + 1,
+ s_rules[rule_num].parse_queue[i - 1],
+ s_rules[rule_num].parse_queue[i]);
+
+ work_queue_pos++;
+ continue;
+ } /* END { */
+
+ if (*s_rules[rule_num].parse_queue[i] == '=' || *s_rules[rule_num].parse_queue[i] == '~') { /* =, ~ */
+
+ for (j = 0; j < nmaps; ++j) {
+ if (!strcmp
+ (s_rules[rule_num].parse_queue[i - 1],
+ s_maps[j].name)) {
+ for (k = 0; k < s_maps[j].nsets; ++k) {
+ if (!strcmp
+ (s_rules[rule_num].parse_queue[i + 1],
+ s_maps[j].sets[k].setname)) {
+
+ s_rules[rule_num].work_queue[work_queue_pos] =
+ t_VAL;
+ s_rules[rule_num].value_queue[work_queue_pos].
+ value = &s_maps[j].cell;
+ s_rules[rule_num].value_queue[work_queue_pos].
+ set = &s_maps[j].sets[k];
+ s_rules[rule_num].value_queue[work_queue_pos].
+ oper = *s_rules[rule_num].parse_queue[i];
+ done = 0;
+ break;
+ }
+ }
+ }
+ } /* END for j */
+
+ if (done)
+ G_fatal_error(_("There is no map <%s> or variable <%s>"),
+ s_rules[rule_num].parse_queue[i - 1],
+ s_rules[rule_num].parse_queue[i + 1]);
+ /* end for j */
+
+ if (s_rules[rule_num].work_queue[work_queue_pos - 1] != t_AND
+ && s_rules[rule_num].work_queue[work_queue_pos - 1] !=
+ t_OR &&
+ s_rules[rule_num].work_queue[work_queue_pos - 1] !=
+ t_START &&
+ s_rules[rule_num].work_queue[work_queue_pos - 1] !=
+ t_LBRC)
+ G_fatal_error(_("line %d Syntax error near <%s %s>"),
+ rule_num + 1,
+ s_rules[rule_num].parse_queue[i - 1],
+ s_rules[rule_num].parse_queue[i]);
+
+ work_queue_pos++;
+ continue;
+ } /* END =, ~ */
+
+ if (*s_rules[rule_num].parse_queue[i] == '&' || *s_rules[rule_num].parse_queue[i] == '|') { /* operators &, | */
+
+ s_rules[rule_num].work_queue[work_queue_pos] =
+ (*s_rules[rule_num].parse_queue[i] == '|') ? t_OR : t_AND;
+
+ if (s_rules[rule_num].work_queue[work_queue_pos - 1] != t_VAL
+ && s_rules[rule_num].work_queue[work_queue_pos - 1] !=
+ t_RBRC)
+ G_fatal_error(_("line %d Syntax error near <%s %s>"),
+ rule_num + 1,
+ s_rules[rule_num].parse_queue[i - 1],
+ s_rules[rule_num].parse_queue[i]);
+
+ work_queue_pos++;
+ continue;
+ } /* END &, | */
+
+ if (*s_rules[rule_num].parse_queue[i] == '(') {
+
+ s_rules[rule_num].work_queue[work_queue_pos] = t_LBRC;
+ lbrc++;
+
+ if (s_rules[rule_num].work_queue[work_queue_pos - 1] != t_AND
+ && s_rules[rule_num].work_queue[work_queue_pos - 1] !=
+ t_OR &&
+ s_rules[rule_num].work_queue[work_queue_pos - 1] !=
+ t_START &&
+ s_rules[rule_num].work_queue[work_queue_pos - 1] !=
+ t_LBRC)
+ G_fatal_error(_("line %d Syntax error near <%s %s>"),
+ rule_num + 1,
+ s_rules[rule_num].parse_queue[i - 1],
+ s_rules[rule_num].parse_queue[i]);
+
+ work_queue_pos++;
+ continue;
+ } /* END ( */
+
+ if (*s_rules[rule_num].parse_queue[i] == ')') {
+
+ s_rules[rule_num].work_queue[work_queue_pos] = t_RBRC;
+ rbrc++;
+
+ if (s_rules[rule_num].work_queue[work_queue_pos - 1] != t_VAL
+ && s_rules[rule_num].work_queue[work_queue_pos - 1] !=
+ t_RBRC)
+ G_fatal_error(_("line %d Syntax error near <%s %s>"),
+ rule_num + 1,
+ s_rules[rule_num].parse_queue[i - 1],
+ s_rules[rule_num].parse_queue[i]);
+
+ work_queue_pos++;
+ continue;
+ } /* END ) */
+
+ if (*s_rules[rule_num].parse_queue[i] == '}') {
+
+ s_rules[rule_num].work_queue[work_queue_pos] = t_STOP;
+
+ if (s_rules[rule_num].work_queue[work_queue_pos - 1] != t_VAL
+ && s_rules[rule_num].work_queue[work_queue_pos - 1] !=
+ t_RBRC)
+ G_fatal_error(_("line %d Syntax error near <%s %s>"),
+ rule_num + 1,
+ s_rules[rule_num].parse_queue[i - 1],
+ s_rules[rule_num].parse_queue[i]);
+
+ work_queue_pos++;
+ continue;
+ } /* END } */
+
+ } /* most external loop */
+
+ if (lbrc != rbrc)
+ G_fatal_error(_("line %d Left and right of braces do not match"),
+ rule_num + 1);
+
+ } /* END check if rule syntax is proper and map names and vars values exist */
+
+ return 0;
+} /* END parse_rules */
Added: grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/system.c
===================================================================
--- grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/system.c (rev 0)
+++ grass-addons/grass7/raster/r.fuzzy/r.fuzzy.system/system.c 2011-02-17 19:45:09 UTC (rev 45422)
@@ -0,0 +1,198 @@
+#include "local_proto.h"
+
+float implicate(void)
+{
+
+ int i, j;
+ //float *agregate = NULL;
+ int set_index;
+ float consequent;
+ float max_antecedent = 0;
+ float max_agregate = 0;
+ float result;
+
+ memset(agregate,0,resolution * sizeof(float));
+
+ for (j = 0; j < nrules; ++j) {
+ antecedents[j] = parse_expression(j);
+ max_antecedent =
+ (max_antecedent >
+ antecedents[j]) ? max_antecedent : antecedents[j];
+ }
+
+ if (max_antecedent == 0. && !coor_proc)
+ return -9999; /* for all rules value is 0 */
+
+ for (j = 0; j < nrules; ++j) {
+
+ if (defuzzyfication > d_BISECTOR && antecedents[j] < max_antecedent && !coor_proc)
+ continue;
+
+ set_index = s_rules[j].output_set_index;
+
+ for (i = 0; i < resolution; ++i) {
+
+ consequent = fuzzy(universe[i],
+ &s_maps[output_index].sets[set_index]);
+
+ consequent = (!implication) ? MIN(antecedents[j], consequent) :
+ antecedents[j] * consequent;
+ agregate[i] = MAX(agregate[i], consequent);
+
+ max_agregate = (max_agregate > agregate[i])
+ ? max_agregate : agregate[i];
+
+
+ if (coor_proc)
+ visual_output[i][j + 1] = consequent;
+ }
+
+ }
+ if (coor_proc)
+ for (i = 0; i < resolution; ++i)
+ visual_output[i][j + 1] = agregate[i];
+
+ result=defuzzify(defuzzyfication, max_agregate);
+ return result;
+}
+
+float parse_expression(int n)
+{
+
+ /* tokens and actions must heve the same order */
+ actions parse_tab[t_size][t_size] = {
+ /* stk -----------INPUT------------------ */
+ /* { & | ~ = ( ) } */
+ /* -- -- -- -- -- -- -- -- */
+ /* { */ {E, S, S, E, E, S, E, A},
+ /* & */ {E, R, R, E, E, S, R, R},
+ /* | */ {E, R, R, E, E, S, R, R},
+ /* ~ */ {E, E, E, E, E, E, E, E},
+ /* = */ {E, E, E, E, E, E, E, E},
+ /* ( */ {E, S, S, E, E, S, S, E},
+ /* ) */ {E, R, R, E, E, E, R, R},
+ /* } */ {E, E, E, E, E, E, E, E}
+ };
+
+ tokens operator_stack[STACKMAX];
+ float values_stack[STACKMAX];
+
+ int i = 0, k = 0;
+ int opr_top = 0;
+ int val_top = 0;
+ int set_index;
+ float f_value;
+
+
+ do {
+ if (s_rules[n].work_queue[i] == t_START) { /* first token */
+ if (i > 0)
+ G_fatal_error("operator stack error, contact author");
+ operator_stack[opr_top] = t_START;
+ continue;
+ }
+
+ if (s_rules[n].work_queue[i] == t_VAL) {
+ f_value =
+ fuzzy(*s_rules[n].value_queue[i].value, s_rules[n].value_queue[i].set);
+ values_stack[++val_top] = (s_rules[n].value_queue[i].oper == '~') ?
+ f_not(f_value, family) : f_value;
+ continue;
+ }
+
+ if (s_rules[n].work_queue[i] < t_size) {
+ switch (parse_tab[operator_stack[opr_top]]
+ [s_rules[n].work_queue[i]]) {
+
+ case E: /* error */
+ G_fatal_error("Stack error, contact author");
+ break;
+
+ case S: /* shift */
+ operator_stack[++opr_top] = s_rules[n].work_queue[i];
+ break;
+
+ case R: /* reduce */
+
+ switch (operator_stack[opr_top]) {
+
+ case t_AND:
+ values_stack[val_top - 1] =
+ f_and(values_stack[val_top],
+ values_stack[val_top - 1], family);
+ val_top--;
+ break;
+
+ case t_OR:
+ values_stack[val_top - 1] =
+ f_or(values_stack[val_top], values_stack[val_top - 1],
+ family);
+ val_top--;
+ break;
+
+ case t_RBRC:
+ opr_top--;
+ break;
+ }
+
+ opr_top--;
+ i--;
+ break;
+
+ case A: /* accept */
+
+ if (!val_top)
+ G_fatal_error("Stack error at end, contact autor");
+ return values_stack[val_top];
+
+ }
+ }
+
+ } while (s_rules[n].work_queue[i++] != t_STOP);
+
+ G_fatal_error("Parse Stack empty, contact autor");
+}
+
+
+
+float defuzzify(int defuzzyfication, float max_agregate)
+{
+ int i;
+ float d_value = 0;
+ float sum_agregate = 0;
+ float tmp;
+
+ for (i = 0; i < resolution; sum_agregate += agregate[i++]) ;
+
+ switch (defuzzyfication) {
+
+ case d_CENTEROID:
+ for (i = 0; i < resolution; ++i)
+ d_value += (universe[i] * agregate[i]);
+ return d_value / sum_agregate;
+
+ case d_BISECTOR:
+ for (i = 0, tmp = 0; (tmp += agregate[i]) < sum_agregate / 2; ++i) ;
+ return universe[i];
+
+ case d_MINOFHIGHEST:
+ for (i = 0; agregate[i] < max_agregate;++i) ;
+ return universe[i];
+
+ case d_MAXOFHIGHEST:
+ for (i = resolution; agregate[i] < max_agregate;--i) ;
+ return universe[i];
+
+ case d_MEANOFHIGHEST:
+ sum_agregate = 0;
+ for (i = 0; i < resolution; ++i) {
+ if (agregate[i] < max_agregate)
+ continue;
+ d_value += (universe[i] * agregate[i]);
+ sum_agregate += agregate[i];
+ }
+ return d_value / sum_agregate;
+ }
+
+ return -9999;
+}
More information about the grass-commit
mailing list