src/fuzzy.cpp

Go to the documentation of this file.
00001 #include "fuzzy.h"
00002 #include <stdlib.h>
00003 #include <math.h>
00004 
00005 fuzzy::fuzzy()
00006 {
00007         fx=NULL;
00008         min=max=0;
00009         samples=0;
00010 }
00011 fuzzy::fuzzy(float min1,float max1,int samples1)
00012 {
00013         min=min1,max=max1,samples=samples1;
00014 
00015         fx=(float *)malloc(samples*sizeof(float));
00016 }
00017 fuzzy::~fuzzy()
00018 {
00019         free(fx);
00020 }
00021 
00022 void fuzzy::setconst(float c)
00023 {
00024         int i;
00025 
00026         for(i=0;i<samples;i++) fx[i]=c;
00027 }
00028 
00029 void fuzzy::setfunction(float f(float))
00030 {
00031         int i;
00032         float x;
00033 
00034         for(i=0;i<samples;i++)
00035         {
00036                 x=min+i*(max-min)/(samples-1);
00037                 fx[i]=f(x);
00038         }
00039 }
00040 
00041 void fuzzy::settriangle(float x1,float x2,float x3)
00042 {
00043         int i;
00044         float x;
00045 
00046         for(i=0;i<samples;i++)
00047         {
00048                 x=min+i*(max-min)/(samples-1);
00049                 if((x<=x1)||(x>x3)) fx[i]=0;
00050                 if((x>x1)&&(x<=x2)) fx[i]=(x-x1)/(x2-x1);
00051                 if((x>x2)&&(x<=x3)) fx[i]=(x-x3)/(x2-x3);
00052         }
00053 
00055         // You can find more about DURIKE at: http://durike.yweb.sk or try Google ;) //
00057         //                                                                           //
00058         // Nasledovny kod bol pridany preto, aby bolo pomocou fuzzy mnoziny mozne    //
00059         // reprezentovat i uhly, ktore potrebuju mat osetrene to, ze dve hodnoty     //
00060         // vyjadruju ten isty uhol. Teda, ze 10 stupnov = 370 stupnov.               //
00061         //                                                                           //
00062         // Neosetruje sa tu ale zaporna cast!!! (Treba na to mysliet pri zadavani    //
00063         // hodnot)                                                                   //
00064         //                                                                           //
00066 
00067         if(x3 > max)    // ide o cyklicku fuzzy mnozinu?
00068         {
00069                 float rozdiel = max-min;
00070                 // posuniem hodnoty dolava o dlzku intervalu
00071                 x1 -= rozdiel;
00072                 x2 -= rozdiel;
00073                 x3 -= rozdiel;
00074                 
00075                 x = min;
00076                 i = 0;
00077 
00078                 // kym nedokoncim cast funkcie, ktora presiahla za hodnotu "max", tak opakujem
00079                 while((i < samples) && (x < x3))
00080                 {
00081                         x=min+i*(max-min)/(samples-1);
00082                         if((x<=x1)||(x>x3)) fx[i]=0;
00083                         if((x>x1)&&(x<=x2)) fx[i]=(x-x1)/(x2-x1);
00084                         if((x>x2)&&(x<=x3)) fx[i]=(x-x3)/(x2-x3);
00085                         i++;
00086                 }
00087         }
00088 }
00089 
00090 void fuzzy::settrapezoid(float x1,float x2,float x3,float x4)
00091 {
00092         int i;
00093         float x;
00094 
00095         for(i=0;i<samples;i++)
00096         {
00097                 x=min+i*(max-min)/(samples-1);
00098                 if((x<=x1)||(x>x4)) fx[i]=0;
00099                 if((x>x1)&&(x<=x2)) fx[i]=(x-x1)/(x2-x1);
00100                 if((x>x2)&&(x<=x3)) fx[i]=1;
00101                 if((x>x3)&&(x<=x4)) fx[i]=(x-x4)/(x3-x4);
00102         }
00103 
00105         // You can find more about DURIKE at: http://durike.yweb.sk or try Google ;) //
00107         //                                                                           //
00108         // Nasledovny kod bol pridany preto, aby bolo pomocou fuzzy mnoziny mozne    //
00109         // reprezentovat i uhly, ktore potrebuju mat osetrene to, ze dve hodnoty     //
00110         // vyjadruju ten isty uhol. Teda, ze 10 stupnov = 370 stupnov.               //
00111         //                                                                           //
00112         // Neosetruje sa tu ale zaporna cast!!! (Treba na to mysliet pri zadavani    //
00113         // hodnot)                                                                   //
00114         //                                                                           //
00116 
00117         if(x4 > max)    // ide o cyklicku fuzzy mnozinu?
00118         {
00119                 float rozdiel = max-min;
00120                 // posuniem hodnoty dolava o dlzku intervalu
00121                 x1 -= rozdiel;
00122                 x2 -= rozdiel;
00123                 x3 -= rozdiel;
00124                 x4 -= rozdiel;
00125                 
00126                 x = min;
00127                 i = 0;
00128 
00129                 // kym nedokoncim cast funkcie, ktora presiahla za hodnotu "max", tak opakujem
00130                 while((i < samples) && (x < x4))
00131                 {
00132                         x=min+i*(max-min)/(samples-1);
00133                         if((x<=x1)||(x>x4)) fx[i]=0;
00134                         if((x>x1)&&(x<=x2)) fx[i]=(x-x1)/(x2-x1);
00135                         if((x>x2)&&(x<=x3)) fx[i]=1;
00136                         if((x>x3)&&(x<=x4)) fx[i]=(x-x4)/(x3-x4);
00137                         i++;
00138                 }
00139         }
00140 }
00141 
00142 void fuzzy::setwell(float x1,float x2,float x3,float x4)
00143 {
00144         int i;
00145         float x;
00146 
00147         for(i=0;i<samples;i++)
00148         {
00149                 x=min+i*(max-min)/(samples-1);
00150                 if((x<=x1)||(x>x4)) fx[i]=1;
00151                 if((x>x1)&&(x<=x2)) fx[i]=(x2-x)/(x2-x1);
00152                 if((x>x2)&&(x<=x3)) fx[i]=0;
00153                 if((x>x3)&&(x<=x4)) fx[i]=(x3-x)/(x3-x4);
00154         }
00155 
00157         // You can find more about DURIKE at: http://durike.yweb.sk or try Google ;) //
00159         //                                                                           //
00160         // Nasledovny kod bol pridany preto, aby bolo pomocou fuzzy mnoziny mozne    //
00161         // reprezentovat i uhly, ktore potrebuju mat osetrene to, ze dve hodnoty     //
00162         // vyjadruju ten isty uhol. Teda, ze 10 stupnov = 370 stupnov.               //
00163         //                                                                           //
00164         // Neosetruje sa tu ale zaporna cast!!! (Treba na to mysliet pri zadavani    //
00165         // hodnot)                                                                   //
00166         //                                                                           //
00168 
00169         if(x4 > max)    // ide o cyklicku fuzzy mnozinu?
00170         {
00171                 float rozdiel = max-min;
00172                 // posuniem hodnoty dolava o dlzku intervalu
00173                 x1 -= rozdiel;
00174                 x2 -= rozdiel;
00175                 x3 -= rozdiel;
00176                 x4 -= rozdiel;
00177                 
00178                 x = min;
00179                 i = 0;
00180 
00181                 // kym nedokoncim cast funkcie, ktora presiahla za hodnotu "max", tak opakujem
00182                 while((i < samples) && (x < x4))
00183                 {
00184                         x=min+i*(max-min)/(samples-1);
00185                         if((x<=x1)||(x>x4)) fx[i]=1;
00186                         if((x>x1)&&(x<=x2)) fx[i]=(x2-x)/(x2-x1);
00187                         if((x>x2)&&(x<=x3)) fx[i]=0;
00188                         if((x>x3)&&(x<=x4)) fx[i]=(x3-x)/(x3-x4);
00189                         i++;
00190                 }
00191         }
00192 }
00193 
00194 void fuzzy::setleft(float x1,float x2)
00195 {
00196         int i;
00197         float x;
00198 
00199         for(i=0;i<samples;i++)
00200         {
00201                 x=min+i*(max-min)/(samples-1);
00202                 if(x<=x1) fx[i]=1;
00203                 if((x>x1)&&(x<=x2)) fx[i]=(x-x2)/(x1-x2);
00204                 if(x>x2) fx[i]=0;
00205         }
00206 
00208         // You can find more about DURIKE at: http://durike.yweb.sk or try Google ;) //
00210         //                                                                           //
00211         // Nasledovny kod bol pridany preto, aby bolo pomocou fuzzy mnoziny mozne    //
00212         // reprezentovat i uhly, ktore potrebuju mat osetrene to, ze dve hodnoty     //
00213         // vyjadruju ten isty uhol. Teda, ze 10 stupnov = 370 stupnov.               //
00214         //                                                                           //
00215         // Neosetruje sa tu ale zaporna cast!!! (Treba na to mysliet pri zadavani    //
00216         // hodnot)                                                                   //
00217         //                                                                           //
00219 
00220         if(x2 > max)    // ide o cyklicku fuzzy mnozinu?
00221         {
00222                 float rozdiel = max-min;
00223                 // posuniem hodnoty dolava o dlzku intervalu
00224                 x1 -= rozdiel;
00225                 x2 -= rozdiel;
00226                 
00227                 x = min;
00228                 i = 0;
00229 
00230                 // kym nedokoncim cast funkcie, ktora presiahla za hodnotu "max", tak opakujem
00231                 while((i < samples) && (x < x2))
00232                 {
00233                         x=min+i*(max-min)/(samples-1);
00234                         if(x<=x1) fx[i]=1;
00235                         if((x>x1)&&(x<=x2)) fx[i]=(x-x2)/(x1-x2);
00236                         if(x>x2) fx[i]=0;
00237                         i++;
00238                 }
00239         }
00240 }
00241 
00242 void fuzzy::setright(float x1,float x2)
00243 {
00244         int i;
00245         float x;
00246 
00247         for(i=0;i<samples;i++)
00248         {
00249                 x=min+i*(max-min)/(samples-1);
00250                 if(x<=x1) fx[i]=0;
00251                 if((x>x1)&&(x<=x2)) fx[i]=(x-x1)/(x2-x1);
00252                 if(x>x2) fx[i]=1;
00253         }
00254 
00256         // You can find more about DURIKE at: http://durike.yweb.sk or try Google ;) //
00258         //                                                                           //
00259         // Nasledovny kod bol pridany preto, aby bolo pomocou fuzzy mnoziny mozne    //
00260         // reprezentovat i uhly, ktore potrebuju mat osetrene to, ze dve hodnoty     //
00261         // vyjadruju ten isty uhol. Teda, ze 10 stupnov = 370 stupnov.               //
00262         //                                                                           //
00263         // Neosetruje sa tu ale zaporna cast!!! (Treba na to mysliet pri zadavani    //
00264         // hodnot)                                                                   //
00265         //                                                                           //
00267 
00268         if(x2 > max)    // ide o cyklicku fuzzy mnozinu?
00269         {
00270                 float rozdiel = max-min;
00271                 // posuniem hodnoty dolava o dlzku intervalu
00272                 x1 -= rozdiel;
00273                 x2 -= rozdiel;
00274                 
00275                 x = min;
00276                 i = 0;
00277 
00278                 // kym nedokonimm cast funkcie, ktora presiahla za hodnotu "max", tak opakujem
00279                 while((i < samples) && (x < x2))
00280                 {
00281                         x=min+i*(max-min)/(samples-1);
00282                         if(x<=x1) fx[i]=0;
00283                         if((x>x1)&&(x<=x2)) fx[i]=(x-x1)/(x2-x1);
00284                         if(x>x2) fx[i]=1;
00285                         i++;
00286                 }
00287         }
00288 }
00289 void fuzzy::setvalues(float *v)
00290 {
00291         int i;
00292 
00293         for(i=0;i<samples;i++) fx[i]=v[i];
00294 }
00295 
00296 void fuzzy::setandz(fuzzy &f1,fuzzy &f2)
00297 {
00298         int i;
00299 
00300         for(i=0;i<samples;i++) fx[i]=(f1.indexvalue(i)<f2.indexvalue(i))?f1.indexvalue(i):f2.indexvalue(i);
00301 }
00302 
00303 void fuzzy::setorz(fuzzy &f1,fuzzy &f2)
00304 {
00305         int i;
00306 
00307         for(i=0;i<samples;i++) fx[i]=(f1.indexvalue(i)>f2.indexvalue(i))?f1.indexvalue(i):f2.indexvalue(i);
00308 }
00309 
00310 void fuzzy::setandp(fuzzy &f1,fuzzy &f2)
00311 {
00312         int i;
00313 
00314         for(i=0;i<samples;i++) fx[i]=f1.indexvalue(i)*f2.indexvalue(i);
00315 }
00316 
00317 void fuzzy::setorp(fuzzy &f1,fuzzy &f2)
00318 {
00319         int i;
00320 
00321         for(i=0;i<samples;i++) fx[i]=1-(1-f1.indexvalue(i))*(1-f2.indexvalue(i));
00322 }
00323 
00324 void fuzzy::setandl(fuzzy &f1,fuzzy &f2)
00325 {
00326         int i;
00327 
00328         for(i=0;i<samples;i++) fx[i]=(f1.indexvalue(i)+f2.indexvalue(i)>1)?f1.indexvalue(i)+f2.indexvalue(i)-1:0;
00329 }
00330 
00331 void fuzzy::setorl(fuzzy &f1,fuzzy &f2)
00332 {
00333         int i;
00334 
00335         for(i=0;i<samples;i++) fx[i]=(f1.indexvalue(i)+f2.indexvalue(i)>1)?1:f1.indexvalue(i)+f2.indexvalue(i);
00336 }
00337 
00338 void fuzzy::setandz(fuzzy &f,float c)
00339 {
00340         int i;
00341 
00342         for(i=0;i<samples;i++) fx[i]=(f.indexvalue(i)<c)?f.indexvalue(i):c;
00343 }
00344 
00345 void fuzzy::setorz(fuzzy &f,float c)
00346 {
00347         int i;
00348 
00349         for(i=0;i<samples;i++) fx[i]=(f.indexvalue(i)>c)?f.indexvalue(i):c;
00350 }
00351 
00352 void fuzzy::setandp(fuzzy &f,float c)
00353 {
00354         int i;
00355 
00356         for(i=0;i<samples;i++) fx[i]=f.indexvalue(i)*c;
00357 }
00358 
00359 void fuzzy::setorp(fuzzy &f,float c)
00360 {
00361         int i;
00362 
00363         for(i=0;i<samples;i++) fx[i]=1-(1-f.indexvalue(i))*(1-c);
00364 }
00365 
00366 void fuzzy::setandl(fuzzy &f,float c)
00367 {
00368         int i;
00369 
00370         for(i=0;i<samples;i++) fx[i]=(f.indexvalue(i)+c>1)?f.indexvalue(i)+c-1:0;
00371 }
00372 
00373 void fuzzy::setorl(fuzzy &f,float c)
00374 {
00375         int i;
00376 
00377         for(i=0;i<samples;i++) fx[i]=(f.indexvalue(i)+c>1)?1:f.indexvalue(i)+c;
00378 }
00379 float fuzzy::value(float x)
00380 {
00381         float index;
00382 
00383         if(x<=min) return(fx[0]);
00384         if(x>=max) return(fx[samples-1]);
00385 
00386         index=(x-min)*(samples-1)/(max-min);
00387         return(fx[(int)index]*(1-index+(int)index)+fx[(int)index+1]*(index-(int)index));
00388 }
00389 float fuzzy::indexvalue(int index)
00390 {
00391         return(fx[index]);
00392 }
00393 float fuzzy::centroid()
00394 {
00395         float nom=0,denom=0,x1,x2;
00396         int i;
00397 
00398         for(i=0;i<samples-1;i++)
00399         {
00400                 x1=min+i*(max-min)/(samples-1);
00401                 x2=min+(i+1)*(max-min)/(samples-1);
00402 
00403                 nom+=fx[i]*(x2*x2/6+x1*x2/6-x1*x1/3)+fx[i+1]*(x2*x2/3-x1*x2/6-x1*x1/6);
00404                 denom+=(x2-x1)*(fx[i+1]+fx[i])/2;
00405         }
00406         return((denom!=0)?(nom/denom):0);
00407 }
00408 
00409 float fuzzy::bisector()
00410 {
00411         float all=0,half=0,x1,x2;
00412         int i;
00413 
00414         for(i=0;i<samples-1;i++)
00415         {
00416                 x1=min+i*(max-min)/(samples-1);
00417                 x2=min+(i+1)*(max-min)/(samples-1);
00418 
00419 
00420                 all+=(x2-x1)*(fx[i+1]+fx[i])/2;
00421         }
00422         for(i=0;i<samples-1;i++)
00423         {
00424                 x1=min+i*(max-min)/(samples-1);
00425                 x2=min+(i+1)*(max-min)/(samples-1);
00426 
00427                 if(half+(x2-x1)*(fx[i+1]+fx[i])/2<all/2) half+=(x2-x1)*(fx[i+1]+fx[i])/2;
00428                 else
00429                 {
00430                         if(fx[i]!=fx[i+1]) return(x1+(-fx[i]+sqrt(fx[i]*fx[i]+(all-2*half)*(fx[i+1]-fx[i])/(x2-x1)))*(x2-x1)/(fx[i+1]-fx[i]));
00431                         else return(x1+(all/2-half)/fx[i]);
00432                 }
00433         }
00434         return(0);
00435 }
00436 
00437 float fuzzy::mom()
00438 {
00439         int integ=0;
00440         float max=0,nom=0,denom=0,x1,x2;
00441         int i;
00442 
00443         for(i=0;i<samples;i++) if(fx[i]>max) max=fx[i];
00444         for(i=0;i<samples-1;i++) if((fx[i]==max)&&(fx[i+1]==max)) integ=1;
00445 
00446         if(integ)
00447         {
00448                 for(i=0;i<samples-1;i++) if((fx[i]==max)&&(fx[i+1]==max))
00449                 {
00450                         x1=min+i*(max-min)/(samples-1);
00451                         x2=min+(i+1)*(max-min)/(samples-1);
00452                         nom+=(x2*x2-x1*x1)/2;
00453                         denom+=x2-x1;
00454                 }
00455         }
00456         else
00457         {
00458                 for(i=0;i<samples;i++) if(fx[i]==max)
00459                 {
00460                         x1=min+i*(max-min)/(samples-1);
00461                         nom+=x1;
00462                         denom+=1;
00463                 }
00464         }
00465         return((denom!=0)?(nom/denom):0);
00466 }
00467 float fuzzy::lom()
00468 {
00469         float max;
00470         int i;
00471 
00472         for(i=0;i<samples;i++) if(fx[i]>max) max=fx[i];
00473         for(i=0;i<samples;i++) if(fx[i]==max) return(min+i*(max-min)/(samples-1));
00474         return(0);
00475 }
00476 
00477 float fuzzy::hom()
00478 {
00479         float max;
00480         int i;
00481 
00482         for(i=0;i<samples;i++) if(fx[i]>max) max=fx[i];
00483         for(i=samples-1;i>=0;i--) if(fx[i]==max) return(min+i*(max-min)/(samples-1));
00484         return(0);
00485 }
00486 
00487 float andz(float c1,float c2)
00488 {
00489         return((c1<c2)?c1:c2);
00490 }
00491 float orz(float c1,float c2)
00492 {
00493         return((c1>c2)?c1:c2);
00494 }
00495 float andp(float c1,float c2)
00496 {
00497         return(c1*c2);
00498 }
00499 float orp(float c1,float c2)
00500 {
00501         return(c1+c2-c1*c2);
00502 }
00503 float andl(float c1,float c2)
00504 {
00505         return((c1+c2-1>0)?(c1+c2-1):0);
00506 }
00507 float orl(float c1,float c2)
00508 {
00509         return((c1+c2>1)?1:c1+c2);
00510 } 

Generated on Thu Apr 26 22:45:26 2007 for GangOfSix(GOS)-RoboCupTeamProject by  doxygen 1.5.1-p1