Advertisement
Guest User

Untitled

a guest
Mar 31st, 2016
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 63.41 KB | None | 0 0
  1. /*
  2. * Файл интерфейса для С++ и Fuzzy Interfere System
  3. *
  4. * Copyright 2000
  5. */
  6.  
  7.  
  8. #ifndef __FIS__
  9. #define __FIS__
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <math.h>
  15.  
  16. /***********************************************************************
  17. Macros and definitions
  18. **********************************************************************/
  19.  
  20. /* Define portable printf */
  21. #if defined(MATLAB_MEX_FILE)
  22. #define PRINTF mexPrintf
  23. #elif defined(__SIMSTRUC__)
  24. #define PRINTF ssPrintf
  25. #else
  26. #define PRINTF printf
  27. #endif
  28.  
  29. #ifndef ABS
  30. #define ABS(x) ( (x) > (0) ? (x): (-(x)) )
  31. #endif
  32. #ifndef MAX
  33. #define MAX(x,y) ( (x) > (y) ? (x) : (y) )
  34. #endif
  35. #ifndef MIN
  36. #define MIN(x,y) ( (x) < (y) ? (x) : (y) )
  37. #endif
  38. #define MF_PARA_N 4
  39. #define STR_LEN 500
  40. #define MF_POINT_N 101
  41.  
  42.  
  43. /***********************************************************************
  44. Data types
  45. **********************************************************************/
  46.  
  47. typedef struct fis_node * pnode;
  48.  
  49. typedef struct fis_node {
  50. int handle;
  51. int load_param;
  52. char name[STR_LEN];
  53. char type[STR_LEN];
  54. char andMethod[STR_LEN];
  55. char orMethod[STR_LEN];
  56. char impMethod[STR_LEN];
  57. char aggMethod[STR_LEN];
  58. char defuzzMethod[STR_LEN];
  59. int userDefinedAnd;
  60. int userDefinedOr;
  61. int userDefinedImp;
  62. int userDefinedAgg;
  63. int userDefinedDefuzz;
  64. int in_n;
  65. int out_n;
  66. int rule_n;
  67. int **rule_list;
  68. double *rule_weight;
  69. int *and_or; /* AND-OR indicator */
  70. double *firing_strength;
  71. double *rule_output;
  72. /* Sugeno: output for each rules */
  73. /* Mamdani: constrained output MF values of rules */
  74. struct io_node **input;
  75. struct io_node **output;
  76. double (*andFcn)(double, double);
  77. double (*orFcn)(double, double);
  78. double (*impFcn)(double, double);
  79. double (*aggFcn)(double, double);
  80. double (*defuzzFcn)(pnode,int,double *,int);
  81. double *BigOutMfMatrix; /* used for Mamdani system only */
  82. double *BigWeightMatrix;/* used for Mamdani system only */
  83. double *mfs_of_rule; /* MF values in a rule */
  84. struct fis_node *next;
  85. } FIS;
  86.  
  87.  
  88.  
  89. typedef struct io_node {
  90. char name[STR_LEN];
  91. int mf_n;
  92. double bound[2];
  93. double value;
  94. struct mf_node **mf;
  95. } IO;
  96.  
  97.  
  98.  
  99. typedef struct mf_node {
  100. char label[STR_LEN]; /* MF name */
  101. char type[STR_LEN]; /* MF type */
  102. int nparams; /* length of params field */
  103. double *params; /* MF parameters */
  104. int userDefined; /* 1 if the MF is user-defined */
  105. double (*mfFcn)(double, double *); /* pointer to a mem. fcn */
  106. double value; /* for Sugeno only */
  107. double *value_array; /* for Mamdani only, array of MF values */
  108. } MF;
  109.  
  110. #endif /* __FIS__ */
  111.  
  112. /***********************************************************************
  113. File, arrays, matrices operations
  114. **********************************************************************/
  115.  
  116. /* display error message and exit */
  117. static void fisError(char *msg)
  118. {
  119. ShowMessage(msg);
  120. }
  121.  
  122. char **fisCreateMatrix(int row_n, int col_n, int element_size)
  123. {
  124. char **matrix;
  125. int i;
  126.  
  127. if (row_n == 0 && col_n == 0)
  128. return(NULL);
  129.  
  130. matrix = (char **)calloc(row_n, sizeof(char *));
  131. if (matrix == NULL)
  132. fisError("calloc error in fisCreateMatrix!");
  133. for (i = 0; i < row_n; i++) {
  134. matrix[i] = (char *)calloc(col_n, element_size);
  135. if (matrix[i] == NULL)
  136. fisError("calloc error in fisCreateMatrix!");
  137. }
  138. return(matrix);
  139. }
  140.  
  141. /* won't complain if given matrix is already freed */
  142. static void fisFreeMatrix(void **matrix, int row_n)
  143. {
  144. int i;
  145. if (matrix != NULL) {
  146. for (i = 0; i < row_n; i++) {
  147. free(matrix[i]);
  148. }
  149. free(matrix);
  150. }
  151. }
  152.  
  153.  
  154. static double**fisCopyMatrix(double **source, int row_n, int col_n)
  155. {
  156. double **target;
  157. int i, j;
  158.  
  159. target = (double **)fisCreateMatrix(row_n, col_n, sizeof(double));
  160. for (i = 0; i < row_n; i++)
  161. for (j = 0; j < col_n; j++)
  162. target[i][j] = source[i][j];
  163. return(target);
  164. }
  165.  
  166.  
  167. /***********************************************************************
  168. Parameterized membership functions
  169. **********************************************************************/
  170.  
  171. /* Triangular membership function */
  172. static double fisTriangleMf(double x, double *params)
  173. {
  174. double a = params[0], b = params[1], c = params[2];
  175.  
  176. if (a>b)
  177. fisError("Illegal parameters in fisTriangleMf() --> a > b");
  178. if (b>c)
  179. fisError("Illegal parameters in fisTriangleMf() --> b > c");
  180.  
  181. if (a == b && b == c)
  182. return(x == a);
  183. if (a == b)
  184. return((c-x)/(c-b)*(b<=x)*(x<=c));
  185. if (b == c)
  186. return((x-a)/(b-a)*(a<=x)*(x<=b));
  187. return(MAX(MIN((x-a)/(b-a), (c-x)/(c-b)), 0));
  188. }
  189.  
  190. /* Trapezpoidal membership function */
  191. static double fisTrapezoidMf(double x, double *params)
  192. {
  193. double a = params[0], b = params[1], c = params[2], d = params[3];
  194. double y1 = 0, y2 = 0;
  195.  
  196. if (a>b) {
  197. PRINTF("a = %f, b = %f, c = %f, d = %f\n", a, b, c, d);
  198. fisError("Illegal parameters in fisTrapezoidMf() --> a > b");
  199. }
  200. if (b>c)
  201. {
  202. PRINTF("a = %f, b = %f, c = %f, d = %f\n", a, b, c, d);
  203. fisError("Illegal parameters in fisTrapezoidMf() --> b > c");
  204. }
  205. if (c>d) {
  206. PRINTF("a = %f, b = %f, c = %f, d = %f\n", a, b, c, d);
  207. fisError("Illegal parameters in fisTrapezoidMf() --> c > d");
  208. }
  209.  
  210. if (b <= x)
  211. y1 = 1;
  212. else if (x < a)
  213. y1 = 0;
  214. else if (a != b)
  215. y1 = (x-a)/(b-a);
  216.  
  217. if (x <= c)
  218. y2 = 1;
  219. else if (d < x)
  220. y2 = 0;
  221. else if (c != d)
  222. y2 = (d-x)/(d-c);
  223.  
  224. return(MIN(y1, y2));
  225. /*
  226. if (a == b && c == d)
  227. return((b<=x)*(x<=c));
  228. if (a == b)
  229. return(MIN(1, (d-x)/(d-c))*(b<=x)*(x<=d));
  230. if (c == d)
  231. return(MIN((x-a)/(b-a), 1)*(a<=x)*(x<=c));
  232. return(MAX(MIN(MIN((x-a)/(b-a), 1), (d-x)/(d-c)), 0));
  233. */
  234. }
  235.  
  236. /* Gaussian membership function */
  237. static double fisGaussianMf(double x, double *params)
  238. {
  239. double sigma = params[0], c = params[1];
  240. double tmp;
  241.  
  242. if (sigma==0)
  243. fisError("Illegal parameters in fisGaussianMF() --> sigma = 0");
  244. tmp = (x-c)/sigma;
  245. return(exp(-tmp*tmp/2));
  246. }
  247.  
  248. /* Extended Gaussian membership function */
  249. static double fisGaussian2Mf(double x, double *params)
  250. {
  251. double sigma1 = params[0], c1 = params[1];
  252. double sigma2 = params[2], c2 = params[3];
  253. double tmp1, tmp2;
  254.  
  255. if ((sigma1 == 0) || (sigma2 == 0))
  256. fisError("Illegal parameters in fisGaussian2MF() --> sigma1 or sigma2 is zero");
  257.  
  258. tmp1 = x >= c1? 1:exp(-pow((x-c1)/sigma1, 2.0)/2);
  259. tmp2 = x <= c2? 1:exp(-pow((x-c2)/sigma2, 2.0)/2);
  260. return(tmp1*tmp2);
  261. }
  262.  
  263. /* Sigmoidal membership function */
  264. static double fisSigmoidMf(double x, double *params)
  265. {
  266. double a = params[0], c = params[1];
  267. return(1/(1+exp(-a*(x-c))));
  268. }
  269.  
  270. /* Product of two sigmoidal functions */
  271. static double fisProductSigmoidMf(double x, double *params)
  272. {
  273. double a1 = params[0], c1 = params[1], a2 = params[2], c2 = params[3];
  274. double tmp1 = 1/(1+exp(-a1*(x-c1)));
  275. double tmp2 = 1/(1+exp(-a2*(x-c2)));
  276. return(tmp1*tmp2);
  277. }
  278.  
  279. /* Absolute difference of two sigmoidal functions */
  280. static double fisDifferenceSigmoidMf(double x, double *params)
  281. {
  282. double a1 = params[0], c1 = params[1], a2 = params[2], c2 = params[3];
  283. double tmp1 = 1/(1+exp(-a1*(x-c1)));
  284. double tmp2 = 1/(1+exp(-a2*(x-c2)));
  285. return(fabs(tmp1-tmp2));
  286. }
  287.  
  288. /* Generalized bell membership function */
  289. static double fisGeneralizedBellMf(double x, double *params)
  290. {
  291. double a = params[0], b = params[1], c = params[2];
  292. double tmp;
  293. if (a==0)
  294. fisError("Illegal parameters in fisGeneralizedBellMf() --> a = 0");
  295. tmp = pow((x-c)/a, 2.0);
  296. if (tmp == 0 && b == 0)
  297. return(0.5);
  298. else if (tmp == 0 && b < 0)
  299. return(0.0);
  300. else
  301. return(1/(1+pow(tmp, b)));
  302. }
  303.  
  304. /* S membership function */
  305. static double fisSMf(double x, double *params)
  306. {
  307. double a = params[0], b = params[1];
  308. double out;
  309.  
  310. if (a >= b)
  311. return(x >= (a+b)/2);
  312.  
  313. if (x <= a)
  314. out = 0;
  315. else if (x <= (a + b)/2)
  316. out = 2*pow((x-a)/(b-a), 2.0);
  317. else if (x <= b)
  318. out = 1-2*pow((b-x)/(b-a), 2.0);
  319. else
  320. out = 1;
  321. return(out);
  322. }
  323.  
  324. /* Z membership function */
  325. static double fisZMf(double x, double *params)
  326. {
  327. double a = params[0], b = params[1];
  328. double out;
  329.  
  330. if (a >= b)
  331. return(x <= (a+b)/2);
  332.  
  333. if (x <= a)
  334. out = 1;
  335. else if (x <= (a + b)/2)
  336. out = 1 - 2*pow((x-a)/(b-a), 2.0);
  337. else if (x <= b)
  338. out = 2*pow((b-x)/(b-a), 2.0);
  339. else
  340. out = 0;
  341. return(out);
  342. }
  343.  
  344. /* pi membership function */
  345. static double fisPiMf(double x, double *params)
  346. {
  347. return(fisSMf(x, params)*fisZMf(x, params+2));
  348. }
  349.  
  350. /* all membership function */
  351. static double fisAllMf(double x, double *params)
  352. {
  353. return(1);
  354. }
  355.  
  356. /* returns the number of parameters of MF */
  357. static int fisGetMfParaN(char *mfType)
  358. {
  359. if (strcmp(mfType, "trimf") == 0)
  360. return(3);
  361. if (strcmp(mfType, "trapmf") == 0)
  362. return(4);
  363. if (strcmp(mfType, "gaussmf") == 0)
  364. return(2);
  365. if (strcmp(mfType, "gauss2mf") == 0)
  366. return(4);
  367. if (strcmp(mfType, "sigmf") == 0)
  368. return(2);
  369. if (strcmp(mfType, "dsigmf") == 0)
  370. return(4);
  371. if (strcmp(mfType, "psigmf") == 0)
  372. return(4);
  373. if (strcmp(mfType, "gbellmf") == 0)
  374. return(3);
  375. if (strcmp(mfType, "smf") == 0)
  376. return(2);
  377. if (strcmp(mfType, "zmf") == 0)
  378. return(2);
  379. if (strcmp(mfType, "pimf") == 0)
  380. return(4);
  381. fisError("Given MF type is unknown.");
  382. exit(1);
  383. return(0); /* get rid of compiler warning */
  384. }
  385. /***********************************************************************
  386. T-norm and T-conorm operators
  387. **********************************************************************/
  388.  
  389. static double fisMin(double x, double y)
  390. {return((x) < (y) ? (x) : (y));}
  391.  
  392. static double fisMax(double x, double y)
  393. {return((x) > (y) ? (x) : (y));}
  394.  
  395. static double fisProduct(double x, double y)
  396. {return(x*y);}
  397.  
  398. static double fisProbOr(double x, double y)
  399. {return(x + y - x*y);}
  400.  
  401. static double fisSum(double x, double y)
  402. {return(x + y);}
  403.  
  404. /* apply given function to an array */
  405. static double fisArrayOperation(double *array, int size, double (*fcn)(double, double))
  406. {
  407. int i;
  408. double out;
  409.  
  410. if (size == 0)
  411. fisError("Given size is zero!");
  412.  
  413. out = array[0];
  414. for (i = 1; i < size; i++)
  415. out = (*fcn)(out, array[i]);
  416. return(out);
  417. }
  418.  
  419. /***********************************************************************
  420. Defuzzification methods
  421. **********************************************************************/
  422.  
  423. /* return the center of area of combined output MF (specified by mf)
  424. of output m */
  425. /* numofpoints is the number of partition for integration */
  426. static double defuzzCentroid(FIS *fis, int m, double *mf, int numofpoints)
  427. {
  428. double min = fis->output[m]->bound[0];
  429. double max = fis->output[m]->bound[1];
  430. double step = (max - min)/(numofpoints - 1);
  431. double total_mf = 0;
  432. double sum = 0;
  433. int i;
  434.  
  435. for (i = 0; i < numofpoints; i++){
  436. total_mf += mf[i];
  437. sum += mf[i]*(min + step*i);
  438. }
  439. if (total_mf == 0) {
  440. ShowMessage("Total area is zero in defuzzCentroid() for output "+FloatToStr(m+1));
  441. ShowMessage("Average of the range of this output variable is used as the output value.\n\n");
  442. return((fis->output[m]->bound[0] + fis->output[m]->bound[1])/2);
  443. }
  444. return(sum/total_mf);
  445. }
  446.  
  447. /* return the bisector of area of mf */
  448. static double defuzzBisector(FIS *fis, int m, double *mf, int numofpoints)
  449. {
  450. double min = fis->output[m]->bound[0];
  451. double max = fis->output[m]->bound[1];
  452. double step = (max - min)/(numofpoints - 1);
  453. double area, sub_area;
  454. int i;
  455.  
  456. /* find the total area */
  457. area = 0;
  458. for (i = 0; i < numofpoints; i++)
  459. area += mf[i];
  460.  
  461. if (area == 0) {
  462. PRINTF("Total area is zero in defuzzBisector() for output %d.\n", m+1);
  463. PRINTF("Average of the range of this output variable is used as the output value.\n");
  464. return((fis->output[m]->bound[0] + fis->output[m]->bound[1])/2);
  465. }
  466.  
  467. sub_area = 0;
  468. for (i = 0; i < numofpoints; i++) {
  469. sub_area += mf[i];
  470. if (sub_area >= area/2)
  471. break;
  472. }
  473. return(min + step*i);
  474. }
  475.  
  476. /* Returns the mean of maximizing x of mf */
  477. static double defuzzMeanOfMax(FIS *fis, int m, double *mf, int numofpoints)
  478. {
  479. double min = fis->output[m]->bound[0];
  480. double max = fis->output[m]->bound[1];
  481. double step = (max - min)/(numofpoints - 1);
  482. double mf_max;
  483. double sum;
  484. int count;
  485. int i;
  486.  
  487. mf_max = fisArrayOperation(mf, numofpoints, fisMax);
  488.  
  489. sum = 0;
  490. count = 0;
  491. for (i = 0; i < numofpoints; i++)
  492. if (mf[i] == mf_max) {
  493. count++;
  494. sum += i;
  495. }
  496. return(min+step*sum/count);
  497. }
  498.  
  499. /* Returns the smallest (in magnitude) maximizing x of mf */
  500. static double defuzzSmallestOfMax(FIS *fis, int m, double *mf, int numofpoints)
  501. {
  502. double min = fis->output[m]->bound[0];
  503. double max = fis->output[m]->bound[1];
  504. double step = (max - min)/(numofpoints - 1);
  505. double mf_max;
  506. int i, min_index = 0;
  507. double min_distance = pow(2.0, 31.0)-1;
  508. double distance; /* distance to the origin */
  509.  
  510. mf_max = fisArrayOperation(mf, numofpoints, fisMax);
  511. for (i = 0; i < numofpoints; i++)
  512. if (mf[i] == mf_max) {
  513. distance = ABS(min + step*i);
  514. if (min_distance > distance) {
  515. min_distance = distance;
  516. min_index = i;
  517. }
  518. }
  519. return(min + step*min_index);
  520. }
  521.  
  522. /* Returns the largest (in magnitude) maximizing x of mf */
  523. static double defuzzLargestOfMax(FIS *fis, int m, double *mf, int numofpoints)
  524. {
  525. double min = fis->output[m]->bound[0];
  526. double max = fis->output[m]->bound[1];
  527. double step = (max - min)/(numofpoints - 1);
  528. double mf_max;
  529. int i, max_index = 0;
  530. double max_distance = -(pow(2.0, 31.0)-1);
  531. double distance; /* distance to the origin */
  532.  
  533. mf_max = fisArrayOperation(mf, numofpoints, fisMax);
  534. for (i = 0; i < numofpoints; i++)
  535. if (mf[i] == mf_max) {
  536. distance = ABS(min + step*i);
  537. if (max_distance < distance) {
  538. max_distance = distance;
  539. max_index = i;
  540. }
  541. }
  542. return(min + step*max_index);
  543. }
  544. /***********************************************************************
  545. Data structure: construction, printing, and destruction
  546. **********************************************************************/
  547. /* Copyright 1994-2000 The MathWorks, Inc. */
  548. /* $Revision: $ $Date: $ */
  549.  
  550. IO *fisBuildIoList(int node_n, int *mf_n)
  551. {
  552. IO *io_list;
  553. int i, j;
  554.  
  555. io_list = (IO *)calloc(node_n, sizeof(IO));
  556. for (i = 0; i < node_n; i++) {
  557. io_list[i].mf_n = mf_n[i];
  558. io_list[i].mf = (MF **)calloc(mf_n[i], sizeof(MF *));
  559. if (mf_n[i] > 0) /* check if no MF at all */
  560. io_list[i].mf[0] = (MF *)calloc(mf_n[i], sizeof(MF));
  561. for (j = 0; j < mf_n[i]; j++)
  562. io_list[i].mf[j] = io_list[i].mf[0] + j;
  563. }
  564. return(io_list);
  565. }
  566.  
  567. /* Assign a MF pointer to each MF node based on the MF node's type */
  568. void fisAssignMfPointer(FIS *fis)
  569. {
  570. int i, j, k, mfTypeN = 13, found;
  571. MF *mf_node;
  572. struct command {
  573. char *mfType;
  574. double (*mfFcn)(double, double *);
  575. } dispatch[] = {
  576. { "trimf", fisTriangleMf },
  577. { "trapmf", fisTrapezoidMf },
  578. { "gaussmf", fisGaussianMf },
  579. { "gauss2mf", fisGaussian2Mf },
  580. { "sigmf", fisSigmoidMf },
  581. { "dsigmf", fisDifferenceSigmoidMf },
  582. { "psigmf", fisProductSigmoidMf },
  583. { "gbellmf", fisGeneralizedBellMf },
  584. { "smf", fisSMf },
  585. { "zmf", fisZMf },
  586. { "pimf", fisPiMf },
  587. { "linear", NULL },
  588. { "constant", NULL }
  589. };
  590.  
  591. /* input MF's */
  592. for (i = 0; i < fis->in_n; i++)
  593. for (j = 0; j < fis->input[i]->mf_n; j++) {
  594. mf_node = fis->input[i]->mf[j];
  595. found = 0;
  596. for (k = 0; k < mfTypeN-2; k++) {
  597. if (strcmp(mf_node->type, dispatch[k].mfType) == 0) {
  598. mf_node->mfFcn = dispatch[k].mfFcn;
  599. found = 1;
  600. break;
  601. }
  602. }
  603. if (found == 0) {
  604. #ifdef MATLAB_MEX_FILE
  605. {
  606. double function_type;
  607. function_type = fisCallMatlabExist(mf_node->type);
  608. if (function_type == 0) {
  609. printf("MF '%s' does not exist!\n", mf_node->type);
  610. fisError("Exiting ...");
  611. }
  612. if (function_type == 1) {
  613. printf("MF '%s' is a MATLAB variable!\n", mf_node->type);
  614. fisError("Exiting ...");
  615. }
  616. mf_node->userDefined = 1;
  617. }
  618. #else
  619. PRINTF("MF type '%s' for input %d is unknown.\n",
  620. mf_node->type, i+1);
  621. PRINTF("Legal input MF types: ");
  622. for (i = 0; i < mfTypeN-2; i++)
  623. printf("%s ", dispatch[i].mfType);
  624. fisError("\n");
  625. #endif
  626. }
  627. }
  628.  
  629. /* output MF's */
  630. for (i = 0; i < fis->out_n; i++)
  631. for (j = 0; j < fis->output[i]->mf_n; j++) {
  632. mf_node = fis->output[i]->mf[j];
  633. found = 0;
  634. for (k = 0; k < mfTypeN; k++) {
  635. if (strcmp(mf_node->type, dispatch[k].mfType) == 0) {
  636. mf_node->mfFcn = dispatch[k].mfFcn;
  637. found = 1;
  638. break;
  639. }
  640. }
  641. if (found == 0) {
  642. #ifdef MATLAB_MEX_FILE
  643. {
  644. double function_type;
  645. function_type = fisCallMatlabExist(mf_node->type);
  646. if (function_type == 0) {
  647. printf("MATLAB function '%s' does not exist!\n", mf_node->type);
  648. fisError("Exiting ...");
  649. }
  650. if (function_type == 1) {
  651. printf("'%s' is a MATLAB variable!\n", mf_node->type);
  652. fisError("Exiting ...");
  653. }
  654. mf_node->userDefined = 1;
  655. }
  656. #else
  657. PRINTF("MF type '%s' for output %d is unknown.\n",
  658. mf_node->type, i+1);
  659. PRINTF("Legal output MF types: ");
  660. for (i = 0; i < mfTypeN-1; i++)
  661. PRINTF("%s ", dispatch[i].mfType);
  662. fisError("\n");
  663. #endif
  664. }
  665. }
  666. }
  667.  
  668. /* Assign a other function pointers */
  669. void fisAssignFunctionPointer(FIS *fis)
  670. {
  671. /* assign andMethod function pointer */
  672. if (strcmp(fis->andMethod, "prod") == 0)
  673. fis->andFcn = fisProduct;
  674. else if (strcmp(fis->andMethod, "min") == 0)
  675. fis->andFcn = fisMin;
  676. else {
  677. #ifdef MATLAB_MEX_FILE
  678. {
  679. double function_type;
  680. function_type = fisCallMatlabExist(fis->andMethod);
  681. if (function_type == 0) {
  682. printf("AND function '%s' does not exist!\n", fis->andMethod);
  683. fisError("Exiting ...");
  684. }
  685. if (function_type == 1) {
  686. printf("AND function '%s' is a MATLAB variable!\n", fis->andMethod);
  687. fisError("Exiting ...");
  688. }
  689. fis->userDefinedAnd = 1;
  690. }
  691. #else
  692. PRINTF("Given andMethod %s is unknown.\n", fis->andMethod);
  693. fisError("Legal andMethod: min, prod");
  694. #endif
  695. }
  696.  
  697. /* assign orMethod function pointer */
  698. if (strcmp(fis->orMethod, "probor") == 0)
  699. fis->orFcn = fisProbOr;
  700. else if (strcmp(fis->orMethod, "max") == 0)
  701. fis->orFcn = fisMax;
  702. else {
  703. #ifdef MATLAB_MEX_FILE
  704. {
  705. double function_type;
  706. function_type = fisCallMatlabExist(fis->orMethod);
  707. if (function_type == 0) {
  708. printf("OR function '%s' does not exist!\n", fis->orMethod);
  709. fisError("Exiting ...");
  710. }
  711. if (function_type == 1) {
  712. printf("OR function '%s' is a MATLAB variable!\n", fis->orMethod);
  713. fisError("Exiting ...");
  714. }
  715. fis->userDefinedOr = 1;
  716. }
  717. #else
  718. PRINTF("Given orMethod %s is unknown.\n", fis->orMethod);
  719. fisError("Legal orMethod: max, probor");
  720. #endif
  721. }
  722.  
  723. /* assign impMethod function pointer */
  724. if (strcmp(fis->impMethod, "prod") == 0)
  725. fis->impFcn = fisProduct;
  726. else if (strcmp(fis->impMethod, "min") == 0)
  727. fis->impFcn = fisMin;
  728. else {
  729. #ifdef MATLAB_MEX_FILE
  730. {
  731. double function_type;
  732. function_type = fisCallMatlabExist(fis->impMethod);
  733. if (function_type == 0) {
  734. printf("IMPLICATION function '%s' does not exist!\n", fis->impMethod);
  735. fisError("Exiting ...");
  736. }
  737. if (function_type == 1) {
  738. printf("IMPLICATION function '%s' is a MATLAB variable!\n", fis->impMethod);
  739. fisError("Exiting ...");
  740. }
  741. fis->userDefinedImp = 1;
  742. }
  743. #else
  744. PRINTF("Given impMethod %s is unknown.\n", fis->impMethod);
  745. fisError("Legal impMethod: min, prod");
  746. #endif
  747. }
  748.  
  749. /* assign aggMethod function pointer */
  750. if (strcmp(fis->aggMethod, "max") == 0)
  751. fis->aggFcn = fisMax;
  752. else if (strcmp(fis->aggMethod, "probor") == 0)
  753. fis->aggFcn = fisProbOr;
  754. else if (strcmp(fis->aggMethod, "sum") == 0)
  755. fis->aggFcn = fisSum;
  756. else {
  757. #ifdef MATLAB_MEX_FILE
  758. {
  759. double function_type;
  760. function_type = fisCallMatlabExist(fis->aggMethod);
  761. if (function_type == 0) {
  762. printf("AGGREGATE function '%s' does not exist!\n", fis->aggMethod);
  763. fisError("Exiting ...");
  764. }
  765. if (function_type == 1) {
  766. printf("AGGREGATE function '%s' is a MATLAB variable!\n", fis->aggMethod);
  767. fisError("Exiting ...");
  768. }
  769. fis->userDefinedAgg = 1;
  770. }
  771. #else
  772. PRINTF("Given aggMethod %s is unknown.\n", fis->aggMethod);
  773. fisError("Legal aggMethod: max, probor, sum");
  774. #endif
  775. }
  776.  
  777. /* assign defuzzification function pointer */
  778. if (strcmp(fis->defuzzMethod, "centroid") == 0)
  779. fis->defuzzFcn = defuzzCentroid;
  780. else if (strcmp(fis->defuzzMethod, "bisector") == 0)
  781. fis->defuzzFcn = defuzzBisector;
  782. else if (strcmp(fis->defuzzMethod, "mom") == 0)
  783. fis->defuzzFcn = defuzzMeanOfMax;
  784. else if (strcmp(fis->defuzzMethod, "som") == 0)
  785. fis->defuzzFcn = defuzzSmallestOfMax;
  786. else if (strcmp(fis->defuzzMethod, "lom") == 0)
  787. fis->defuzzFcn = defuzzLargestOfMax;
  788. else if (strcmp(fis->defuzzMethod, "wtaver") == 0)
  789. ;
  790. else if (strcmp(fis->defuzzMethod, "wtsum") == 0)
  791. ;
  792. else {
  793. #ifdef MATLAB_MEX_FILE
  794. {
  795. double function_type;
  796. function_type = fisCallMatlabExist(fis->defuzzMethod);
  797. if (function_type == 0) {
  798. printf("DEFUZZIFICATION function '%s' does not exist!\n", fis->defuzzMethod);
  799. fisError("Exiting ...");
  800. }
  801. if (function_type == 1) {
  802. printf("DEFUZZIFICATION function '%s' is a MATLAB variable!\n", fis->defuzzMethod);
  803. fisError("Exiting ...");
  804. }
  805. fis->userDefinedDefuzz = 1;
  806. }
  807. #else
  808. PRINTF("Given defuzzification method %s is unknown.\n", fis->defuzzMethod);
  809. fisError("Legal defuzzification methods: centroid, bisector, mom, som, lom, wtaver, wtsum");
  810. #endif
  811. }
  812. }
  813.  
  814. #ifndef NO_PRINTF
  815. static void fisPrintData(FIS *fis)
  816. {
  817. int i, j, k;
  818.  
  819. if (fis == NULL)
  820. fisError("Given fis pointer is NULL, no data to print!");
  821.  
  822. printf("fis_name = %s\n", fis->name);
  823. printf("fis_type = %s\n", fis->type);
  824. printf("in_n = %d\n", fis->in_n);
  825. printf("out_n = %d\n", fis->out_n);
  826.  
  827. printf("in_mf_n: ");
  828. for (i = 0; i < fis->in_n; i++)
  829. printf("%d ", fis->input[i]->mf_n);
  830. printf("\n");
  831.  
  832. printf("out_mf_n: ");
  833. for (i = 0; i < fis->out_n; i++)
  834. printf("%d ", fis->output[i]->mf_n);
  835. printf("\n");
  836.  
  837. printf("rule_n = %d\n", fis->rule_n);
  838.  
  839. printf("andMethod = %s\n", fis->andMethod);
  840. printf("orMethod = %s\n", fis->orMethod);
  841. printf("impMethod = %s\n", fis->impMethod);
  842. printf("aggMethod = %s\n", fis->aggMethod);
  843. printf("defuzzMethod = %s\n", fis->defuzzMethod);
  844.  
  845. /*
  846. for (i = 0; i < fis->in_n; i++) {
  847. printf("Input variable %d = %s\n", i+1, fis->input[i]->name);
  848. for (j = 0; j < fis->input[i]->mf_n; j++)
  849. printf("\t Label for MF %d = %s\n", j+1, fis->input[i]->mf[j]->label);
  850. }
  851.  
  852. for (i = 0; i < fis->out_n; i++) {
  853. printf("Output variable %d = %s\n", i+1, fis->output[i]->name);
  854. for (j = 0; j < fis->output[i]->mf_n; j++)
  855. printf("\t Label for MF %d = %s\n", j+1, fis->output[i]->mf[j]->label);
  856. }
  857. */
  858.  
  859. for (i = 0; i < fis->in_n; i++)
  860. printf("Bounds for input variable %d: [%6.3f %6.3f]\n", i+1,
  861. fis->input[i]->bound[0], fis->input[i]->bound[1]);
  862.  
  863. for (i = 0; i < fis->out_n; i++)
  864. printf("Bounds for output variable %d: [%6.3f %6.3f]\n", i+1,
  865. fis->output[i]->bound[0], fis->output[i]->bound[1]);
  866.  
  867. for (i = 0; i < fis->in_n; i++) {
  868. printf("MF for input variable %d (%s):\n", i+1, fis->input[i]->name);
  869. for (j = 0; j < fis->input[i]->mf_n; j++)
  870. printf("\t Type for MF %d = %s\n", j+1, fis->input[i]->mf[j]->type);
  871. }
  872.  
  873. for (i = 0; i < fis->out_n; i++) {
  874. printf("MF for output variable %d (%s):\n", i+1, fis->output[i]->name);
  875. for (j = 0; j < fis->output[i]->mf_n; j++)
  876. printf("\t Type for MF %d = %s\n", j+1, fis->output[i]->mf[j]->type);
  877. }
  878.  
  879. printf("Rule list:\n");
  880. for (i = 0; i < fis->rule_n; i++) {
  881. for (j = 0; j < fis->in_n + fis->out_n; j++)
  882. printf("%d ", fis->rule_list[i][j]);
  883. printf("\n");
  884. }
  885.  
  886. printf("Rule weights:\n");
  887. for (i = 0; i < fis->rule_n; i++)
  888. printf("%f\n", fis->rule_weight[i]);
  889.  
  890. printf("AND-OR indicator:\n");
  891. for (i = 0; i < fis->rule_n; i++)
  892. printf("%d\n", fis->and_or[i]);
  893.  
  894. for (i = 0; i < fis->in_n; i++) {
  895. printf("MF parameters for input variable %d (%s):\n",
  896. i+1, fis->input[i]->name);
  897. for (j = 0; j < fis->input[i]->mf_n; j++) {
  898. printf("\tParameters for MF %d (%s) (%s): ",
  899. j+1, fis->input[i]->mf[j]->label,
  900. fis->input[i]->mf[j]->type);
  901. for (k = 0; k < fis->input[i]->mf[j]->nparams; k++)
  902. printf("%6.3f ", fis->input[i]->mf[j]->params[k]);
  903. printf("\n");
  904. }
  905. }
  906.  
  907. for (i = 0; i < fis->out_n; i++) {
  908. printf("MF parameters for output variable %d (%s):\n",
  909. i+1, fis->output[i]->name);
  910. for (j = 0; j < fis->output[i]->mf_n; j++) {
  911. printf("\tParameters for MF %d (%s) (%s): ",
  912. j+1, fis->output[i]->mf[j]->label,
  913. fis->output[i]->mf[j]->type);
  914. for (k = 0; k < fis->output[i]->mf[j]->nparams; k++)
  915. printf("%6.3f ", fis->output[i]->mf[j]->params[k]);
  916. printf("\n");
  917. }
  918. }
  919. }
  920. #endif
  921.  
  922.  
  923. static void fisFreeMfList(MF *mf_list, int n)
  924. {
  925. int i;
  926.  
  927. for (i = 0; i < n; i++) {
  928. free(mf_list[i].params);
  929. free(mf_list[i].value_array);
  930. }
  931. free(mf_list);
  932. }
  933.  
  934.  
  935. static void fisFreeIoList(IO *io_list, int n)
  936. {
  937. int i;
  938. for (i = 0; i < n; i++) {
  939. if (io_list[i].mf_n > 0) /* check if no MF at all */
  940. fisFreeMfList(io_list[i].mf[0], io_list[i].mf_n);
  941. free(io_list[i].mf);
  942. }
  943. free(io_list);
  944. }
  945.  
  946. void fisFreeFisNode(FIS *fis)
  947. {
  948. if (fis == NULL)
  949. return;
  950. fisFreeIoList(fis->input[0], fis->in_n);
  951. free(fis->input);
  952. fisFreeIoList(fis->output[0], fis->out_n);
  953. free(fis->output);
  954. #ifdef FREEMAT
  955. FREEMAT((void **)fis->rule_list, fis->rule_n);
  956. #else
  957. fisFreeMatrix((void **)fis->rule_list, fis->rule_n);
  958. #endif
  959. free(fis->rule_weight);
  960. free(fis->and_or);
  961. free(fis->firing_strength);
  962. free(fis->rule_output);
  963. free(fis->BigOutMfMatrix);
  964. free(fis->BigWeightMatrix);
  965. free(fis->mfs_of_rule);
  966. free(fis);
  967. }
  968.  
  969. /* Compute arrays of MF values (for Mamdani model only) */
  970. /* This is done whenever new parameters are loaded */
  971. void fisComputeOutputMfValueArray(FIS *fis, int numofpoints)
  972. {
  973. int i, j, k;
  974. double x, lx, ux, dx;
  975. MF *mf_node;
  976.  
  977. for (i = 0; i < fis->out_n; i++) {
  978. lx = fis->output[i]->bound[0];
  979. ux = fis->output[i]->bound[1];
  980. dx = (ux - lx)/(numofpoints - 1);
  981. for (j = 0; j < fis->output[i]->mf_n; j++) {
  982. mf_node = fis->output[i]->mf[j];
  983. if (!mf_node->userDefined)
  984. for (k = 0; k < numofpoints; k++) {
  985. x = lx + k*dx;
  986. mf_node->value_array[k] =
  987. (*mf_node->mfFcn)(x, mf_node->params);
  988. }
  989. else { /* user defined MF */
  990. #ifdef MATLAB_MEX_FILE
  991. /* this is vector version */
  992. {
  993. double *X;
  994. X = (double *)calloc(numofpoints, sizeof(double));
  995. /* double X[numofpoints]; */
  996. for (k = 0; k < numofpoints; k++)
  997. X[k] = lx + k*dx;
  998. fisCallMatlabMf2(X, mf_node->nparams, mf_node->params,
  999. mf_node->type, numofpoints, mf_node->value_array);
  1000. free(X);
  1001. }
  1002. #else
  1003. PRINTF("Cannot find MF type %s!\n", mf_node->type);
  1004. fisError("Exiting ...");
  1005. #endif
  1006. }
  1007. }
  1008. }
  1009. }
  1010.  
  1011.  
  1012. /* copy string (the first 'length' characters) from array to target string */
  1013. static void fisGetString2(char *target, double *array, int max_leng)
  1014. {
  1015. int i;
  1016. int actual_leng;
  1017.  
  1018. /* Find the actual length of the string */
  1019. /* If the string is not ended with 0, take max_leng */
  1020. for (actual_leng = 0; actual_leng < max_leng; actual_leng++)
  1021. if (array[actual_leng] == 0)
  1022. break;
  1023.  
  1024. if (actual_leng + 1 > STR_LEN) {
  1025. PRINTF("actual_leng = %d\n", actual_leng);
  1026. PRINTF("STR_LEN = %d\n", STR_LEN);
  1027. fisError("String too long!");
  1028. }
  1029. for (i = 0; i < actual_leng; i++)
  1030. target[i] = (char)array[i];
  1031. target[actual_leng] = 0;
  1032. }
  1033.  
  1034. /* Check if there are abnormal situations is the FIS data structure */
  1035. /* Things being checked:
  1036. 1. MF indices out of bound.
  1037. 2. Rules with no premise part.
  1038. 3. Sugeno system with negated consequent.
  1039. 4. Sugeno system with zero consequent.
  1040. */
  1041. void fisCheckDataStructure(FIS *fis)
  1042. {
  1043. int i, j, mf_index;
  1044. int found;
  1045.  
  1046. /* check if MF indices are out of bound */
  1047. for (i = 0; i < fis->rule_n; i++) {
  1048. for (j = 0; j < fis->in_n; j++) {
  1049. mf_index = fis->rule_list[i][j];
  1050. if (ABS(mf_index) > fis->input[j]->mf_n) {
  1051. PRINTF("MF index for input %d in rule %d is out of bound.\n",
  1052. j+1, i+1);
  1053. fisFreeFisNode(fis);
  1054. fisError("Exiting ...");
  1055. }
  1056. }
  1057. for (j = 0; j < fis->out_n; j++) {
  1058. mf_index = fis->rule_list[i][fis->in_n+j];
  1059. if (ABS(mf_index) > fis->output[j]->mf_n) {
  1060. PRINTF("MF index for output %d in rule %d is out of bound.\n",
  1061. j+1, i+1);
  1062. fisFreeFisNode(fis);
  1063. fisError("Exiting ...");
  1064. }
  1065. }
  1066. }
  1067. /* check if there is a rule whose premise MF indice are all zeros */
  1068. for (i = 0; i < fis->rule_n; i++) {
  1069. found = 1;
  1070. for (j = 0; j < fis->in_n; j++) {
  1071. mf_index = fis->rule_list[i][j];
  1072. if (mf_index != 0) {
  1073. found = 0;
  1074. break;
  1075. }
  1076. }
  1077. if (found == 1) {
  1078. PRINTF("Rule %d has no premise part.\n", i+1);
  1079. fisFreeFisNode(fis);
  1080. fisError("Exiting ...");
  1081. }
  1082. }
  1083. /* check if it's sugeno system with "NOT" consequent */
  1084. if (strcmp(fis->type, "sugeno") == 0)
  1085. for (i = 0; i < fis->rule_n; i++)
  1086. for (j = 0; j < fis->out_n; j++) {
  1087. mf_index = fis->rule_list[i][fis->in_n+j];
  1088. if (mf_index < 0) {
  1089. PRINTF("Rule %d has a 'NOT' consequent.\n", i+1);
  1090. PRINTF("Sugeno fuzzy inference system does not allow this.\n");
  1091. fisError("Exiting ...");
  1092. }
  1093. }
  1094. /* check if it's sugeno system with zero consequent */
  1095. if (strcmp(fis->type, "sugeno") == 0)
  1096. for (i = 0; i < fis->rule_n; i++)
  1097. for (j = 0; j < fis->out_n; j++) {
  1098. mf_index = fis->rule_list[i][fis->in_n+j];
  1099. if (mf_index == 0) {
  1100. PRINTF("Warning: Output %d in rule %d has a zero MF index.\n", j+1, i+1);
  1101. PRINTF("This output in the rule is assumed zero in subsequent calculation.\n\n");
  1102. }
  1103. }
  1104. }
  1105.  
  1106. /* Build FIS node and load parameter from fismatrix directly */
  1107. /* col_n is the number of columns of the fismatrix */
  1108. static void fisBuildFisNode(FIS *fis, double **fismatrix, int col_n, int numofpoints)
  1109. {
  1110. int i, j, k;
  1111. int *in_mf_n, *out_mf_n;
  1112. IO *io_list;
  1113. int start;
  1114.  
  1115. fisGetString2(fis->name, fismatrix[0], col_n);
  1116. fisGetString2(fis->type, fismatrix[1], col_n);
  1117. fis->in_n = (int) fismatrix[2][0];
  1118. fis->out_n = (int) fismatrix[2][1];
  1119.  
  1120. /* create input node list */
  1121. in_mf_n = (int *)calloc(fis->in_n, sizeof(int));
  1122. for (i = 0; i < fis->in_n; i++)
  1123. in_mf_n[i] = (int) fismatrix[3][i];
  1124. io_list = fisBuildIoList(fis->in_n, in_mf_n);
  1125. free(in_mf_n);
  1126. fis->input = (IO **)calloc(fis->in_n, sizeof(IO *));
  1127. for (i = 0; i < fis->in_n; i++)
  1128. fis->input[i] = io_list+i;
  1129.  
  1130. /* create output node list */
  1131. out_mf_n = (int *)calloc(fis->out_n, sizeof(int));
  1132. for (i = 0; i < fis->out_n; i++)
  1133. out_mf_n[i] = (int) fismatrix[4][i];
  1134. io_list = fisBuildIoList(fis->out_n, out_mf_n);
  1135. free(out_mf_n);
  1136. fis->output = (IO **)calloc(fis->out_n, sizeof(IO *));
  1137. for (i = 0; i < fis->out_n; i++)
  1138. fis->output[i] = io_list+i;
  1139.  
  1140. fis->rule_n = (int) fismatrix[5][0];
  1141.  
  1142. fisGetString2(fis->andMethod, fismatrix[6], col_n);
  1143. fisGetString2(fis->orMethod, fismatrix[7], col_n);
  1144. fisGetString2(fis->impMethod, fismatrix[8], col_n);
  1145. fisGetString2(fis->aggMethod, fismatrix[9], col_n);
  1146. fisGetString2(fis->defuzzMethod, fismatrix[10], col_n);
  1147.  
  1148. start = 11;
  1149. /* For efficiency, I/O names and MF labels are not stored */
  1150. for (i = 0; i < fis->in_n; i++) {
  1151. fis->input[i]->name[0] = '\0';
  1152. for (j = 0; j < fis->input[i]->mf_n; j++)
  1153. fis->input[i]->mf[j]->label[0] = '\0';
  1154. }
  1155. for (i = 0; i < fis->out_n; i++) {
  1156. fis->output[i]->name[0] = '\0';
  1157. for (j = 0; j < fis->output[i]->mf_n; j++)
  1158. fis->output[i]->mf[j]->label[0] = '\0';
  1159. }
  1160.  
  1161. start = start + fis->in_n + fis->out_n;
  1162. for (i = start; i < start + fis->in_n; i++) {
  1163. fis->input[i-start]->bound[0] = fismatrix[i][0];
  1164. fis->input[i-start]->bound[1] = fismatrix[i][1];
  1165. }
  1166.  
  1167. start = start + fis->in_n;
  1168. for (i = start; i < start + fis->out_n; i++) {
  1169. fis->output[i-start]->bound[0] = fismatrix[i][0];
  1170. fis->output[i-start]->bound[1] = fismatrix[i][1];
  1171. }
  1172.  
  1173. /* update "start" to skip reading of MF labels */
  1174. for (i = 0; i < fis->in_n; start += fis->input[i]->mf_n, i++);
  1175. for (i = 0; i < fis->out_n; start += fis->output[i]->mf_n, i++);
  1176.  
  1177. start = start + fis->out_n;
  1178. for (i = 0; i < fis->in_n; i++)
  1179. for (j = 0; j < fis->input[i]->mf_n; j++) {
  1180. fisGetString2(fis->input[i]->mf[j]->type, fismatrix[start], col_n);
  1181. start++;
  1182. }
  1183.  
  1184. for (i = 0; i < fis->out_n; i++)
  1185. for (j = 0; j < fis->output[i]->mf_n; j++) {
  1186. fisGetString2(fis->output[i]->mf[j]->type, fismatrix[start], col_n);
  1187. start++;
  1188. }
  1189.  
  1190. fisAssignMfPointer(fis);
  1191. fisAssignFunctionPointer(fis);
  1192.  
  1193. /* get input MF parameters */
  1194. for (i = 0; i < fis->in_n; i++) {
  1195. for (j = 0; j < fis->input[i]->mf_n; j++) {
  1196. fis->input[i]->mf[j]->nparams = MF_PARA_N;
  1197. fis->input[i]->mf[j]->params = (double *)calloc(MF_PARA_N,sizeof(double));
  1198. for (k = 0; k < MF_PARA_N; k++)
  1199. fis->input[i]->mf[j]->params[k] = fismatrix[start][k];
  1200. start++;
  1201. }
  1202. }
  1203.  
  1204. /* get Mamdani output MF parameters and compute MF value array */
  1205. if (strcmp(fis->type, "mamdani") == 0) {
  1206. for (i = 0; i < fis->out_n; i++)
  1207. for (j = 0; j < fis->output[i]->mf_n; j++) {
  1208. fis->output[i]->mf[j]->value_array =
  1209. (double *)calloc(numofpoints, sizeof(double));
  1210. fis->output[i]->mf[j]->nparams = MF_PARA_N;
  1211. fis->output[i]->mf[j]->params =
  1212. (double *)calloc(MF_PARA_N,sizeof(double));
  1213. for (k = 0; k < MF_PARA_N; k++)
  1214. fis->output[i]->mf[j]->params[k] = fismatrix[start][k];
  1215. start++;
  1216. }
  1217. fisComputeOutputMfValueArray(fis, numofpoints);
  1218. /* get Sugeno output equation parameters */
  1219. } else if (strcmp(fis->type, "sugeno") == 0) {
  1220. for (i = 0; i < fis->out_n; i++)
  1221. for (j = 0; j < fis->output[i]->mf_n; j++) {
  1222. fis->output[i]->mf[j]->nparams = fis->in_n+1;
  1223. fis->output[i]->mf[j]->params =
  1224. (double *)calloc(fis->in_n+1, sizeof(double));
  1225. for (k = 0; k < fis->in_n+1; k++)
  1226. fis->output[i]->mf[j]->params[k] = fismatrix[start][k];
  1227. start++;
  1228. }
  1229. } else {
  1230. PRINTF("fis->type = %s\n", fis->type);
  1231. fisError("Unknown fis type!");
  1232. }
  1233.  
  1234. fis->rule_list = (int **)fisCreateMatrix
  1235. (fis->rule_n, fis->in_n + fis->out_n, sizeof(int));
  1236. fis->rule_weight = (double *)calloc(fis->rule_n, sizeof(double));
  1237. fis->and_or = (int *)calloc(fis->rule_n, sizeof(int));
  1238. for (i = 0; i < fis->rule_n; i++) {
  1239. for (j = 0; j < fis->in_n + fis->out_n; j++)
  1240. fis->rule_list[i][j] = (int)fismatrix[start][j];
  1241. fis->rule_weight[i] = fismatrix[start][fis->in_n+fis->out_n];
  1242. fis->and_or[i] = (int)fismatrix[start][fis->in_n+fis->out_n+1];
  1243. start++;
  1244. }
  1245.  
  1246. fis->firing_strength = (double *)calloc(fis->rule_n, sizeof(double));
  1247. fis->rule_output = (double *)calloc(fis->rule_n, sizeof(double));
  1248. if (strcmp(fis->type, "mamdani") == 0) {
  1249. fis->BigOutMfMatrix = (double *)
  1250. calloc(fis->rule_n*numofpoints, sizeof(double));
  1251. fis->BigWeightMatrix = (double *)
  1252. calloc(fis->rule_n*numofpoints, sizeof(double));
  1253. }
  1254. fis->mfs_of_rule = (double *)calloc(fis->in_n, sizeof(double));
  1255. fisCheckDataStructure(fis);
  1256. }
  1257.  
  1258.  
  1259. /* load parameters and rule list from given fismatrix */
  1260. static void fisLoadParameter(FIS *fis, double **fismatrix, int numofpoints)
  1261. {
  1262. int start;
  1263. int i, j, k;
  1264.  
  1265. start = 11 + 2*(fis->in_n + fis->out_n);
  1266. for (i = 0; i < fis->in_n; start += fis->input[i]->mf_n, i++);
  1267. for (i = 0; i < fis->out_n; start += fis->output[i]->mf_n, i++);
  1268. for (i = 0; i < fis->in_n; start += fis->input[i]->mf_n, i++);
  1269. for (i = 0; i < fis->out_n; start += fis->output[i]->mf_n, i++);
  1270.  
  1271. /* get input MF parameters */
  1272. for (i = 0; i < fis->in_n; i++) {
  1273. for (j = 0; j < fis->input[i]->mf_n; j++) {
  1274. fis->input[i]->mf[j]->nparams = MF_PARA_N;
  1275. fis->input[i]->mf[j]->params = (double *)calloc(MF_PARA_N,sizeof(double));
  1276. for (k = 0; k < MF_PARA_N; k++)
  1277. fis->input[i]->mf[j]->params[k] = fismatrix[start][k];
  1278. start++;
  1279. }
  1280. }
  1281.  
  1282. /* get Mamdani output MF parameters */
  1283. if (strcmp(fis->type, "mamdani") == 0) {
  1284. for (i = 0; i < fis->out_n; i++)
  1285. for (j = 0; j < fis->output[i]->mf_n; j++) {
  1286. fis->output[i]->mf[j]->nparams = MF_PARA_N;
  1287. fis->output[i]->mf[j]->params =
  1288. (double *)calloc(MF_PARA_N,sizeof(double));
  1289. for (k = 0; k < MF_PARA_N; k++)
  1290. fis->output[i]->mf[j]->params[k] =
  1291. fismatrix[start][k];
  1292. start++;
  1293. }
  1294. fisComputeOutputMfValueArray(fis, numofpoints);
  1295.  
  1296. /* get Sugeno output equation parameters */
  1297. } else if (strcmp(fis->type, "sugeno") == 0) {
  1298. for (i = 0; i < fis->out_n; i++)
  1299. for (j = 0; j < fis->output[i]->mf_n; j++) {
  1300. fis->output[i]->mf[j]->nparams = fis->in_n+1;
  1301. fis->output[i]->mf[j]->params =
  1302. (double *)calloc(fis->in_n+1, sizeof(double));
  1303. for (k = 0; k < fis->in_n+1; k++)
  1304. fis->output[i]->mf[j]->params[k] =
  1305. fismatrix[start][k];
  1306. start++;
  1307. }
  1308. } else {
  1309. PRINTF("fis->type = %s\n", fis->type);
  1310. fisError("Unknown fis type!");
  1311. }
  1312.  
  1313. for (i = 0; i < fis->rule_n; i++) {
  1314. for (j = 0; j < fis->in_n + fis->out_n; j++)
  1315. fis->rule_list[i][j] = (int)fismatrix[start][j];
  1316. fis->rule_weight[i] = fismatrix[start][fis->in_n+fis->out_n];
  1317. fis->and_or[i] = (int)fismatrix[start][fis->in_n+fis->out_n+1];
  1318. start++;
  1319. }
  1320. }
  1321.  
  1322. /* load parameters contain in the given parameter array */
  1323. /* (Note that the array is compact, no zero padding */
  1324. static void fisLoadParameter1(FIS *fis, double *para_array, int numofpoints)
  1325. {
  1326. int start = 0;
  1327. int paraN;
  1328. int i, j, k;
  1329.  
  1330. /* get input MF parameters */
  1331. for (i = 0; i < fis->in_n; i++)
  1332. for (j = 0; j < fis->input[i]->mf_n; j++) {
  1333. paraN = fisGetMfParaN(fis->input[i]->mf[j]->type);
  1334. fis->input[i]->mf[j]->nparams = paraN;
  1335. fis->input[i]->mf[j]->params =
  1336. (double *)calloc(MF_PARA_N,sizeof(double));
  1337. for (k = 0; k < paraN; k++)
  1338. fis->input[i]->mf[j]->params[k] = para_array[start++];
  1339. }
  1340.  
  1341. /* get Mamdani output MF parameters */
  1342. if (strcmp(fis->type, "mamdani") == 0) {
  1343. for (i = 0; i < fis->out_n; i++)
  1344. for (j = 0; j < fis->output[i]->mf_n; j++) {
  1345. paraN = fisGetMfParaN(fis->input[i]->mf[j]->type);
  1346. fis->output[i]->mf[j]->nparams = paraN;
  1347. fis->output[i]->mf[j]->params =
  1348. (double *)calloc(MF_PARA_N,sizeof(double));
  1349. for (k = 0; k < paraN; k++)
  1350. fis->output[i]->mf[j]->params[k] = para_array[start++];
  1351. }
  1352. fisComputeOutputMfValueArray(fis, numofpoints);
  1353. /* get Sugeno output equation parameters */
  1354. } else if (strcmp(fis->type, "sugeno") == 0) {
  1355. for (i = 0; i < fis->out_n; i++)
  1356. for (j = 0; j < fis->output[i]->mf_n; j++)
  1357. fis->output[i]->mf[j]->nparams = fis->in_n+1;
  1358. fis->output[i]->mf[j]->params =
  1359. (double *)calloc(fis->in_n+1, sizeof(double));
  1360. for (k = 0; k < fis->in_n+1; k++)
  1361. fis->output[i]->mf[j]->params[k] =
  1362. para_array[start++];
  1363. } else {
  1364. PRINTF("fis->type = %s\n", fis->type);
  1365. fisError("Unknown fis type!");
  1366. }
  1367. }
  1368.  
  1369. /* Returns a FIS pointer if there is a match; otherwise signals error */
  1370. static FIS *fisMatchHandle(FIS *head, int handle)
  1371. {
  1372. FIS *p;
  1373.  
  1374. for (p = head; p != NULL; p = p->next)
  1375. if (p->handle == handle)
  1376. break;
  1377. if (p == NULL) {
  1378. PRINTF("Given handle is %d.\n", handle);
  1379. fisError("Cannot find an FIS with this handle.");
  1380. }
  1381. return(p);
  1382. }
  1383.  
  1384. /* Returns the FIS handle that matches a given name */
  1385. /* If more than two are qualified, the largest handle is returned. */
  1386. static FIS *fisMatchName(FIS *head, char *name)
  1387. {
  1388. FIS *p, *matched_p = NULL;
  1389.  
  1390. for (p = head; p != NULL; p = p->next)
  1391. if (strcmp(p->name, name) == 0)
  1392. matched_p = p;
  1393. return(matched_p);
  1394. }
  1395.  
  1396. static int fisFindMaxHandle(FIS *head)
  1397. {
  1398. FIS *p;
  1399. int max_handle = 0;
  1400.  
  1401. if (head == NULL)
  1402. return(0);
  1403.  
  1404. for (p = head; p != NULL; p = p->next)
  1405. if (p->handle > max_handle)
  1406. max_handle = p->handle;
  1407. return(max_handle);
  1408. }
  1409. /***********************************************************************
  1410. Main functions for fuzzy inference
  1411. **********************************************************************/
  1412.  
  1413. /* $Revision: $ $Date: $ */
  1414.  
  1415. /* Compute MF values for all input variables */
  1416. static void fisComputeInputMfValue(FIS *fis)
  1417. {
  1418. int i, j;
  1419. MF *mf_node;
  1420.  
  1421. for (i = 0; i < fis->in_n; i++)
  1422. for (j = 0; j < fis->input[i]->mf_n; j++) {
  1423. mf_node = fis->input[i]->mf[j];
  1424. if (!mf_node->userDefined)
  1425. mf_node->value = (*mf_node->mfFcn)
  1426. (fis->input[i]->value, mf_node->params);
  1427. else {
  1428. #ifdef MATLAB_MEX_FILE
  1429. mf_node->value =
  1430. fisCallMatlabMf(fis->input[i]->value, mf_node->nparams, mf_node->params, mf_node->type);
  1431. #else
  1432. PRINTF("Given MF %s is unknown.\n", mf_node->label);
  1433. fisError("Exiting ...");
  1434. #endif
  1435. }
  1436. }
  1437. }
  1438.  
  1439. /* Compute rule output (for Sugeno model only) */
  1440. static void fisComputeTskRuleOutput(FIS *fis)
  1441. {
  1442. int i, j, k;
  1443. double out;
  1444. MF *mf_node;
  1445.  
  1446. for (i = 0; i < fis->out_n; i++)
  1447. for (j = 0; j < fis->output[i]->mf_n; j++) {
  1448. mf_node = fis->output[i]->mf[j];
  1449. out = 0;
  1450. for (k = 0; k < fis->in_n; k++)
  1451. out += (fis->input[k]->value)*(mf_node->params[k]);
  1452. out = out + mf_node->params[fis->in_n];
  1453. mf_node->value = out;
  1454. }
  1455. }
  1456.  
  1457.  
  1458. /* Compute firing strengths */
  1459. static void fisComputeFiringStrength(FIS *fis)
  1460. {
  1461. double out = 0, mf_value;
  1462. int i, j, which_mf;
  1463.  
  1464. /* Compute original firing strengths via andFcn or orFcn */
  1465. for (i = 0; i < fis->rule_n; i++) {
  1466. if (fis->and_or[i] == 1) { /* AND premise */
  1467. for (j = 0; j < fis->in_n; j++) {
  1468. which_mf = fis->rule_list[i][j];
  1469. if (which_mf > 0)
  1470. mf_value =fis->input[j]->mf[which_mf-1]->value;
  1471. else if (which_mf == 0) /* Don't care */
  1472. mf_value = 1;
  1473. else /* Linguistic hedge NOT */
  1474. mf_value = 1 - fis->input[j]->mf[-which_mf-1]->value;
  1475. fis->mfs_of_rule[j] = mf_value;
  1476. }
  1477. if (!fis->userDefinedAnd)
  1478. out = fisArrayOperation(
  1479. fis->mfs_of_rule, fis->in_n, fis->andFcn);
  1480. else {
  1481. #ifdef MATLAB_MEX_FILE
  1482. out = fisCallMatlabFcn(
  1483. fis->mfs_of_rule, fis->in_n, fis->andMethod);
  1484. #else
  1485. PRINTF("Given AND method %s is unknown.\n", fis->andMethod);
  1486. fisError("Exiting ...");
  1487. #endif
  1488. }
  1489. } else { /* OR premise */
  1490. for (j = 0; j < fis->in_n; j++) {
  1491. which_mf = fis->rule_list[i][j];
  1492. if (which_mf > 0)
  1493. mf_value =fis->input[j]->mf[which_mf-1]->value;
  1494. else if (which_mf == 0) /* Don't care */
  1495. mf_value = 0;
  1496. else /* Linguistic hedge NOT */
  1497. mf_value = 1 - fis->input[j]->mf[-which_mf-1]->value;
  1498. fis->mfs_of_rule[j] = mf_value;
  1499. }
  1500. if (!fis->userDefinedOr)
  1501. out = fisArrayOperation(
  1502. fis->mfs_of_rule, fis->in_n, fis->orFcn);
  1503. else {
  1504. #ifdef MATLAB_MEX_FILE
  1505. out = fisCallMatlabFcn(
  1506. fis->mfs_of_rule, fis->in_n, fis->orMethod);
  1507. #else
  1508. PRINTF("Given OR method %s is unknown.\n", fis->orMethod);
  1509. fisError("Exiting ...");
  1510. #endif
  1511. }
  1512. }
  1513. fis->firing_strength[i] = out;
  1514. }
  1515.  
  1516. /* Scale the original firing strength by rule_weight */
  1517. for (i = 0; i < fis->rule_n; i++)
  1518. fis->firing_strength[i] =
  1519. fis->rule_weight[i]*fis->firing_strength[i];
  1520. }
  1521.  
  1522. #ifdef MATLAB_MEX_FILE
  1523. /* Returns the n-th value of combined m-th output MF. */
  1524. /* (n is the index into the MF value arrays of the m-th output.) */
  1525. /* Both m and n are zero-offset */
  1526. /* (for Mamdani's model only */
  1527. /* This is used in mexFunction() of evalfis.c only */
  1528. static double fisFinalOutputMf(FIS *fis, int m, int n)
  1529. {
  1530. int i, which_mf;
  1531. double mf_value, out;
  1532.  
  1533. /* The following should not be based on t-conorm */
  1534. for (i = 0; i < fis->rule_n; i++) {
  1535. /* rule_list is 1-offset */
  1536. which_mf = fis->rule_list[i][fis->in_n+m];
  1537. if (which_mf > 0)
  1538. mf_value = fis->output[m]->mf[which_mf-1]->value_array[n];
  1539. else if (which_mf == 0) /* Don't care */
  1540. mf_value = 0;
  1541. else
  1542. mf_value = 1-fis->output[m]->mf[-which_mf-1]->value_array[n];
  1543. if (!fis->userDefinedImp)
  1544. fis->rule_output[i] = (*fis->impFcn)(mf_value,
  1545. fis->firing_strength[i]);
  1546. else {
  1547. double tmp[2];
  1548. tmp[0] = mf_value;
  1549. tmp[1] = fis->firing_strength[i];
  1550. fis->rule_output[i] = fisCallMatlabFcn(tmp, 2, fis->impMethod);
  1551. }
  1552. }
  1553. if (!fis->userDefinedAgg)
  1554. out = fisArrayOperation(fis->rule_output, fis->rule_n, fis->aggFcn);
  1555. else
  1556. out = fisCallMatlabFcn(fis->rule_output, fis->rule_n, fis->aggMethod);
  1557. return(out);
  1558. }
  1559. #endif
  1560.  
  1561.  
  1562. /* Returns the aggregated MF aggMF of the m-th output variable . */
  1563. /* (for Mamdani's model only */
  1564. static void fisFinalOutputMf2(FIS *fis, int m, double *aggMF, int numofpoints)
  1565. {
  1566. int i, j, which_mf;
  1567.  
  1568. /* fill in BigOutMfMatrix */
  1569. /* The following should not be based on t-conorm */
  1570. for (i = 0; i < fis->rule_n; i++) {
  1571. which_mf = fis->rule_list[i][fis->in_n+m];
  1572. if (which_mf > 0)
  1573. for (j = 0; j < numofpoints; j++)
  1574. /*
  1575. fis->BigOutMfMatrix[i][j] =
  1576. fis->output[m]->mf[which_mf-1]->value_array[j];
  1577. */
  1578. fis->BigOutMfMatrix[j*fis->rule_n+i] =
  1579. fis->output[m]->mf[which_mf-1]->value_array[j];
  1580. else if (which_mf < 0)
  1581. for (j = 0; j < numofpoints; j++)
  1582. /*
  1583. fis->BigOutMfMatrix[i][j] =
  1584. 1-fis->output[m]->mf[-which_mf-1]->value_array[j];
  1585. */
  1586. fis->BigOutMfMatrix[j*fis->rule_n+i] =
  1587. 1 - fis->output[m]->mf[-which_mf-1]->value_array[j];
  1588. else /* which_mf == 0 */
  1589. for (j = 0; j < numofpoints; j++)
  1590. fis->BigOutMfMatrix[j*fis->rule_n+i] = 0;
  1591. }
  1592.  
  1593. /* fill in BigWeightMatrix */
  1594. for (i = 0; i < fis->rule_n; i++)
  1595. for (j = 0; j < numofpoints; j++)
  1596. fis->BigWeightMatrix[j*fis->rule_n+i] =
  1597. fis->firing_strength[i];
  1598.  
  1599. /* apply implication operator */
  1600. if (!fis->userDefinedImp)
  1601. for (i = 0; i < (fis->rule_n)*numofpoints; i++)
  1602. fis->BigOutMfMatrix[i] = (*fis->impFcn)(
  1603. fis->BigWeightMatrix[i], fis->BigOutMfMatrix[i]);
  1604. else {
  1605. #ifdef MATLAB_MEX_FILE
  1606. fisCallMatlabFcn2(fis->BigWeightMatrix, fis->BigOutMfMatrix,
  1607. fis->rule_n, numofpoints, fis->impMethod, fis->BigOutMfMatrix);
  1608. #else
  1609. PRINTF("Given IMP method %s is unknown.\n", fis->impMethod);
  1610. fisError("Exiting ...");
  1611. #endif
  1612. }
  1613.  
  1614. /* apply MATLAB aggregate operator */
  1615. if (!fis->userDefinedAgg)
  1616. for (i = 0; i < numofpoints; i++)
  1617. aggMF[i] = fisArrayOperation(
  1618. fis->BigOutMfMatrix+i*fis->rule_n,
  1619. fis->rule_n, fis->aggFcn);
  1620. else {
  1621. #ifdef MATLAB_MEX_FILE
  1622. fisCallMatlabFcn1(fis->BigOutMfMatrix, fis->rule_n,
  1623. numofpoints, fis->aggMethod, aggMF);
  1624. #else
  1625. PRINTF("Given AGG method %s is unknown.\n", fis->aggMethod);
  1626. fisError("Exiting ...");
  1627. #endif
  1628. }
  1629. }
  1630.  
  1631. /***********************************************************************
  1632. Evaluate the constructed FIS based on given input vector
  1633. **********************************************************************/
  1634.  
  1635. /* compute outputs and put them into output nodes */
  1636. void fisEvaluate(FIS *fis, int numofpoints)
  1637. {
  1638. double out = 0;
  1639. double total_w, total_wf;
  1640. int i, j, k, which_mf;
  1641.  
  1642. if (fis == NULL) {
  1643. PRINTF("FIS data structure has not been built yet.\n");
  1644. fisError("Exiting ...");
  1645. }
  1646.  
  1647. fisComputeInputMfValue(fis);
  1648. fisComputeFiringStrength(fis);
  1649. total_w = fisArrayOperation(fis->firing_strength, fis->rule_n, fisSum);
  1650. if (total_w == 0) {
  1651. #ifdef SS_SFCN /* Do not generate warning for S-function */
  1652. PRINTF("Warning: no rule is fired for input [");
  1653. for (i = 0; i < fis->in_n; i++)
  1654. PRINTF("%f ", fis->input[i]->value);
  1655. PRINTF("]\n");
  1656. PRINTF("Average of the range for each output variable is used as default output.\n\n");
  1657. #endif
  1658. for (i = 0; i < fis->out_n; i++)
  1659. fis->output[i]->value = (fis->output[i]->bound[0] +
  1660. fis->output[i]->bound[1])/2;
  1661. return;
  1662. }
  1663.  
  1664. if (strcmp(fis->type, "sugeno") == 0) {
  1665. fisComputeTskRuleOutput(fis);
  1666. /* Find each rule's output */
  1667. for (i = 0; i < fis->out_n; i++) {
  1668. for (j = 0; j < fis->rule_n; j++) {
  1669. which_mf = fis->rule_list[j][fis->in_n + i] - 1;
  1670. if (which_mf == -1) /* don't_care consequent */
  1671. fis->rule_output[j] = 0;
  1672. else
  1673. fis->rule_output[j] = fis->output[i]->mf[which_mf]->value;
  1674. }
  1675. /* Weighted average to find the overall output*/
  1676. total_wf = 0;
  1677. for (k = 0; k < fis->rule_n; k++)
  1678. total_wf += (fis->firing_strength[k]*
  1679. fis->rule_output[k]);
  1680.  
  1681. if (strcmp(fis->defuzzMethod, "wtaver") == 0)
  1682. fis->output[i]->value = total_wf/total_w;
  1683. else if (strcmp(fis->defuzzMethod, "wtsum") == 0)
  1684. fis->output[i]->value = total_wf;
  1685. else {
  1686. PRINTF("Unknown method (%s) for Sugeno model!", fis->defuzzMethod);
  1687. fisError("Legal methods: wtaver, wtsum");
  1688. }
  1689. }
  1690. }
  1691. else if (strcmp(fis->type, "mamdani") == 0)
  1692. for (i = 0; i < fis->out_n; i++) {
  1693. /* double aggMF[MF_POINT_N];
  1694. double X[MF_POINT_N];*/
  1695. double *aggMF;
  1696. double *X;
  1697.  
  1698. double min = fis->output[i]->bound[0];
  1699. double max = fis->output[i]->bound[1];
  1700. double step = (max - min)/(numofpoints - 1);
  1701.  
  1702. X = (double *)calloc(numofpoints, sizeof(double));
  1703. aggMF = (double *)calloc(numofpoints, sizeof(double));
  1704.  
  1705. for (j = 0; j < numofpoints; j++)
  1706. X[j] = min + step*j;
  1707. /* fill in aggMF */
  1708. fisFinalOutputMf2(fis, i, aggMF, numofpoints);
  1709. /* defuzzification */
  1710. if (!fis->userDefinedDefuzz)
  1711. out = (*fis->defuzzFcn)(fis, i, aggMF, numofpoints);
  1712. else { /* user defined defuzzification */
  1713. #ifdef MATLAB_MEX_FILE
  1714. out = fisCallMatlabDefuzz(X, aggMF, numofpoints, fis->defuzzMethod);
  1715. #else
  1716. PRINTF("Given defuzzification method %s is unknown.\n", fis->defuzzMethod);
  1717. fisError("Exiting ...");
  1718. #endif
  1719. }
  1720. fis->output[i]->value = out;
  1721. free(X);
  1722. free(aggMF);
  1723. }
  1724. else {
  1725. PRINTF("Given FIS %s is unknown.\n", fis->name);
  1726. fisError("Exiting ...");
  1727. }
  1728. }
  1729.  
  1730. /* given input vector and FIS data structure, return output */
  1731. /* this is a wrap-up on fisEvaluate () */
  1732. /* used in fismain() only */
  1733. static void getFisOutput(double *input, FIS *fis, double *output)
  1734. {
  1735. int i;
  1736.  
  1737. /* dispatch input */
  1738. for (i = 0; i < fis->in_n; i++)
  1739. fis->input[i]->value = input[i];
  1740.  
  1741. /* evaluate FIS */
  1742. fisEvaluate(fis, 101);
  1743.  
  1744. /* dispatch output */
  1745. for (i = 0; i < fis->out_n; i++)
  1746. output[i] = fis->output[i]->value;
  1747. }
  1748.  
  1749. /* $Revision: $ $Date: $ */
  1750.  
  1751. /* return the next valid line without comments */
  1752. static char *
  1753. getNextLine(char *buf, FILE *fp)
  1754. {
  1755. char *returned_value;
  1756. int i, j;
  1757.  
  1758. returned_value = fgets(buf, STR_LEN, fp);
  1759. if (NULL == returned_value)
  1760. return(NULL);
  1761.  
  1762. /* skip if it starts with '%' or '\n' */
  1763. if (buf[0] == '%' || buf[0] == '\n')
  1764. return(getNextLine(buf, fp));
  1765.  
  1766. /* get rid of trailing comment or new line */
  1767. for (i = 0; buf[i]!='%' && buf[i]!='\n' && i < STR_LEN; i++);
  1768. /*
  1769. printf("%s\n", buf);
  1770. printf("i = %d\n", i);
  1771. */
  1772. for (j = i; j < STR_LEN; j++)
  1773. buf[j] = 0;
  1774.  
  1775. return(returned_value);
  1776. }
  1777.  
  1778. /* find number x in "******=x" */
  1779. static double
  1780. getNumber(char *buf, FILE *fp)
  1781. {
  1782. int tmp;
  1783. char string[STR_LEN];
  1784. double num;
  1785.  
  1786. if (getNextLine(buf, fp) == NULL)
  1787. fisError("getNumber: Incomplete FIS file!");
  1788.  
  1789. tmp = sscanf(buf, " %[^=] = %lf ", string, &num);
  1790. if (tmp != 2) {
  1791. printf("Error format in FIS file when parsing\n");
  1792. printf("\"%s\"\n", buf);
  1793. fisError("Error in getNumber().");
  1794. }
  1795. /*
  1796. printf("getNumber --> %s%lf\n", string, num);
  1797. printf("getNumber --> %lf\n", num);
  1798. */
  1799. return(num);
  1800. }
  1801.  
  1802. /* find string x in "*******='x'" */
  1803. static void
  1804. getString(char *buf, FILE *fp, double *array)
  1805. {
  1806. int i;
  1807. char string1[STR_LEN];
  1808. char string2[STR_LEN];
  1809. int tmp;
  1810.  
  1811. if (getNextLine(buf, fp) == NULL)
  1812. fisError("getString: Incomplete FIS file!");
  1813.  
  1814. tmp = sscanf(buf, " %[^'] '%[^']' ", string1, string2);
  1815. if (tmp != 2) {
  1816. printf("Error format in FIS file when parsing\n");
  1817. printf("\"%s\"\n", buf);
  1818. fisError("Error in getString().");
  1819. }
  1820.  
  1821. /* copy it to output array */
  1822. for (i = 0; i < (int)strlen(string2); i++)
  1823. array[i] = string2[i];
  1824. /*
  1825. printf("getString --> %s\n", string2);
  1826. */
  1827. }
  1828.  
  1829. /* put a string "a b c" to an array [a b c]*/
  1830. /* return number of elements */
  1831. static int
  1832. getArray(char *string, double *array)
  1833. {
  1834. int i;
  1835. int start, end, index;
  1836. char tmp[STR_LEN];
  1837.  
  1838. start = 0; /* start of a number */
  1839. end = 0; /* end of a number */
  1840. index = 0; /* index of array */
  1841. while (start <= (int)strlen(string)-1) {
  1842. /* find end */
  1843. for (end = start; end < (int)strlen(string); end++)
  1844. if (string[end] == ' ')
  1845. break;
  1846. for (i = start; i <= end; i++)
  1847. tmp[i-start] = string[i];
  1848. tmp[i-start] = 0;
  1849. array[index++] = atof(tmp);
  1850. /* find new start */
  1851. for (start = end; start < (int)strlen(string); start++)
  1852. if (string[start] != ' ')
  1853. break;
  1854. }
  1855. /*
  1856. printf("%s\n", string);
  1857. fisPrintArray(array, 8);
  1858. */
  1859. return(index);
  1860. }
  1861.  
  1862. static void
  1863. getMfN(char *filename, int in_n, double *in_mf_n, int out_n, double *out_mf_n)
  1864. {
  1865. int i, tmp;
  1866. char buf[STR_LEN];
  1867. FILE *fp = fopen(filename, "r");
  1868.  
  1869. for (i = 0; i < in_n+out_n; i++) {
  1870. while (1) {
  1871. if (getNextLine(buf, fp) == NULL)
  1872. fisError("Not enough NumMFs in FIS file!");
  1873. if (sscanf(buf, " NumMFs = %d ", &tmp) == 1)
  1874. break;
  1875. }
  1876. if (i < in_n)
  1877. in_mf_n[i] = tmp;
  1878. else
  1879. out_mf_n[i-in_n] = tmp;
  1880. }
  1881. fclose(fp);
  1882. /*
  1883. fisPrintArray(in_mf_n, in_n);
  1884. fisPrintArray(out_mf_n, out_n);
  1885. */
  1886. }
  1887.  
  1888. /* return an empty FIS matrix with right size */
  1889. static double **
  1890. returnEmptyFismatrix(char *filename, int *row_n_p, int *col_n_p)
  1891. {
  1892. int in_n, out_n, rule_n, total_in_mf_n, total_out_mf_n;
  1893. int row_n, col_n;
  1894. char buf[STR_LEN], fisType[STR_LEN];
  1895. char fisName[STR_LEN], IoName[STR_LEN];
  1896. char tmp1[STR_LEN], tmp2[STR_LEN], tmp3[STR_LEN], tmp4[STR_LEN];
  1897. FILE *fp;
  1898. double *in_mf_n;
  1899. double *out_mf_n;
  1900. double **fismatrix;
  1901.  
  1902. /* find the row_n */
  1903. fp = fopen(filename, "r");
  1904. if (fp == NULL) ShowMessage("dfdsf!");
  1905. /* find in_n */
  1906. while (1) {
  1907. if (getNextLine(buf, fp) == NULL)
  1908. fisError("Cannot find NumInputs in FIS file!");
  1909. if (sscanf(buf, " NumInputs = %d ", &in_n) == 1)
  1910. break;
  1911. }
  1912. /* find out_n */
  1913. while (1) {
  1914. if (getNextLine(buf, fp) == NULL)
  1915. fisError("Cannot find NumOutputs in FIS file!");
  1916. if (sscanf(buf, " NumOutputs = %d ", &out_n) == 1)
  1917. break;
  1918. }
  1919. /* find rule_n */
  1920. while (1) {
  1921. if (getNextLine(buf, fp) == NULL)
  1922. fisError("Cannot find NumRules in FIS file!");
  1923. if (sscanf(buf, " NumRules = %d ", &rule_n) == 1)
  1924. break;
  1925. }
  1926. fclose(fp);
  1927. in_mf_n = (double *)calloc(in_n, sizeof(double));
  1928. out_mf_n = (double *)calloc(out_n, sizeof(double));
  1929. getMfN(filename, in_n, in_mf_n, out_n, out_mf_n);
  1930. total_in_mf_n = fisArrayOperation(in_mf_n, in_n, fisSum);
  1931. total_out_mf_n = fisArrayOperation(out_mf_n, out_n, fisSum);
  1932. row_n = 11 + 2*(in_n+out_n) +
  1933. 3*(total_in_mf_n + total_out_mf_n) + rule_n;
  1934. free(in_mf_n);
  1935. free(out_mf_n);
  1936.  
  1937. /* find the col_n */
  1938. fp = fopen(filename, "r");
  1939. /* find FIS name */
  1940. while (1) {
  1941. if (getNextLine(buf, fp) == NULL)
  1942. fisError("Cannot find FIS Name in FIS file!");
  1943. if (sscanf(buf, " Name = '%[^']' ", fisName) == 1)
  1944. break;
  1945. }
  1946. col_n = (int)strlen(fisName);
  1947. col_n = MAX(col_n, 8); /* 'centroid' defuzzification */
  1948. /* find FIS type */
  1949. while (1) {
  1950. if (getNextLine(buf, fp) == NULL)
  1951. fisError("Cannot find FIS Type in FIS file!");
  1952. if (sscanf(buf, " Type = '%[^']' ", fisType) == 1)
  1953. break;
  1954. }
  1955. /* find IO names, MF labels, MF types */
  1956. while (getNextLine(buf, fp) != NULL) {
  1957. if (sscanf(buf, " Name = '%[^']' ", IoName) == 1)
  1958. col_n = MAX(col_n, (int)strlen(IoName));
  1959. if (sscanf(buf, " %[^'] '%[^']' : '%[^']' , [ %[^]] ",
  1960. tmp1, tmp2, tmp3, tmp4) == 4) {
  1961. col_n = MAX(col_n, (int)strlen(tmp2));
  1962. col_n = MAX(col_n, (int)strlen(tmp3));
  1963. }
  1964. }
  1965. if (!strcmp(fisType, "mamdani"))
  1966. col_n = MAX(col_n, MF_PARA_N);
  1967. else if (!strcmp(fisType, "sugeno"))
  1968. col_n = MAX(col_n, in_n+out_n+2);
  1969. else
  1970. fisError("Unknown FIS type!");
  1971.  
  1972. fclose(fp);
  1973. /*
  1974. printf("row_n = %d\n", row_n);
  1975. printf("col_n = %d\n", col_n);
  1976. */
  1977. *row_n_p = row_n;
  1978. *col_n_p = col_n;
  1979. fismatrix = (double **)fisCreateMatrix(row_n, col_n, sizeof(double));
  1980. return(fismatrix);
  1981. }
  1982.  
  1983. /* return a FIS matrix with all information */
  1984. static double **
  1985. returnFismatrix(char *fis_file, int *row_n_p, int *col_n_p)
  1986. {
  1987. int i, j, k;
  1988. FILE *fp;
  1989. char buf[STR_LEN];
  1990. char str1[STR_LEN], str2[STR_LEN], str3[STR_LEN], str4[STR_LEN];
  1991. char fisType[STR_LEN];
  1992.  
  1993. int in_n, out_n, rule_n;
  1994. int mf_n;
  1995.  
  1996. int now;
  1997. double **fismatrix;
  1998. double *in_mf_n, *out_mf_n;
  1999.  
  2000. fismatrix = returnEmptyFismatrix(fis_file, row_n_p, col_n_p);
  2001.  
  2002. fp = fopen(fis_file, "r");
  2003. /* looping till it finds "[System]" */
  2004. while (1) {
  2005. if (getNextLine(buf, fp) == NULL)
  2006. fisError("Cannot find [System] in FIS file!");
  2007. if (!strcmp(buf, "[System]")) /* found it! */
  2008. break;
  2009. }
  2010.  
  2011. /* get FIS information */
  2012. now = 0;
  2013. getString(buf, fp, fismatrix[now++]); /* name */
  2014. getString(buf, fp, fismatrix[now++]); /* type */
  2015. for (i = 0; i < STR_LEN && fismatrix[1][i] != 0; i++)
  2016. fisType[i] = (int) fismatrix[1][i];
  2017. fisType[i] = 0;
  2018. in_n = (int)getNumber(buf, fp);
  2019. out_n = (int)getNumber(buf, fp);
  2020.  
  2021. fismatrix[now][0] = (double) in_n;
  2022. fismatrix[now][1] = (double) out_n;
  2023. now++;
  2024.  
  2025. /* create in_mf_n and out_mf_n */
  2026. in_mf_n = (double *)calloc(in_n, sizeof(double));
  2027. out_mf_n = (double *)calloc(out_n, sizeof(double));
  2028. getMfN(fis_file, in_n, in_mf_n, out_n, out_mf_n);
  2029. for (i = 0; i < in_n; i++)
  2030. fismatrix[now][i] = in_mf_n[i];
  2031. now++;
  2032. for (i = 0; i < out_n; i++)
  2033. fismatrix[now][i] = out_mf_n[i];
  2034. now++;
  2035. rule_n = (int)getNumber(buf, fp);
  2036. fismatrix[now++][0] = (double) rule_n;
  2037. getString(buf, fp, fismatrix[now++]); /* and method */
  2038. getString(buf, fp, fismatrix[now++]); /* or method */
  2039. getString(buf, fp, fismatrix[now++]); /* imp method */
  2040. getString(buf, fp, fismatrix[now++]); /* agg method */
  2041. getString(buf, fp, fismatrix[now++]); /* defuzz method */
  2042. fclose(fp);
  2043.  
  2044. /*
  2045. printf("in_n = %d, out_n = %d, rule_n = %d\n", in_n, out_n, rule_n);
  2046. */
  2047.  
  2048. /* get input & output labels */
  2049. /* get rid of FIS name */
  2050. fp = fopen(fis_file, "r");
  2051. while (1) {
  2052. if (getNextLine(buf, fp) == NULL)
  2053. fisError("Cannot find the first Name in FIS file!");
  2054. if (sscanf(buf, " Name = '%[^']' ", str1) == 1)
  2055. break;
  2056. }
  2057. for (i = 0; i < in_n+out_n; i++) {
  2058. while (1) {
  2059. if (getNextLine(buf, fp) == NULL)
  2060. fisError("Not enough Name in FIS file!");
  2061. if (sscanf(buf, " Name = '%[^']' ", str1) == 1)
  2062. break;
  2063. }
  2064. for (j = 0; j < (int)strlen(str1); j++)
  2065. fismatrix[now][j] = str1[j];
  2066. now++;
  2067. }
  2068. fclose(fp);
  2069.  
  2070. /* get input & output ranges */
  2071. fp = fopen(fis_file, "r");
  2072. for (i = 0; i < in_n+out_n; i++) {
  2073. while (1) {
  2074. if (getNextLine(buf, fp) == NULL)
  2075. fisError("Not enough Range in FIS file!");
  2076. if (sscanf(buf, " Range = [ %[^]] ", str1) == 1)
  2077. break;
  2078. }
  2079. if (getArray(str1, fismatrix[now++]) != 2)
  2080. fisError("Error in parsing I/O ranges.");
  2081. }
  2082. fclose(fp);
  2083.  
  2084. /* get input and output MF labels */
  2085. fp = fopen(fis_file, "r");
  2086. for (i = 0; i < in_n+out_n; i++) {
  2087. mf_n = i < in_n? in_mf_n[i]:out_mf_n[i-in_n];
  2088. for (j = 0; j < mf_n; j++) {
  2089. while (1) {
  2090. if (getNextLine(buf, fp) == NULL)
  2091. fisError("Not enough MF Labels in FIS file!");
  2092. if (sscanf(buf, " %[^']'%[^']' : '%[^']' , [ %[^]] ",
  2093. str1, str2, str3, str4) == 4)
  2094. break;
  2095. }
  2096. for (k = 0; k < (int)strlen(str2); k++)
  2097. fismatrix[now][k] = str2[k];
  2098. now++;
  2099. }
  2100. }
  2101. fclose(fp);
  2102.  
  2103. /* get input and output MF types */
  2104. fp = fopen(fis_file, "r");
  2105. for (i = 0; i < in_n+out_n; i++) {
  2106. mf_n = i < in_n? in_mf_n[i]:out_mf_n[i-in_n];
  2107. for (j = 0; j < mf_n; j++) {
  2108. while (1) {
  2109. if (getNextLine(buf, fp) == NULL)
  2110. fisError("Not enough MF types in FIS file!");
  2111. if (sscanf(buf, " %[^']'%[^']' : '%[^']' , [ %[^]] ",
  2112. str1, str2, str3, str4) == 4)
  2113. break;
  2114. }
  2115. for (k = 0; k < (int)strlen(str3); k++)
  2116. fismatrix[now][k] = str3[k];
  2117. now++;
  2118. }
  2119. }
  2120. fclose(fp);
  2121.  
  2122. /* get input & output MF parameters */
  2123. fp = fopen(fis_file, "r");
  2124. for (i = 0; i < in_n+out_n; i++) {
  2125. mf_n = i < in_n? in_mf_n[i]:out_mf_n[i-in_n];
  2126. for (j = 0; j < mf_n; j++) {
  2127. while (1) {
  2128. if (getNextLine(buf, fp) == NULL)
  2129. fisError("Not enough MF parameters in FIS file!");
  2130. if (sscanf(buf, " %[^']'%[^']' : '%[^']' , [ %[^]] ",
  2131. str1, str2, str3, str4) == 4) {
  2132. /*
  2133. printf("%s\n", buf);
  2134. printf("str1 = %s\n", str1);
  2135. printf("str2 = %s\n", str2);
  2136. printf("str3 = %s\n", str3);
  2137. printf("str4 = %s\n", str4);
  2138. */
  2139. break;
  2140. }
  2141. }
  2142. if (i < in_n) {
  2143. if (getArray(str4, fismatrix[now]) > MF_PARA_N) {
  2144. /*
  2145. printf("%s\n", str4);
  2146. printf("%d\n", getArray(str4, fismatrix[now]));
  2147. */
  2148. fisError("Error in parsing input MF parameters.");
  2149. }
  2150. } else {
  2151. if (!strcmp(fisType, "mamdani")) {
  2152. if (getArray(str4, fismatrix[now]) > MF_PARA_N) {
  2153. fisError("Error in parsing output MF parameters.");
  2154. }
  2155. } else { /* sugeno system */
  2156. int tmp = getArray(str4, fismatrix[now]);
  2157. if (!strcmp(str3, "constant")){
  2158. if (tmp != 1)
  2159. fisError("Zero-order Sugeno system does not has the right number of output MF parameters.");
  2160. else { /* pad with zeros for zero coefficients */
  2161. fismatrix[now][in_n] = fismatrix[now][0];
  2162. fismatrix[now][0] = 0;
  2163. }
  2164. } else if (!strcmp(str3, "linear")) {
  2165. if (tmp != in_n+1)
  2166. fisError("First-order Sugeno system does not has the right number of output MF parameters.");
  2167. } else {
  2168. fisError("Unknown output MF type for Sugeno system.");
  2169. }
  2170. }
  2171. }
  2172. now++;
  2173. }
  2174. }
  2175. fclose(fp);
  2176.  
  2177. /* get rule list */
  2178. fp = fopen(fis_file, "r");
  2179. /* looping till it finds "[Rules]" */
  2180. while (1) {
  2181. if (getNextLine(buf, fp) == NULL)
  2182. fisError("Cannot find [Rules] in FIS file!");
  2183. if (!strcmp(buf, "[Rules]")) /* found it! */
  2184. break;
  2185. }
  2186. for (i = 0; i < rule_n; i++) {
  2187. if (getNextLine(buf, fp) == NULL)
  2188. fisError("Not enough rule list in FIS file!");
  2189. /* get rid of ",", "(" and ")" */
  2190. for (j = 0; j < (int)strlen(buf); j++)
  2191. if (buf[j]==',' || buf[j]=='(' || buf[j]==')' || buf[j]==':')
  2192. buf[j] = ' ';
  2193. if (getArray(buf, fismatrix[now++]) != in_n + out_n + 2) {
  2194. /*
  2195. printf("%s\n", buf);
  2196. printf("%d\n", getArray(buf, fismatrix[now]));
  2197. */
  2198. fisError("Error in parsing rule list!");
  2199. }
  2200. }
  2201. fclose(fp);
  2202.  
  2203. /* clean up */
  2204. free(in_mf_n);
  2205. free(out_mf_n);
  2206.  
  2207. return(fismatrix);
  2208. }
  2209.  
  2210. /* return data matrix */
  2211. double **
  2212. returnDataMatrix(char *filename, int *row_n_p, int *col_n_p)
  2213. {
  2214. double **datamatrix;
  2215. int element_n = 0, row_n = 0, col_n = 0, i, j;
  2216. FILE *fp;
  2217. char str1[STR_LEN];
  2218. double num1;
  2219.  
  2220. /* find the size of the data file */
  2221.  
  2222. /* find data number */
  2223. fp = fopen(filename, "r");
  2224. row_n = 0;
  2225. while (fscanf(fp, " %[^\n] ", str1) != EOF)
  2226. row_n++;
  2227. fclose(fp);
  2228.  
  2229. /* find element number */
  2230. fp = fopen(filename, "r");
  2231. while (fscanf(fp, "%lf", &num1) != EOF)
  2232. element_n++;
  2233. fclose(fp);
  2234. col_n = element_n/row_n;
  2235. /*
  2236. printf("row_n = %d\n", row_n);
  2237. printf("element_n = %d\n", element_n);
  2238. printf("col_n = %d\n", col_n);
  2239. */
  2240.  
  2241. /* create a data matrix */
  2242. datamatrix = (double **)fisCreateMatrix(row_n, col_n, sizeof(double));
  2243. /* read data file and put data into data matrix */
  2244. fp = fopen(filename, "r");
  2245. for (i = 0; i < row_n; i++) {
  2246. for (j = 0; j < col_n; j++) {
  2247. if (fscanf(fp, "%lf", &num1) != EOF)
  2248. datamatrix[i][j] = num1;
  2249. else
  2250. fisError("Not enough data in data file!");
  2251. }
  2252. }
  2253. fclose(fp);
  2254.  
  2255. *row_n_p = row_n;
  2256. *col_n_p = col_n;
  2257. return(datamatrix);
  2258. }
  2259.  
  2260. double **ConsultFIS(double **inputMatrix, int row_n, int col_n,
  2261. char *fis_file)
  2262. {
  2263. FIS *fis;
  2264. int i, j;
  2265.  
  2266.  
  2267. double **fisMatrix, **outputMatrix;
  2268. int fis_row_n, fis_col_n;
  2269.  
  2270. fisMatrix = returnFismatrix(fis_file, &fis_row_n, &fis_col_n);
  2271.  
  2272. // build FIS data structure
  2273. fis = (FIS *)calloc(1, sizeof(FIS));
  2274. fisBuildFisNode(fis, fisMatrix, fis_col_n, MF_POINT_N);
  2275.  
  2276.  
  2277. // create output matrix
  2278. outputMatrix = (double **)fisCreateMatrix(row_n, fis->out_n, sizeof(double));
  2279.  
  2280. // evaluate FIS on each input vector
  2281. for (i = 0; i < row_n; i++)
  2282. getFisOutput(inputMatrix[i], fis, outputMatrix[i]);
  2283.  
  2284. // fis->out_n - кол-во выходов
  2285.  
  2286. // clean up memory
  2287. fisFreeFisNode(fis);
  2288. fisFreeMatrix((void **)fisMatrix, fis_row_n);
  2289.  
  2290. return outputMatrix;
  2291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement