📄 nodefun.c
字号:
/* Copyright (c) 1994-98 by The MathWorks, Inc. */
/* $Revision: 1.5 $ $Date: 1997/12/01 21:45:50 $ $Author: moler $ */
/* setup the input array of node with index index */
static void
#ifdef __STDC__
anfisSetupInputArray(FIS *fis, int index)
#else
anfisSetupInputArray(fis, index)
FIS *fis;
int index;
#endif
{
FAN *p = fis->node[index]->fanin;
int i;
for (i = 0; i < fis->node[index]->fanin_n; i++, p = p->next)
fis->node[index]->input[i] = fis->node[p->index]->value;
}
/* Node function for each layer */
/* action == "forward" --> return O_{index}
action == "backward" --> return dO_{index}/dO_{index2}
(derivative w.r.t. fan-in nodes)
action == "parameter" --> return dO_{index}/dP_{index2}
(derivative w.r.t. parameters)
*/
/* layer 0 */
static double
#ifdef __STDC__
anfisInputNode(FIS *fis, int index, char *action, int index2)
#else
anfisInputNode(fis, index, action, index2)
FIS *fis;
int index;
char *action;
int index2;
#endif
{
fisError("anfisInputNode should not be called at all!");
return(0); /* for suppressing compiler's warning only */
}
/* layer 1 */
static double
#ifdef __STDC__
anfisMfNode(FIS *fis, int index, char *action, int index2)
#else
anfisMfNode(fis, index, action, index2)
FIS *fis;
int index;
char *action;
int index2;
#endif
{
int which_input = fis->node[index]->fanin->index;
int which_mf = fis->node[index]->ll_index;
double input_value = fis->node[which_input]->value;
double (*mfFcn)() = fis->input[which_input]->mf[which_mf]->mfFcn;
double *para = fis->node[index]->para;
if (strcmp(action, "forward") == 0) {
/* temperary storage for future use */
fis->node[index]->tmp = (*mfFcn)(input_value, para);
return(fis->node[index]->tmp);
}
if (strcmp(action, "backward") == 0)
fisError("MF derivatives w.r.t. inputs should not be called!");
if (strcmp(action, "parameter") == 0) {
/* temperary storage for future use */
return(fisMfDerivative(mfFcn, input_value, para, index2));
}
fisError("Unknown action!\n");
return(0); /* for suppressing compiler's warning only */
}
/* layer 2 */
static double
#ifdef __STDC__
anfisInvNode(FIS *fis, int index, char *action, int index2)
#else
anfisInvNode(fis, index, action, index2)
FIS *fis;
int index;
char *action;
int index2;
#endif
{
int fanin_node_index = fis->node[index]->fanin->index;
double in_mf_value = fis->node[fanin_node_index]->value;
if (strcmp(action, "forward") == 0)
return(1.0 - in_mf_value);
if (strcmp(action, "backward") == 0)
return(-1.0);
if (strcmp(action, "parameter") == 0)
return(0.0);
fisError("Unknown action!\n");
return(0); /* for suppressing compiler's warning only */
}
/* layer 3 */
static double
#ifdef __STDC__
anfisAndOrNode(FIS *fis, int index, char *action, int index2)
#else
anfisAndOrNode(fis, index, action, index2)
FIS *fis;
int index;
char *action;
int index2;
#endif
{
double *input = fis->node[index]->input;
int which_rule = fis->node[index]->l_index;
int and_or = fis->and_or[which_rule];
double (*AndOrFcn)() = and_or == 1? fis->andFcn:fis->orFcn;
int i;
anfisSetupInputArray(fis, index);
if (strcmp(action, "forward") == 0) {
fis->node[index]->tmp =
fisArrayOperation(input, fis->node[index]->fanin_n,
AndOrFcn);
return(fis->node[index]->tmp);
}
if (strcmp(action, "backward") == 0) {
if ((AndOrFcn == fisMin) || (AndOrFcn == fisMax)) {
for (i = 0; i < fis->node[index]->fanin_n; i++)
if (fis->node[index]->tmp == input[i])
break;
return(index2 == i? 1.0:0.0);
}
if (AndOrFcn == fisProduct) {
double product = 1.0;
for (i = 0; i < fis->node[index]->fanin_n; i++) {
if (i == index2)
continue;
product *= input[i];
}
return(product);
}
if (AndOrFcn == fisProbOr) {
double product = 1.0;
for (i = 0; i < fis->node[index]->fanin_n; i++) {
if (i == index2)
continue;
product *= (1 - input[i]);
}
return(product);
}
}
if (strcmp(action, "parameter") == 0)
return(0.0);
fisError("Unknown action!\n");
return(0); /* for suppressing compiler's warning only */
}
/* layer 4 */
static double
#ifdef __STDC__
anfisRuleOutputNode(FIS *fis, int index, char *action, int index2)
#else
anfisRuleOutputNode(fis, index, action, index2)
FIS *fis;
int index;
char *action;
int index2;
#endif
{
double *input;
double firing_strength;
double *para = fis->node[index]->para;
int i;
double sum = 0;
anfisSetupInputArray(fis, index);
input = fis->node[index]->input;
/* ========== */
if (fis->order==1) {
for (i = 0; i < fis->in_n; i++)
sum += input[i]*para[i];
sum += para[fis->in_n];
} else
sum = para[0];
firing_strength = input[fis->in_n];
if (strcmp(action, "forward") == 0)
return(firing_strength*sum);
/* ========== */
if (strcmp(action, "backward") == 0)
return(index2 != fis->in_n?
fis->order*(firing_strength*para[index2]):sum);
/* ========== */
if (strcmp(action, "parameter") == 0) {
if (fis->order == 1)
return(index2 != fis->in_n?
firing_strength*input[index2]:firing_strength);
else
return(firing_strength);
}
fisError("Unknown action!\n");
return(0); /* for suppressing compiler's warning only */
}
/* layer 5 */
static double
#ifdef __STDC__
anfisSummationNode(FIS *fis, int index, char *action, int index2)
#else
anfisSummationNode(fis, index, action, index2)
FIS *fis;
int index;
char *action;
int index2;
#endif
{
FAN *p, *fanin = fis->node[index]->fanin;
double sum = 0;
for (p = fanin; p != NULL; p = p->next)
sum += fis->node[p->index]->value;
if (strcmp(action, "forward") == 0)
return(sum);
if (strcmp(action, "backward") == 0)
return(1.0);
if (strcmp(action, "parameter") == 0)
return(0.0);
fisError("Unknown action!\n");
return(0); /* for suppressing compiler's warning only */
}
/* layer 6 */
static double
#ifdef __STDC__
anfisDivisionNode(FIS *fis, int index, char *action, int index2)
#else
anfisDivisionNode(fis, index, action, index2)
FIS *fis;
int index;
char *action;
int index2;
#endif
{
double total_wf, total_w;
anfisSetupInputArray(fis, index);
total_wf = fis->node[index]->input[0];
total_w = fis->node[index]->input[1];
if (total_w == 0)
fisError("Total of firing strength is zero!\n");
if (strcmp(action, "forward") == 0)
return(total_wf/total_w);
if (strcmp(action, "backward") == 0) {
if (index2 == 0)
return(1/total_w);
if (index2 == 1)
return(-total_wf/(total_w*total_w));
fisError("Wrong index2!\n");
}
if (strcmp(action, "parameter") == 0)
return(0.0);
fisError("Unknown action!\n");
return(0); /* for suppressing compiler's warning only */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -