lgradual_rules_classif.c

Go to the documentation of this file.
00001 /*
00002 *    Copyright (c) 2007. The BATI team. All right reserved.
00003 *
00004 *    This file is part of BATI library.
00005 *
00006 *    BATI library is free software: you can redistribute it and/or modify
00007 *    it under the terms of the GNU General Public License as published by
00008 *    the Free Software Foundation, either version 3 of the License, or
00009 *    (at your option) any later version.
00010 *
00011 *    BATI library  is distributed in the hope that it will be useful,
00012 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 *    GNU General Public License for more details.
00015 *
00016 *    You should have received a copy of the GNU General Public License
00017 *    along with BATI library.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 /*********************************************************************************
00020 **              lff_symb.c
00021 *********************************************************************************/
00022 #include <stdio.h>
00023 #include <stdarg.h>
00024 #include "image.h"
00025 #include "proto2D.h"
00026 #include "gradual_rules_classif.h"
00027 
00028 int gr_tn_zadeh
00029 (
00030          const  gr_degreApp_t*  x,
00031         const   gr_degreApp_t*  y,
00032                 gr_degreApp_t*  z
00033 ){
00034         *z      =       gr_MINI_t(*x, *y);
00035         return 0;
00036 }
00037 
00038 int gr_tc_zadeh(
00039         const   gr_degreApp_t*  x,
00040         const   gr_degreApp_t*  y,
00041                 gr_degreApp_t*  z
00042 ){
00043   *z    =       gr_MAXI_t(*x, *y);
00044         return 0;
00045 }
00046 
00047 int gr_tn_proba(
00048         const   gr_degreApp_t*  x,
00049         const   gr_degreApp_t*  y,
00050                 gr_degreApp_t*  z
00051 ){
00052         *z      =       (*x)  *  (*y);
00053         return 0;
00054 }
00055 
00056 int gr_tc_proba(
00057         const   gr_degreApp_t*  x,
00058         const   gr_degreApp_t*  y,
00059                 gr_degreApp_t*  z
00060 ){
00061         (*z)    =       (*x) + (*y) - (*x)*(*y);
00062         return 0;
00063 }
00064 
00065 int gr_tn_luk(
00066         const   gr_degreApp_t*  x,
00067         const   gr_degreApp_t*  y,
00068                 gr_degreApp_t*  z
00069 ){
00070         gr_degreApp_t   tmp;
00071         tmp     =       *x+*y-1;
00072         *z      =       gr_MAXI_t(tmp,0);
00073 }
00074 
00075 int gr_tc_luk(
00076         const   gr_degreApp_t*  x,
00077         const   gr_degreApp_t*  y,
00078                 gr_degreApp_t*  z
00079 ){
00080         gr_degreApp_t   tmp;
00081         tmp     =       *x+*y;
00082         *z      =       gr_MINI_t(tmp,1);
00083 }
00084 
00085 int gr_tn_weber(
00086         const   gr_degreApp_t*  x,
00087         const   gr_degreApp_t*  y,
00088                 gr_degreApp_t*  z
00089 ){
00090         (*z)    =       (*x == 1) ? (*y) : ((*y == 1) ? (*x) : (0));
00091         return 0;
00092 }
00093 
00094 int gr_tc_weber(
00095         const   gr_degreApp_t*  x,
00096         const   gr_degreApp_t*  y,
00097                 gr_degreApp_t*  z
00098 ){
00099         (*z)    =       (*x == 0) ? (*y) : ((*y == 0) ? (*x) : (1));
00100         return 0;
00101 }
00102 
00103 
00104 int gr_op_Rescher_Gaines(
00105         const   gr_degreApp_t*  x,
00106         const   gr_degreApp_t*  y,
00107                 gr_degreApp_t*  z
00108 ){
00109         (*z)    =       (*x > *y) ? (0) : (1);
00110 }
00111 
00112 /*initialisation*/
00113 gr_init(char * filename, gr_fctAppartenance_t * fct, gr_lesRegles_t * rules, gr_descripteur_t *dpteur)
00114 {
00115     FILE * fin;
00116     int i, j, tmp;
00117     int nb_regle=1;
00118     gr_chaine_t var;
00119     /*ouverture du fichier contenant les parametres*/
00120     if( (fin=fopen(filename, "r")) == NULL) {
00121         printf("ERREUR: impossible d'ouvrir le fichier %s\n", filename);
00122         exit(1);
00123     }
00124         
00125     /*lecture et allocation du nombre d'entrée*/
00126 
00127     fscanf(fin, "%d", &tmp);
00128     fct->nb_entree = (unsigned char)tmp;
00129     if( (fct->partition=(gr_partition_t *)malloc(fct->nb_entree*sizeof(gr_partition_t))) ==NULL){ 
00130         printf("problème d'allocation mémoire.\n");     exit(1);     }
00131 
00132     /*Pour chaque entree, lecture de son nom et de son nombre de fonction d'appartenance*/
00133     for(i=0; i<fct->nb_entree; i++)
00134         {
00135 
00136             fscanf(fin, "%s %d", fct->partition[i].nom, &tmp );
00137             fct->partition[i].nb_fct = (unsigned char)tmp;
00138             if( (fct->partition[i].part = (gr_symbol_t *)malloc(fct->partition[i].nb_fct*sizeof(gr_symbol_t))) == NULL){
00139                 printf("problème d'allocation mémoire.\n");
00140                 exit(1);
00141             }
00142 
00143 
00144             /*Pour chaque fonction d'appartenance, lecture de son nom et de ses parametres*/
00145             for(j=0; j<fct->partition[i].nb_fct; j++)
00146               {
00147                 fscanf(fin, "%s %d", fct->partition[i].part[j].nom,  &fct->partition[i].part[j].type);
00148                 if (fct->partition[i].part[j].type > 1 && fct->partition[i].part[j].type < 6)
00149                   fscanf(fin, "%f %f", &fct->partition[i].part[j].gauche, &fct->partition[i].part[j].droite);
00150               }
00151         }
00152 
00153 
00154         
00155     /*allocation de la table de règles et initialisation*/
00156  
00157     fscanf(fin, "%d", &rules->nb_regle);
00158 
00159     if( (rules->regle=(gr_uneRegle_t *)malloc(rules->nb_regle * sizeof(gr_uneRegle_t))) ==NULL){
00160         printf("problème d'allocation mémoire.\n");
00161         exit(1);
00162     }
00163     /*allocation du nombre d'entrée par regle*/
00164     for(i=0; i<rules->nb_regle; i++)
00165         if( (rules->regle[i].liste_in = (unsigned char *)calloc( fct->nb_entree-1, sizeof(unsigned char)) ) == NULL){
00166             printf("problème d'allocation mémoire.\n");
00167             exit(1);
00168         }
00169         
00170 
00171     /*lecture des regles*/
00172 
00173     for(j=0; j<rules->nb_regle; j++) 
00174       {    
00175         for(i=0; i<fct->nb_entree-1; i++)
00176           {
00177             fscanf(fin, "%s", var);
00178             tmp = 0;
00179             while(strcmp(var,fct->partition[i].part[tmp].nom)!=0)
00180               tmp++;
00181             rules->regle[j].liste_in[i] = tmp;
00182           }
00183         fscanf(fin, "%s %f", var, &rules->regle[j].ponderation );
00184         tmp = 0;
00185         while(strcmp(var,fct->partition[fct->nb_entree-1].part[tmp].nom)!=0)
00186           tmp++;
00187         rules->regle[j].nom_out = tmp;
00188 
00189       }
00190 
00191     fclose(fin);
00192 
00193     /*allocation des descripteurs*/
00194 
00195     dpteur->nb_descripteur = fct->nb_entree;
00196     if( (dpteur->descript = (gr_ssEnsFlouSymb_t *)malloc(dpteur->nb_descripteur*sizeof(gr_ssEnsFlouSymb_t))) == NULL) {
00197             printf("problème d'allocation mémoire.\n");
00198             exit(1);
00199         }
00200     for(i=0; i<fct->nb_entree; i++)
00201         if( (dpteur->descript[i] = (gr_degreApp_t *)malloc(fct->partition[i].nb_fct*sizeof(gr_degreApp_t))) == NULL) {
00202             printf("problème d'allocation mémoire.\n");
00203             exit(1);
00204         }
00205  
00206     
00207 }
00208 
00209 int grClassif_init_set_pfi(
00210         gr_fusionFloue_t*       ff
00211 ){
00212   int i;
00213   for (i=0; i<3; i++)
00214     switch(ff->oper[i]){
00215         case 0:
00216             ff->op[i]   =       gr_tn_zadeh;
00217             break;
00218         case 1:
00219             ff->op[i]   =       gr_tn_proba;
00220             break;
00221         case 2:
00222             ff->op[i]   =       gr_tn_luk;
00223             break;
00224         case 3:
00225             ff->op[i]   =       gr_tn_weber;
00226             break;
00227         case 4:
00228             ff->op[i]   =       gr_tc_zadeh;
00229             break;
00230         case 5:
00231             ff->op[i]   =       gr_tc_proba;
00232             break;
00233         case 6:
00234             ff->op[i]   =       gr_tc_luk;
00235             break;
00236         case 7:
00237             ff->op[i]   =       gr_tc_weber;
00238             break;
00239         case 8:
00240             ff->op[i]   =       gr_op_Rescher_Gaines;
00241             break;
00242         default:
00243             printf("Erreur sur le choix du type d'operateur\n");
00244             exit(1);
00245             break;
00246     }
00247     return 0;
00248 }
00249         
00250 
00251 /* ************************************/
00252 float
00253 gr_calcul_premisse(
00254         gr_fctAppartenance_t*       fct,
00255         gr_descripteur_t*               desc,
00256         unsigned char*          liste,
00257         int (*oper3)()
00258 ){
00259     int l;
00260     float premisse;
00261     (*oper3)(&desc->descript[0][liste[0]],&desc->descript[1][liste[1]], &premisse);
00262     /*pour tous les mots de la liste de la regles selectionnee*/
00263            for(l=2; l<fct->nb_entree-1; l++)
00264       /*mise a jour de la premisse connaissant la position du degree pour le mot l*/
00265              (*oper3)(&premisse, &desc->descript[l][liste[l]], &premisse);
00266     return(premisse);
00267 }
00268 
00269 
00270 gr_degreApp_t gr_appartenance (float x, gr_symbol_t s)     
00271 {
00272 
00273   switch(s.type){
00274   case 0:
00275     return(0.0);
00276   case 1:
00277     return(1.0);
00278   case 2:
00279     if (x <= s.gauche)    
00280             return (0.0);
00281     else
00282       if (x >= s.droite)
00283             return (1.0);
00284       else
00285         return (x / (s.droite - s.gauche) + s.gauche / (s.gauche - s.droite));
00286   case 3:
00287     if (x <= s.gauche)    
00288             return (1.0);
00289     else
00290       if (x >= s.droite)
00291             return (0.0);
00292       else
00293         return (x / (s.gauche - s.droite) + s.droite / (s.droite - s.gauche));
00294   case 4:
00295     if (x >= s.gauche && x <= s.droite)
00296       return (1.0);
00297     else
00298       return (0.0);
00299   case 5:
00300    if (x >= s.gauche && x <= s.droite)
00301       return (0.0);
00302     else
00303       return (1.0);
00304   default:
00305     printf("Erreur dans la fonction appartenance");
00306     break;
00307   }
00308 
00309     return(0.0);
00310 }
00311 
00312 
00313 gr_fuzzification(float *val, gr_fctAppartenance_t *fct, gr_descripteur_t *desc)
00314 {                              
00315     int i, j;
00316     /* pour toutes les entrees du systeme */
00317     for(i=0; i<fct->nb_entree-1; i++)
00318         /*pour toutes les fonctions d'appartenance décrivant l'entrée i*/
00319         for(j=0; j<fct->partition[i].nb_fct; j++)
00320             /* calcul du degre d'appartenance*/
00321           desc->descript[i][j] = gr_appartenance(val[i],fct->partition[i].part[j]);
00322   
00323 }
00324 
00325 
00326 
00327 /* ************ defuzzification *******/
00328 int gr_defuzzification(float *result, gr_fctAppartenance_t *fct, gr_descripteur_t * desc, int t) 
00329 {
00330     int i; 
00331     float max=0.0, num=0.0, denum=0.0;
00332     int mot=0;
00333 
00334     switch(t){
00335     case 0:
00336         /* la classe max est retourne et tous les  degres vont dans result*/
00337         for(i=0; i<fct->partition[fct->nb_entree-1].nb_fct; i++) {
00338             result[i]=desc->descript[fct->nb_entree-1][i];
00339             if( desc->descript[fct->nb_entree-1][i] > max ){
00340                 max = desc->descript[fct->nb_entree-1][i];
00341                 mot = i;
00342             }
00343         }
00344         return(mot);
00345         break;
00346     case 1:
00347         /* */
00348         for(i=0; i<fct->partition[fct->nb_entree-1].nb_fct; i++){
00349             num = num + desc->descript[fct->nb_entree-1][i] * fct->partition[fct->nb_entree-1].part[i].mode;
00350             denum = denum + desc->descript[fct->nb_entree-1][i];
00351         }
00352         result[0] = (float)(num/denum);
00353         break;
00354     default:
00355         printf("type defuzzification incorrect\n");
00356         exit(1);
00357     }
00358  }
00359 
00360 
00361 /***************** inference *********/
00362 int
00363 gr_inference(
00364         gr_fctAppartenance_t*   fct,
00365         gr_lesRegles_t*         rules,
00366         gr_descripteur_t*               desc,
00367         int (*oper2) (),
00368         int (*oper1) (),
00369         int (*oper3) ()
00370 ){
00371   int s, r, k;
00372     float premisse, combinaison, projection;
00373 
00374     /*Pour tous les mots definisants la variable de  sorties*/
00375     for (s=0; s<fct->partition[fct->nb_entree-1].nb_fct; s++)
00376         {
00377           k=0;
00378             /*test de toutes les regles*/
00379             for(r=0; r<rules->nb_regle; r++)
00380               {     if( rules->regle[r].nom_out == s)
00381                         {
00382                           k++;
00383                             /*si regle OK alors calcul de la premisse correspondante*/
00384                             premisse = gr_calcul_premisse(fct, desc, rules->regle[r].liste_in, (*oper3));
00385                             /*combinaison*/
00386                             (*oper2)( &premisse, &rules->regle[r].ponderation, &combinaison);
00387                             if (k==1)
00388                               projection=combinaison;
00389                             else
00390                             /*projection*/
00391                             (*oper1)( &projection, &combinaison, &projection );
00392                         }
00393                 }
00394             desc->descript[desc->nb_descripteur-1][s] = projection;
00395             //printf("%.2f/%s ", projection, fct->partition[fct->nb_entree-1].part[s].nom );
00396         }
00397  }
00398 
00465 
00484 param *grClassif_lect( gr_fusionFloue_t *d, param *ptp, char *debq)
00485 {
00486     char question[500];
00487 
00488     sprintf(question, "%s fichier d'initialisation", debq); 
00489     lec_param(question, ptp);
00490     d->nom = ptp->rep;
00491     ptp = ptp->next;
00492 
00493     sprintf(question, "%s type de l'operateur pour premisse (0-8)", debq);
00494     lec_param(question, ptp);
00495     d->oper[2] = atoi(ptp->rep);
00496     ptp = ptp->next;
00497 
00498     sprintf(question, "%s type de l'operateur pour combinaison (0-8)", debq);
00499     lec_param(question, ptp);
00500     d->oper[1] = atoi(ptp->rep);
00501     ptp = ptp->next;
00502 
00503     sprintf(question, "%s type de l'operateur pour projection (0-8)", debq);
00504     lec_param(question, ptp);
00505     d->oper[0] = atoi(ptp->rep);
00506     ptp = ptp->next;
00507 
00508     sprintf(question, "%s type de défuzzification (0-1)", debq);
00509     lec_param(question, ptp);
00510     d->defuzz = atoi(ptp->rep);
00511     ptp = ptp->next;
00512 
00513 
00514 
00515     return(ptp);
00516  }
00517 
00518 
00519 
00527 int grClassif_init(gr_fusionFloue_t *d){
00528     gr_init(d->nom, &d->fonction, &d->rgl, &d->des);
00529     grClassif_init_set_pfi( d);
00530  }
00531 
00532 
00533 
00542 int
00543 grClassif_calc(
00544                 gr_fusionFloue_t*       d,
00545                 gr_degreApp_t*  data,
00546                 gr_degreApp_t*  result
00547 ){
00548 
00549     gr_fuzzification(data, &d->fonction, &d->des);
00550     gr_inference(       &d->fonction,
00551                 &d->rgl,
00552                 &d->des,
00553                 d->op[1],
00554                 d->op[0],
00555                 d->op[2] 
00556                 );
00557 
00558  int res=gr_defuzzification(result, &d->fonction, &d->des, d->defuzz);
00559 
00560  return res;
00561 
00562  }
00563 

Generated on Tue Apr 22 13:31:02 2008 for donnee1D by  doxygen 1.5.3