⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nodefun.c

📁 模糊逻辑工具箱 模糊逻辑工具箱 模糊逻辑工具箱 模糊逻辑工具箱 模糊逻辑工具箱
💻 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 + -