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

📄 fis.c

📁 交流 模糊控制 交流 模糊控制
💻 C
📖 第 1 页 / 共 5 页
字号:
		return(3);
	if (strcmp(mfType, "trapmf") == 0)
		return(4);
	if (strcmp(mfType, "gaussmf") == 0)
		return(2);
	if (strcmp(mfType, "gauss2mf") == 0)
		return(4);
	if (strcmp(mfType, "sigmf") == 0)
		return(2);
	if (strcmp(mfType, "dsigmf") == 0)
		return(4);
	if (strcmp(mfType, "psigmf") == 0)
		return(4);
	if (strcmp(mfType, "gbellmf") == 0)
		return(3);
	if (strcmp(mfType, "smf") == 0)
		return(2);
	if (strcmp(mfType, "zmf") == 0)
		return(2);
	if (strcmp(mfType, "pimf") == 0)
		return(4);
	PRINTF("Given MF type (%s) is unknown.\n", mfType);
	exit(1);
	return(0);	/* get rid of compiler warning */
}
/***********************************************************************
 T-norm and T-conorm operators
 **********************************************************************/
/* Copyright 1994-2002 The MathWorks, Inc.  */
/* $Revision: $  $Date: $  */

static DOUBLE fisMin(DOUBLE x, DOUBLE y)
{return((x) < (y) ? (x) : (y));}

static DOUBLE fisMax(DOUBLE x, DOUBLE y)
{return((x) > (y) ? (x) : (y));}

static DOUBLE fisProduct(DOUBLE x, DOUBLE y)
{return(x*y);} 

static DOUBLE fisProbOr(DOUBLE x, DOUBLE y)
{return(x + y - x*y);} 

static DOUBLE fisSum(DOUBLE x, DOUBLE y)
{return(x + y);} 

/* apply given function to an array */
static DOUBLE fisArrayOperation(DOUBLE *array, int size, DOUBLE (*fcn)())
{
	int i;
	DOUBLE out;

	if (size == 0)
		fisError("Given size is zero!");

	out = array[0];
	for (i = 1; i < size; i++)
		out = (*fcn)(out, array[i]);
	return(out);
}
/* Copyright 1994-2002 The MathWorks, Inc.  */
/* $Revision: $  $Date: $  */

/***********************************************************************
 Defuzzification methods
 **********************************************************************/

/* return the center of area of combined output MF (specified by mf)
   of output m */
/* numofpoints is the number of partition for integration */
static DOUBLE defuzzCentroid(FIS *fis, int m, DOUBLE *mf, int numofpoints)
{
	DOUBLE min = fis->output[m]->bound[0];
	DOUBLE max = fis->output[m]->bound[1];
	DOUBLE step = (max - min)/(numofpoints - 1);
	DOUBLE total_mf = 0;
	DOUBLE sum = 0;
	int i;

	for (i = 0; i < numofpoints; i++){
		total_mf += mf[i];
       		sum += mf[i]*(min + step*i);
	}
	if (total_mf == 0) {
		PRINTF("Total area is zero in defuzzCentroid() for output %d.\n", m+1);
		PRINTF("Average of the range of this output variable is used as the output value.\n\n");
		return((fis->output[m]->bound[0] + fis->output[m]->bound[1])/2);
	} 
	return(sum/total_mf);
}

/* return the bisector of area of mf */
static DOUBLE defuzzBisector(FIS *fis, int m, DOUBLE *mf, int numofpoints)
{
	DOUBLE min = fis->output[m]->bound[0];
	DOUBLE max = fis->output[m]->bound[1];
	DOUBLE step = (max - min)/(numofpoints - 1); 
	DOUBLE area, sub_area;
	int i;

	/* find the total area */
	area = 0;
	for (i = 0; i < numofpoints; i++)
		area += mf[i];

	if (area == 0) {
		PRINTF("Total area is zero in defuzzBisector() for output %d.\n", m+1);
		PRINTF("Average of the range of this output variable is used as the output value.\n");
		return((fis->output[m]->bound[0] + fis->output[m]->bound[1])/2);
	} 
     
	sub_area = 0;
	for (i = 0; i < numofpoints; i++) {
		sub_area += mf[i];
		if (sub_area >= area/2)
			break;
	}
	return(min + step*i);
}

/* Returns the mean of maximizing x of mf */
static DOUBLE defuzzMeanOfMax(FIS *fis, int m, DOUBLE *mf, int numofpoints)
{
	DOUBLE min = fis->output[m]->bound[0];
	DOUBLE max = fis->output[m]->bound[1];
	DOUBLE step = (max - min)/(numofpoints - 1); 
	DOUBLE mf_max;
	DOUBLE sum;
	int count;
	int i;

	mf_max = fisArrayOperation(mf, numofpoints, fisMax);

	sum = 0;
	count = 0;
	for (i = 0; i < numofpoints; i++)
		if (mf[i] == mf_max) {
			count++;
			sum += i;
		}
	return(min+step*sum/count);
}

/* Returns the smallest (in magnitude) maximizing x of mf */
static DOUBLE defuzzSmallestOfMax(FIS *fis, int m, DOUBLE *mf, int numofpoints)
{
	DOUBLE min = fis->output[m]->bound[0];
	DOUBLE max = fis->output[m]->bound[1];
	DOUBLE step = (max - min)/(numofpoints - 1); 
	DOUBLE mf_max;
	int i, min_index = 0;
	DOUBLE min_distance = pow(2.0, 31.0)-1;
	DOUBLE distance; /* distance to the origin */

	mf_max = fisArrayOperation(mf, numofpoints, fisMax);
	for (i = 0; i < numofpoints; i++)
		if (mf[i] == mf_max) {
			distance = ABS(min + step*i);
			if (min_distance > distance) {
				min_distance = distance;
				min_index = i;
			}
		}
	return(min + step*min_index);
}

/* Returns the largest (in magnitude) maximizing x of mf */
static DOUBLE defuzzLargestOfMax(FIS *fis, int m, DOUBLE *mf, int numofpoints)
{
	DOUBLE min = fis->output[m]->bound[0];
	DOUBLE max = fis->output[m]->bound[1];
	DOUBLE step = (max - min)/(numofpoints - 1); 
	DOUBLE mf_max;
	int i, max_index = 0;
	DOUBLE max_distance = -(pow(2.0, 31.0)-1);
	DOUBLE distance; /* distance to the origin */

	mf_max = fisArrayOperation(mf, numofpoints, fisMax);
	for (i = 0; i < numofpoints; i++)
		if (mf[i] == mf_max) {
			distance = ABS(min + step*i);
			if (max_distance < distance) {
				max_distance = distance;
				max_index = i;
			}
		}
	return(min + step*max_index);
}
/***********************************************************************
 Data structure: construction, printing, and destruction 
 **********************************************************************/
/* Copyright 1994-2002 The MathWorks, Inc.  */
/* $Revision: $  $Date: $  */

IO *fisBuildIoList(int node_n, int *mf_n)
{
	IO *io_list;
	int i, j;

	io_list = (IO *)fisCalloc(node_n, sizeof(IO));
	for (i = 0; i < node_n; i++) {
		io_list[i].mf_n = mf_n[i];
		io_list[i].mf = (MF **)fisCalloc(mf_n[i], sizeof(MF *));
		if (mf_n[i] > 0)	/* check if no MF at all */
			io_list[i].mf[0] = (MF *)fisCalloc(mf_n[i], sizeof(MF));
		for (j = 0; j < mf_n[i]; j++)
			io_list[i].mf[j] = io_list[i].mf[0] + j;
	}
	return(io_list);
}

/* Assign a MF pointer to each MF node based on the MF node's type */
void fisAssignMfPointer(FIS *fis)
{
	int i, j, k, mfTypeN = 13, found;
	MF *mf_node;
	struct command {
		char *mfType;
        DOUBLE (*mfFcn)(DOUBLE, DOUBLE *);
	} dispatch[] = {
		{ "trimf",	fisTriangleMf },
		{ "trapmf",	fisTrapezoidMf },
		{ "gaussmf",	fisGaussianMf },
		{ "gauss2mf",	fisGaussian2Mf },
		{ "sigmf",	fisSigmoidMf },
		{ "dsigmf",	fisDifferenceSigmoidMf },
		{ "psigmf",	fisProductSigmoidMf },
		{ "gbellmf",	fisGeneralizedBellMf },
		{ "smf",	fisSMf },
		{ "zmf",	fisZMf },
		{ "pimf",	fisPiMf },
		{ "linear",	NULL },
		{ "constant",	NULL }
	};

	/* input MF's */
	for (i = 0; i < fis->in_n; i++)
		for (j = 0; j < fis->input[i]->mf_n; j++) {
			mf_node = fis->input[i]->mf[j];
			found = 0;
			for (k = 0; k < mfTypeN-2; k++) {
				if (strcmp(mf_node->type, dispatch[k].mfType) == 0) {
					mf_node->mfFcn = dispatch[k].mfFcn;
					found = 1;
					break;
				}
			}
			if (found == 0) {
#ifdef MATLAB_MEX_FILE
			{
				DOUBLE function_type;
				function_type = fisCallMatlabExist(mf_node->type);
				if (function_type == 0) {
					PRINTF("MF '%s' does not exist!\n", mf_node->type);
					fisError("Exiting ...");
				}
				if (function_type == 1) {
					PRINTF("MF '%s' is a MATLAB variable!\n", mf_node->type);
					fisError("Exiting ...");
				}
				mf_node->userDefined = 1;
			}
#else
				PRINTF("MF type '%s' for input %d is unknown.\n",
					mf_node->type, i+1);
				PRINTF("Legal input MF types: ");
				for (i = 0; i < mfTypeN-2; i++)
					PRINTF("%s ", dispatch[i].mfType);
				fisError("\n");
#endif
			}
		}

	/* output MF's */
	for (i = 0; i < fis->out_n; i++)
		for (j = 0; j < fis->output[i]->mf_n; j++) {
			mf_node = fis->output[i]->mf[j];
			found = 0;
			for (k = 0; k < mfTypeN; k++) {
				if (strcmp(mf_node->type, dispatch[k].mfType) == 0) {
					mf_node->mfFcn = dispatch[k].mfFcn;
					found = 1;
					break;
				}
			}
			if (found == 0) {
#ifdef MATLAB_MEX_FILE
			{
				DOUBLE function_type;
				function_type = fisCallMatlabExist(mf_node->type);
				if (function_type == 0) {
					PRINTF("MATLAB function '%s' does not exist!\n", mf_node->type);
					fisError("Exiting ...");
				}
				if (function_type == 1) {
					PRINTF("'%s' is a MATLAB variable!\n", mf_node->type);
					fisError("Exiting ...");
				}
				mf_node->userDefined = 1;
			}
#else
				PRINTF("MF type '%s' for output %d is unknown.\n",
					mf_node->type, i+1);
				PRINTF("Legal output MF types: ");
				for (i = 0; i < mfTypeN-1; i++)
					PRINTF("%s ", dispatch[i].mfType);
				fisError("\n");
#endif
			}
		}
}

/* Assign a other function pointers */
void fisAssignFunctionPointer(FIS *fis)
{
	/* assign andMethod function pointer */
	if (strcmp(fis->andMethod, "prod") == 0)
		fis->andFcn = fisProduct;
	else if (strcmp(fis->andMethod, "min") == 0)
		fis->andFcn = fisMin;
	else {
#ifdef MATLAB_MEX_FILE
	{
		DOUBLE function_type;
		function_type = fisCallMatlabExist(fis->andMethod);
		if (function_type == 0) {
			PRINTF("AND function '%s' does not exist!\n", fis->andMethod);
			fisError("Exiting ...");
		}
		if (function_type == 1) {
			PRINTF("AND function '%s' is a MATLAB variable!\n", fis->andMethod);
			fisError("Exiting ...");
		}
		fis->userDefinedAnd = 1;
	}
#else
		PRINTF("Given andMethod %s is unknown.\n", fis->andMethod);
		fisError("Legal andMethod: min, prod");
#endif
	}

	/* assign orMethod function pointer */
	if (strcmp(fis->orMethod, "probor") == 0)
		fis->orFcn = fisProbOr;
	else if (strcmp(fis->orMethod, "max") == 0)
		fis->orFcn = fisMax;
	else {
#ifdef MATLAB_MEX_FILE
	{
		DOUBLE function_type;
		function_type = fisCallMatlabExist(fis->orMethod);
		if (function_type == 0) {
			PRINTF("OR function '%s' does not exist!\n", fis->orMethod);
			fisError("Exiting ...");
		}
		if (function_type == 1) {
			PRINTF("OR function '%s' is a MATLAB variable!\n", fis->orMethod);
			fisError("Exiting ...");
		}
		fis->userDefinedOr = 1;
	}
#else
		PRINTF("Given orMethod %s is unknown.\n", fis->orMethod);
		fisError("Legal orMethod: max, probor");
#endif
	}

	/* assign impMethod function pointer */
	if (strcmp(fis->impMethod, "prod") == 0)
		fis->impFcn = fisProduct;
	else if (strcmp(fis->impMethod, "min") == 0)
		fis->impFcn = fisMin;
	else {
#ifdef MATLAB_MEX_FILE
	{
		DOUBLE function_type;
		function_type = fisCallMatlabExist(fis->impMethod);
		if (function_type == 0) {
			PRINTF("IMPLICATION function '%s' does not exist!\n", fis->impMethod);
			fisError("Exiting ...");
		}
		if (function_type == 1) {
			PRINTF("IMPLICATION function '%s' is a MATLAB variable!\n", fis->impMethod);
			fisError("Exiting ...");
		}
		fis->userDefinedImp = 1;
	}
#else
		PRINTF("Given impMethod %s is unknown.\n", fis->impMethod);
		fisError("Legal impMethod: min, prod");
#endif
	}

	/* assign aggMethod function pointer */
	if (strcmp(fis->aggMethod, "max") == 0)
		fis->aggFcn = fisMax;
	else if (strcmp(fis->aggMethod, "probor") == 0)
		fis->aggFcn = fisProbOr;
	else if (strcmp(fis->aggMethod, "sum") == 0)
		fis->aggFcn = fisSum;
	else {
#ifdef MATLAB_MEX_FILE
	{
		DOUBLE function_type;
		function_type = fisCallMatlabExist(fis->aggMethod);
		if (function_type == 0) {
			PRINTF("AGGREGATE function '%s' does not exist!\n", fis->aggMethod);
			fisError("Exiting ...");
		}
		if (function_type == 1) {
			PRINTF("AGGREGATE function '%s' is a MATLAB variable!\n", fis->aggMethod);
			fisError("Exiting ...");
		}
		fis->userDefinedAgg = 1;
	}
#else
		PRINTF("Given aggMethod %s is unknown.\n", fis->aggMethod);
		fisError("Legal aggMethod: max, probor, sum");
#endif
	}

	/* assign defuzzification function pointer */
	if (strcmp(fis->defuzzMethod, "centroid") == 0)
		fis->defuzzFcn = defuzzCentroid;
	else if (strcmp(fis->defuzzMethod, "bisector") == 0)
		fis->defuzzFcn = defuzzBisector;
	else if (strcmp(fis->defuzzMethod, "mom") == 0)
		fis->defuzzFcn = defuzzMeanOfMax;
	else if (strcmp(fis->defuzzMethod, "som") == 0)
		fis->defuzzFcn = defuzzSmallestOfMax;
	else if (strcmp(fis->defuzzMethod, "lom") == 0)
		fis->defuzzFcn = defuzzLargestOfMax;
	else if (strcmp(fis->defuzzMethod, "wtaver") == 0)
		;
	else if (strcmp(fis->defuzzMethod, "wtsum") == 0)
		;
	else {
#ifdef MATLAB_MEX_FILE
	{
		DOUBLE function_type;
		function_type = fisCallMatlabExist(fis->defuzzMethod);
		if (function_type == 0) {
			PRINTF("DEFUZZIFICATION function '%s' does not exist!\n", fis->defuzzMethod);
			fisError("Exiting ...");
		}
		if (function_type == 1) {
			PRINTF("DEFUZZIFICATION function '%s' is a MATLAB variable!\n", fis->defuzzMethod);
			fisError("Exiting ...");
		}
		fis->userDefinedDefuzz = 1;
	}
#else
		PRINTF("Given defuzzification method %s is unknown.\n", fis->defuzzMethod);
		fisError("Legal defuzzification methods: centroid, bisector, mom, som, lom, wtaver, wtsum");
#endif
	}
}

#ifndef NO_PRINTF
static void fisPrintData(FIS *fis)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -