nodefun.c

Package [view]: fuzzy.rar
Upload User: hnchenxi
Upload Date: 2008-11-02
Package Size: 1083k
Code Size: 6k
Category: AI-NN-PR
Development Platform: Matlab
  1. /* Copyright 1994-2002 The MathWorks, Inc.  */
  2. /* $Revision: 1.12 $  $Date: 2002/06/05 13:17:17 $  $Author: eyarrow $ */
  3. /* setup the input array of node with index index */
  4. static void anfisSetupInputArray(FIS *fis, int index)
  5. {
  6. FAN *p = fis->node[index]->fanin;
  7. int i;
  8. for (i = 0; i < fis->node[index]->fanin_n; i++, p = p->next)
  9. fis->node[index]->input[i] = fis->node[p->index]->value;
  10. }
  11. /* Node function for each layer */
  12. /* action ==   "forward" --> return O_{index}
  13.    action ==  "backward" --> return dO_{index}/dO_{index2}
  14. (derivative w.r.t. fan-in nodes)
  15.    action == "parameter" --> return dO_{index}/dP_{index2}
  16. (derivative w.r.t. parameters)
  17. */
  18. /* layer 0 */
  19. static DOUBLE anfisInputNode(FIS *fis, int index, char *action, int index2)
  20. {
  21. fisError("anfisInputNode should not be called at all!");
  22. return(0); /* for suppressing compiler's warning only */
  23. }
  24. /* layer 1 */
  25. static DOUBLE anfisMfNode(FIS *fis, int index, char *action, int index2)
  26. {
  27. int which_input = fis->node[index]->fanin->index;
  28. int which_mf = fis->node[index]->ll_index;
  29. DOUBLE input_value = fis->node[which_input]->value;
  30. DOUBLE (*mfFcn)() = fis->input[which_input]->mf[which_mf]->mfFcn;
  31. DOUBLE *para = fis->node[index]->para;
  32. if (strcmp(action, "forward") == 0) {
  33. /* temperary storage for future use */
  34. fis->node[index]->tmp = (*mfFcn)(input_value, para);
  35. return(fis->node[index]->tmp);
  36. }
  37. if (strcmp(action, "backward") == 0)
  38. fisError("MF derivatives w.r.t. inputs should not be called!");
  39. if (strcmp(action, "parameter") == 0) {
  40. /* temperary storage for future use */
  41. return(fisMfDerivative(mfFcn, input_value, para, index2));
  42. }
  43. fisError("Unknown action!n");
  44. return(0); /* for suppressing compiler's warning only */
  45. }
  46. /* layer 2 */
  47. static DOUBLE anfisInvNode(FIS *fis, int index, char *action, int index2)
  48. {
  49. int fanin_node_index = fis->node[index]->fanin->index;
  50. DOUBLE in_mf_value = fis->node[fanin_node_index]->value;
  51. if (strcmp(action, "forward") == 0)
  52. return(1.0 - in_mf_value);
  53. if (strcmp(action, "backward") == 0)
  54. return(-1.0);
  55. if (strcmp(action, "parameter") == 0)
  56. return(0.0);
  57. fisError("Unknown action!n");
  58. return(0); /* for suppressing compiler's warning only */
  59. }
  60. /* layer 3 */
  61. static DOUBLE anfisAndOrNode(FIS *fis, int index, char *action, int index2)
  62. {
  63. DOUBLE *input = fis->node[index]->input;
  64. int which_rule = fis->node[index]->l_index;
  65. int and_or = fis->and_or[which_rule];
  66. DOUBLE (*AndOrFcn)() = and_or == 1? fis->andFcn:fis->orFcn;
  67. int i;
  68. anfisSetupInputArray(fis, index);
  69. if (strcmp(action, "forward") == 0) {
  70. fis->node[index]->tmp =
  71. fisArrayOperation(input, fis->node[index]->fanin_n,
  72. AndOrFcn);
  73. return(fis->node[index]->tmp);
  74. }
  75. if (strcmp(action, "backward") == 0) {
  76. if ((AndOrFcn == fisMin) || (AndOrFcn == fisMax)) {
  77. for (i = 0; i < fis->node[index]->fanin_n; i++)
  78. if (fis->node[index]->tmp == input[i])
  79. break;
  80. return(index2 == i? 1.0:0.0);
  81. }
  82. if (AndOrFcn == fisProduct) {
  83. DOUBLE product = 1.0;
  84. for (i = 0; i < fis->node[index]->fanin_n; i++) {
  85. if (i == index2)
  86. continue;
  87. product *= input[i];
  88. }
  89. return(product);
  90. }
  91. if (AndOrFcn == fisProbOr) {
  92. DOUBLE product = 1.0;
  93. for (i = 0; i < fis->node[index]->fanin_n; i++) {
  94. if (i == index2)
  95. continue;
  96. product *= (1 - input[i]);
  97. }
  98. return(product);
  99. }
  100. }
  101. if (strcmp(action, "parameter") == 0)
  102. return(0.0);
  103. fisError("Unknown action!n");
  104. return(0); /* for suppressing compiler's warning only */
  105. }
  106. /* layer 4 */
  107. static DOUBLE anfisRuleOutputNode(FIS *fis, int index, char *action, int index2)
  108. {
  109. DOUBLE *input;
  110. DOUBLE firing_strength;
  111. DOUBLE *para = fis->node[index]->para;
  112. int i;
  113. DOUBLE sum = 0;
  114. anfisSetupInputArray(fis, index);
  115. input = fis->node[index]->input;
  116. /* ========== */
  117. if (fis->order==1) {
  118. for (i = 0; i < fis->in_n; i++)
  119. sum += input[i]*para[i];
  120. sum += para[fis->in_n];
  121. } else
  122. sum = para[0];
  123. firing_strength = input[fis->in_n];
  124. if (strcmp(action, "forward") == 0)
  125. return(firing_strength*sum);
  126. /* ========== */
  127. if (strcmp(action, "backward") == 0)
  128. return(index2 != fis->in_n?
  129. fis->order*(firing_strength*para[index2]):sum);
  130. /* ========== */
  131. if (strcmp(action, "parameter") == 0) {
  132. if (fis->order == 1)
  133. return(index2 != fis->in_n?
  134. firing_strength*input[index2]:firing_strength);
  135. else
  136. return(firing_strength);
  137. }
  138. fisError("Unknown action!n");
  139. return(0);      /* for suppressing compiler's warning only */
  140. }
  141. /* layer 5 */
  142. static DOUBLE anfisSummationNode(FIS *fis, int index, char *action, int index2)
  143. {
  144. FAN *p, *fanin = fis->node[index]->fanin;
  145. DOUBLE sum = 0;
  146. for (p = fanin; p != NULL; p = p->next)
  147. sum += fis->node[p->index]->value;
  148. if (strcmp(action, "forward") == 0)
  149. return(sum);
  150. if (strcmp(action, "backward") == 0)
  151. return(1.0);
  152. if (strcmp(action, "parameter") == 0)
  153. return(0.0);
  154. fisError("Unknown action!n");
  155. return(0);      /* for suppressing compiler's warning only */
  156. }
  157. /* layer 6 */
  158. static DOUBLE anfisDivisionNode(FIS *fis, int index, char *action, int index2)
  159. {
  160. DOUBLE total_wf, total_w;
  161. anfisSetupInputArray(fis, index);
  162. total_wf = fis->node[index]->input[0];
  163. total_w = fis->node[index]->input[1];
  164. if (total_w == 0)
  165. fisError("Total of firing strength is zero!n");
  166. if (strcmp(action, "forward") == 0)
  167. return(total_wf/total_w);
  168. if (strcmp(action, "backward") == 0) {
  169. if (index2 == 0)
  170. return(1/total_w);
  171. if (index2 == 1)
  172. return(-total_wf/(total_w*total_w));
  173. fisError("Wrong index2!n");
  174. }
  175. if (strcmp(action, "parameter") == 0)
  176. return(0.0);
  177. fisError("Unknown action!n");
  178. return(0);      /* for suppressing compiler's warning only */
  179. }