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

📄 fis.c

📁 模糊逻辑工具箱 模糊逻辑工具箱 模糊逻辑工具箱 模糊逻辑工具箱 模糊逻辑工具箱
💻 C
📖 第 1 页 / 共 5 页
字号:

	if (a >= b)
		return(x <= (a+b)/2);

	if (x <= a)
		out = 1;
	else if (x <= (a + b)/2)
		out = 1 - 2*pow((x-a)/(b-a), 2.0);
	else if (x <= b)
		out = 2*pow((b-x)/(b-a), 2.0);
	else
		out = 0;
	return(out);
}

/* pi membership function */
static double
#ifdef __STDC__
fisPiMf(double x, double *para)
#else
fisPiMf(x, para)
double x, *para;
#endif
{
	return(fisSMf(x, para)*fisZMf(x, para+2));
}

/* all membership function */
static double
#ifdef __STDC__
fisAllMf(double x, double *para)
#else
fisAllMf(x, para)
double x, *para;
#endif
{
	return(1);
}

/* returns the number of parameters of MF */
static int
#ifdef __STDC__
fisGetMfParaN(char *mfType)
#else
fisGetMfParaN(mfType)
char *mfType;
#endif
{
	if (strcmp(mfType, "trimf") == 0)
		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
 **********************************************************************/

static double
#ifdef __STDC__
fisMin(double x, double y)
#else
fisMin(x, y)
double x, y;
#endif
{return((x) < (y) ? (x) : (y));}

static double
#ifdef __STDC__
fisMax(double x, double y)
#else
fisMax(x, y)
double x, y;
#endif
{return((x) > (y) ? (x) : (y));}

static double
#ifdef __STDC__
fisProduct(double x, double y)
#else
fisProduct(x, y)
double x, y;
#endif
{return(x*y);} 

static double
#ifdef __STDC__
fisProbOr(double x, double y)
#else
fisProbOr(x, y)
double x, y;
#endif
{return(x + y - x*y);} 

static double
#ifdef __STDC__
fisSum(double x, double y)
#else
fisSum(x, y)
double x, y;
#endif
{return(x + y);} 

/* apply given function to an array */
static double
#ifdef __STDC__
fisArrayOperation(double *array, int size, double (*fcn)())
#else
fisArrayOperation(array, size, fcn)
double *array;
int size;
double (*fcn)();
#endif
{
	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);
}
/***********************************************************************
 Defuzzification methods
 **********************************************************************/

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

	for (i = 0; i < MF_POINT_N; 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 
#ifdef __STDC__
defuzzBisector(FIS *fis, int m, double *mf)
#else
defuzzBisector(fis, m, mf)
FIS *fis;
int m;
double *mf;
#endif
{
	double min = fis->output[m]->bound[0];
	double max = fis->output[m]->bound[1];
	double step = (max - min)/(MF_POINT_N - 1); 
	double area, sub_area;
	int i;

	/* find the total area */
	area = 0;
	for (i = 0; i < MF_POINT_N; 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 < MF_POINT_N; 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 
#ifdef __STDC__
defuzzMeanOfMax(FIS *fis, int m, double *mf)
#else
defuzzMeanOfMax(fis, m, mf)
FIS *fis;
int m;
double *mf;
#endif
{
	double min = fis->output[m]->bound[0];
	double max = fis->output[m]->bound[1];
	double step = (max - min)/(MF_POINT_N - 1); 
	double mf_max;
	double sum;
	int count;
	int i;

	mf_max = fisArrayOperation(mf, MF_POINT_N, fisMax);

	sum = 0;
	count = 0;
	for (i = 0; i < MF_POINT_N; 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 
#ifdef __STDC__
defuzzSmallestOfMax(FIS *fis, int m, double *mf)
#else
defuzzSmallestOfMax(fis, m, mf)
FIS *fis;
int m;
double *mf;
#endif
{
	double min = fis->output[m]->bound[0];
	double max = fis->output[m]->bound[1];
	double step = (max - min)/(MF_POINT_N - 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, MF_POINT_N, fisMax);
	for (i = 0; i < MF_POINT_N; 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 
#ifdef __STDC__
defuzzLargestOfMax(FIS *fis, int m, double *mf)
#else
defuzzLargestOfMax(fis, m, mf)
FIS *fis;
int m;
double *mf;
#endif
{
	double min = fis->output[m]->bound[0];
	double max = fis->output[m]->bound[1];
	double step = (max - min)/(MF_POINT_N - 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, MF_POINT_N, fisMax);
	for (i = 0; i < MF_POINT_N; 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 
 **********************************************************************/

static IO *
#ifdef __STDC__
fisBuildIoList(int node_n, int *mf_n)
#else
fisBuildIoList(node_n, mf_n)
int node_n;
int *mf_n;
#endif
{
	IO *io_list;
	int i, j;

	io_list = (IO *)calloc(node_n, sizeof(MF));
	for (i = 0; i < node_n; i++) {
		io_list[i].mf_n = mf_n[i];
		io_list[i].mf = (MF **)calloc(mf_n[i], sizeof(MF *));
		if (mf_n[i] > 0)	/* check if no MF at all */
			io_list[i].mf[0] = (MF *)calloc(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 */
static void
#ifdef __STDC__
fisAssignMfPointer(FIS *fis)
#else
fisAssignMfPointer(fis)
FIS *fis;
#endif
{
	int i, j, k, mfTypeN = 13, found;
	MF *mf_node;
#ifdef __STDC__
	struct command {
		char *mfType;
		double (*mfFcn)();
	} 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 }
	};
#else
	struct command {
		char mfType[20];
		double (*mfFcn)();
	} dispatch[20];
	
	strcpy(dispatch[0].mfType, "trimf");
	dispatch[0].mfFcn = fisTriangleMf;
	strcpy(dispatch[1].mfType, "trapmf");
	dispatch[1].mfFcn = fisTrapezoidMf;
	strcpy(dispatch[2].mfType, "gaussmf");
	dispatch[2].mfFcn = fisGaussianMf;
	strcpy(dispatch[3].mfType, "gauss2mf");
	dispatch[3].mfFcn = fisGaussian2Mf;
	strcpy(dispatch[4].mfType, "sigmf");
	dispatch[4].mfFcn = fisSigmoidMf;
	strcpy(dispatch[5].mfType, "dsigmf");
	dispatch[5].mfFcn = fisDifferenceSigmoidMf;
	strcpy(dispatch[6].mfType, "psigmf");
	dispatch[6].mfFcn = fisProductSigmoidMf;
	strcpy(dispatch[7].mfType, "gbellmf");
	dispatch[7].mfFcn = fisGeneralizedBellMf;
	strcpy(dispatch[8].mfType, "smf");
	dispatch[8].mfFcn = fisSMf;
	strcpy(dispatch[9].mfType, "zmf");
	dispatch[9].mfFcn = fisZMf;
	strcpy(dispatch[10].mfType, "pimf");
	dispatch[10].mfFcn = fisPiMf;
	strcpy(dispatch[11].mfType, "linear");
	dispatch[11].mfFcn = NULL;
	strcpy(dispatch[12].mfType, "constant");
	dispatch[12].mfFcn = NULL;
#endif

	/* 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);
				/*
				printf("\n\nIf '%s' is a customized MF, use M-file command FISEVAL1 or FISEVAL2 instead.\n", mf_node->type);
				*/
				printf("\n");
				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);
				/*
				printf("\n\nIf '%s' is a customized MF, use M-file command FISEVAL1 or FISEVAL2 instead.\n", mf_node->type);
				*/
				printf("\n");
				fisError("\n");
#endif
			}
		}
}

/* Assign a other function pointers */
static void
#ifdef __STDC__
fisAssignFunctionPointer(FIS *fis)
#else
fisAssignFunctionPointer(fis)
FIS *fis;
#endif
{
	/* 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 ...");

⌨️ 快捷键说明

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