lff_symb.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 /*
00023  ensemble de fonction pour l'operateur de fusion floue symbolique
00024 */
00025 
00026 #include <stdio.h>
00027 #include <stdarg.h>
00028 #include "image.h"
00029 #include "proto2D.h"
00030 #include "ff_symb.h"
00031 
00032 
00033 int
00034 tn_zadeh(
00035         const   degre_app*      x,
00036         const   degre_app*      y,
00037                 degre_app*      z
00038 ){
00039         *z      =       MINI(*x, *y);
00040         return 0;
00041 }
00042 
00043 int tc_zadeh(
00044         const   degre_app*      x,
00045         const   degre_app*      y,
00046                 degre_app*      z
00047 ){
00048         *z      =       MAXI(*x, *y);
00049         return 0;
00050 }
00051 
00052 int tn_proba(
00053         const   degre_app*      x,
00054         const   degre_app*      y,
00055                 degre_app*      z
00056 ){
00057         *z      =       (*x)  *  (*y);
00058         return 0;
00059 }
00060 
00061 int tc_proba(
00062         const   degre_app*      x,
00063         const   degre_app*      y,
00064                 degre_app*      z
00065 ){
00066         (*z)    =       (*x) + (*y) - (*x)*(*y);
00067         return 0;
00068 }
00069 
00070 int tn_luk(
00071         const   degre_app*      x,
00072         const   degre_app*      y,
00073                 degre_app*      z
00074 ){
00075         degre_app       tmp;
00076         tmp     =       *x+*y-1;
00077         *z      =       MAXI(tmp,0);
00078 }
00079 
00080 int tc_luk(
00081         const   degre_app*      x,
00082         const   degre_app*      y,
00083                 degre_app*      z
00084 ){
00085         degre_app       tmp;
00086         tmp     =       *x+*y;
00087         *z      =       MINI(tmp,1);
00088 }
00089 
00090 int tn_weber(
00091         const   degre_app*      x,
00092         const   degre_app*      y,
00093                 degre_app*      z
00094 ){
00095         (*z)    =       (*x == 1) ? (*y) : ((*y == 1) ? (*x) : (0));
00096         return 0;
00097 }
00098 
00099 int tc_weber(
00100         const   degre_app*      x,
00101         const   degre_app*      y,
00102                 degre_app*      z
00103 ){
00104         (*z)    =       (*x == 0) ? (*y) : ((*y == 0) ? (*x) : (1));
00105         return 0;
00106 }
00107 
00108 
00109 /*initialisation*/
00110 init(char * filename, Fct_appartenance * fct, Les_regles * rules, Descripteur *dpteur)
00111 {
00112     FILE * fin;
00113     int i, j, tmp;
00114     int nb_regle=1;
00115     chaine var;
00116     /*ouverture du fichier contenant les parametres*/
00117     if( (fin=fopen(filename, "r")) == NULL) {
00118         printf("ERREUR: impossible d'ouvrir le fichier %s\n", filename);
00119         exit(1);
00120     }
00121         
00122     /*lecture et allocation du nombre d'entrée*/
00123     printf("lecture du nombre d'entree\n");
00124     fscanf(fin, "%d", &tmp);
00125     fct->nb_entree = (unsigned char)tmp;
00126     if( (fct->partition=(Partition *)malloc(fct->nb_entree*sizeof(Partition))) ==NULL){         printf("problème d'allocation mémoire.\n");     exit(1);     }
00127 
00128     /*Pour chaque entree, lecture de son nom et de son nombre de fonction d'appartenance*/
00129     for(i=0; i<fct->nb_entree; i++)
00130         {
00131           //printf("lect des entrees %d\n",i);
00132             fscanf(fin, "%s %d", fct->partition[i].nom, &tmp );
00133             fct->partition[i].nb_fct = (unsigned char)tmp;
00134             if( (fct->partition[i].part = (Symbol *)malloc(fct->partition[i].nb_fct*sizeof(Symbol))) == NULL){
00135                 printf("problème d'allocation mémoire.\n");
00136                 exit(1);
00137             }
00138 
00139             /*Pour chaque fonction d'appartenance, lecture de son nom et de ses parametres*/
00140             for(j=0; j<fct->partition[i].nb_fct; j++)
00141                 fscanf(fin, "%s %f %f %f", fct->partition[i].part[j].nom,  &fct->partition[i].part[j].gauche, &fct->partition[i].part[j].mode, &fct->partition[i].part[j].droite);
00142         }
00143         
00144     /*allocation de la table de règles et initialisation*/
00145     //printf("lecture du nombre de regle\n");
00146     fscanf(fin, "%d", &rules->nb_regle);
00147     if( (rules->regle=(Une_regle *)malloc(rules->nb_regle * sizeof(Une_regle))) ==NULL){
00148         printf("problème d'allocation mémoire.\n");
00149         exit(1);
00150     }
00151     /*allocation du nombre d'entrée par regle*/
00152     for(i=0; i<rules->nb_regle; i++)
00153         if( (rules->regle[i].liste_in = (unsigned char *)calloc( fct->nb_entree-1, sizeof(unsigned char)) ) == NULL){
00154             printf("problème d'allocation mémoire.\n");
00155             exit(1);
00156         }
00157         
00158     /*lecture des regles*/
00159     //printf("lecture des regles\n");
00160     for(j=0; j<rules->nb_regle; j++) {    
00161       for(i=0; i<fct->nb_entree-1; i++){
00162         fscanf(fin, "%s", var);
00163         tmp = 0;
00164         while(strcmp(var,fct->partition[i].part[tmp].nom)!=0)
00165           tmp++;
00166         rules->regle[j].liste_in[i] = tmp;
00167       }
00168       fscanf(fin, "%s %f", var, &rules->regle[j].ponderation );
00169       tmp = 0;
00170       while(strcmp(var,fct->partition[fct->nb_entree-1].part[tmp].nom)!=0)
00171         tmp++;
00172       rules->regle[j].nom_out = tmp;
00173 
00174     }
00175 
00176     fclose(fin);
00177 
00178     /*allocation des descripteurs*/
00179     //printf("allocation des descripteurs\n");
00180     dpteur->nb_descripteur = fct->nb_entree;
00181     if( (dpteur->descript = (ss_ens_flou_symb *)malloc(dpteur->nb_descripteur*sizeof(ss_ens_flou_symb))) == NULL) {
00182             printf("problème d'allocation mémoire.\n");
00183             exit(1);
00184         }
00185     for(i=0; i<fct->nb_entree; i++)
00186         if( (dpteur->descript[i] = (degre_app *)malloc(fct->partition[i].nb_fct*sizeof(degre_app))) == NULL) {
00187             printf("problème d'allocation mémoire.\n");
00188             exit(1);
00189         }
00190  
00191     
00192 }
00193 
00194 int
00195 ff_symb_init_set_pfi(
00196         fusion_floue_t* ff
00197 ){
00198     switch(ff->Tnorme){
00199         case 0:
00200             ff->tn      =       tn_zadeh;
00201             break;
00202         case 1:
00203             ff->tn      =       tn_proba;
00204             break;
00205         case 2:
00206             ff->tn      =       tn_luk;
00207             break;
00208         case 3:
00209             ff->tn      =       tn_weber;
00210             break;
00211         default:
00212             printf("erreur sur le choix du type de T-norme\n");
00213             exit(1);
00214             break;
00215     }
00216     switch(ff->Tconorme){
00217         case 0:
00218             ff->tcn     =       tc_zadeh;
00219             break;
00220         case 1:
00221             ff->tcn     =       tc_proba;
00222             break;
00223         case 2:
00224             ff->tcn     =       tc_luk;
00225             break;
00226         case 3:
00227             ff->tcn     =       tc_weber;
00228             break;
00229         default:
00230             printf("erreur sur le choix du type de T-norme\n");
00231             exit(1);
00232             break;
00233     }
00234     return 0;
00235 }
00236         
00237 
00238 /* ************************************/
00239 float
00240 calcul_premisse(
00241         Fct_appartenance*       fct,
00242         Descripteur*            desc,
00243         unsigned char*          liste,
00244         int (*tnorme)()
00245 ){
00246     int l;
00247     float premisse=1.0;
00248 
00249     /*pour tous les mots de la liste de la regles selectionnee*/
00250     for(l=0; l<fct->nb_entree-1; l++)
00251       /*mise a jour de la premisse connaissant la position du degree pour le mot l*/
00252       (*tnorme)(&premisse, &desc->descript[l][liste[l]], &premisse);
00253 
00254     return(premisse);
00255 }
00256 
00257 /* ************ appartenance ***********/
00258 degre_app appartenance (float x, Symbol s)     
00259 {
00260     if (x <= s.gauche)     
00261         if(s.gauche==s.mode)
00262             return(1.0);
00263         else
00264             return (0.0);
00265 
00266     if (x <= s.mode)
00267         return ( ( x - s.gauche ) / ( s.mode - s.gauche ) );
00268 
00269     if (x <= s.droite)
00270         if ( s.droite != s.mode )
00271             return ( ( s.droite - x ) / ( s.droite - s.mode ) );
00272         else
00273             return (1.0);
00274 
00275     if ( x > s.droite)
00276         if(s.droite==s.mode)
00277             return (1.0);
00278         else
00279             return (0.0);
00280 
00281     printf("Erreur dans la fonction appartenance");
00282     return(0.0);
00283 }
00284 
00285 
00286 /* *************** fuzzification *********************/
00287 fuzzification(float *val, Fct_appartenance *fct, Descripteur *desc)
00288 {                              
00289     int i, j;
00290    
00291     /* pour toutes les entrees du systemes */
00292     for(i=0; i<fct->nb_entree-1; i++)
00293         /*pour toutes les fonctions d'appartenance décrivant l'entrée i*/
00294         for(j=0; j<fct->partition[i].nb_fct; j++)
00295             /* calcul du degre d'appartenance*/
00296             desc->descript[i][j] = appartenance(val[i],fct->partition[i].part[j]);
00297 }
00298 
00299 
00300 
00301 
00302 /* ************ defuzzification *******/
00303 int defuzzification(float *result, Fct_appartenance *fct, Descripteur * desc, int t) 
00304 {
00305   int i; 
00306   float max=0.0, num=0.0, denum=0.0;
00307   int mot=0;
00308 
00309   switch(t){
00310   case 0:
00311     /* la classe max est retourne et tous les  degres vont dans result*/
00312     for(i=0; i<fct->partition[fct->nb_entree-1].nb_fct; i++) {
00313       result[i]=desc->descript[fct->nb_entree-1][i];
00314       if( desc->descript[fct->nb_entree-1][i] > max ){
00315         max = desc->descript[fct->nb_entree-1][i];
00316         mot = i;
00317       }
00318     }
00319     return(mot);
00320     break;
00321   case 1:
00322     /* */
00323     for(i=0; i<fct->partition[fct->nb_entree-1].nb_fct; i++){
00324       num = num + desc->descript[fct->nb_entree-1][i] * fct->partition[fct->nb_entree-1].part[i].mode;
00325       denum = denum + desc->descript[fct->nb_entree-1][i];
00326     }
00327     result[0] = (float)(num/denum);
00328     break;
00329   default:
00330     printf("type defuzzification incorrect\n");
00331     exit(1);
00332   }
00333 }
00334 
00335 
00336 
00337 /***************** inference *********/
00338 int
00339 inference(
00340         Fct_appartenance*       fct,
00341         Les_regles*             rules,
00342         Descripteur*            desc,
00343         int (*tnorme) (),
00344         int (*tconorme) ()
00345 ){
00346     int s, r;
00347     float premisse, combinaison, projection;
00348 
00349     /*Pour tous les mots definisants la variable de  sorties*/
00350     for (s=0; s<fct->partition[fct->nb_entree-1].nb_fct; s++)
00351         {
00352             projection = 0.0;
00353             /*test de toutes les regles*/
00354             for(r=0; r<rules->nb_regle; r++)
00355                 {
00356                     if( rules->regle[r].nom_out == s)
00357                         {
00358                             /*si regle OK alors calcul de la premisse correspondante*/
00359                             premisse = calcul_premisse(fct, desc, rules->regle[r].liste_in, (*tnorme));
00360                             /*combinaison*/
00361                             (*tnorme)( &premisse, &rules->regle[r].ponderation, &combinaison);
00362                             /*projection*/
00363                             (*tconorme)( &projection, &combinaison, &projection );
00364                         }
00365                 }
00366             desc->descript[desc->nb_descripteur-1][s] = projection;
00367             //printf("%.2f/%s ", projection, fct->partition[fct->nb_entree-1].part[s].nom );
00368         }
00369 }
00370 
00463 param *ff_symb_lect( fusion_floue_t *d, param *ptp, char *debq)
00464 {
00465     char question[500];
00466 
00467     sprintf(question, "%s fichier d'initialisation", debq); 
00468     lec_param(question, ptp);
00469     d->nom = ptp->rep;
00470     ptp = ptp->next;
00471 
00472     sprintf(question, "%s type de Tnorme (0-3)", debq);
00473     lec_param(question, ptp);
00474     d->Tnorme = atoi(ptp->rep);
00475     ptp = ptp->next;
00476 
00477     sprintf(question, "%s type de Tconorme (0-3)", debq);
00478     lec_param(question, ptp);
00479     d->Tconorme = atoi(ptp->rep);
00480     ptp = ptp->next;
00481 
00482     sprintf(question, "%s type de défuzzification (0-1)", debq);
00483     lec_param(question, ptp);
00484     d->defuzz = atoi(ptp->rep);
00485     ptp = ptp->next;
00486 
00487     return(ptp);
00488 }
00489 
00490 
00491 
00499 int ff_symb_init(fusion_floue_t *d){
00500     init(d->nom, &d->fonction, &d->rgl, &d->des);
00501     ff_symb_init_set_pfi( d);
00502 }
00503 
00504 
00505 
00514 int
00515 ff_symb_calc(
00516                 fusion_floue_t* d,
00517                 degre_app*      data,
00518                 degre_app*      result
00519 ){
00520     fuzzification(data, &d->fonction, &d->des);
00521     inference(  &d->fonction,
00522                 &d->rgl,
00523                 &d->des,
00524                 d->tn,
00525                 d->tcn
00526                 );
00527     return( defuzzification(result, &d->fonction, &d->des, d->defuzz) );
00528 }
00529 
00530 
00537 int
00538 ff_symb_ferm(
00539         fusion_floue_t *d
00540 ){
00541         int     i;                              //iterator
00542         
00543         free( d->fonction.partition);
00544         for ( i = 0; i < d->fonction.nb_entree; i++) {
00545                 free( d->fonction.partition[i].part );
00546         }
00547         free( d->rgl.regle );
00548         free( d->des.descript );
00549         for ( i = 0; i < d->fonction.nb_entree; i++) {
00550                 free(d->des.descript[i]);
00551         }
00552         return 0;
00553 }

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