fis.c

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