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
00057
00058
00059
00060
00061
00062
00063
00064
00066
00067 if(x3 > max)
00068 {
00069 float rozdiel = max-min;
00070
00071 x1 -= rozdiel;
00072 x2 -= rozdiel;
00073 x3 -= rozdiel;
00074
00075 x = min;
00076 i = 0;
00077
00078
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
00107
00108
00109
00110
00111
00112
00113
00114
00116
00117 if(x4 > max)
00118 {
00119 float rozdiel = max-min;
00120
00121 x1 -= rozdiel;
00122 x2 -= rozdiel;
00123 x3 -= rozdiel;
00124 x4 -= rozdiel;
00125
00126 x = min;
00127 i = 0;
00128
00129
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
00159
00160
00161
00162
00163
00164
00165
00166
00168
00169 if(x4 > max)
00170 {
00171 float rozdiel = max-min;
00172
00173 x1 -= rozdiel;
00174 x2 -= rozdiel;
00175 x3 -= rozdiel;
00176 x4 -= rozdiel;
00177
00178 x = min;
00179 i = 0;
00180
00181
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
00210
00211
00212
00213
00214
00215
00216
00217
00219
00220 if(x2 > max)
00221 {
00222 float rozdiel = max-min;
00223
00224 x1 -= rozdiel;
00225 x2 -= rozdiel;
00226
00227 x = min;
00228 i = 0;
00229
00230
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
00258
00259
00260
00261
00262
00263
00264
00265
00267
00268 if(x2 > max)
00269 {
00270 float rozdiel = max-min;
00271
00272 x1 -= rozdiel;
00273 x2 -= rozdiel;
00274
00275 x = min;
00276 i = 0;
00277
00278
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 }