📄 fis.c
字号:
else if (x <= (a + b)/2)
out = 2*pow((x-a)/(b-a), 2.0);
else if (x <= b)
out = 1-2*pow((b-x)/(b-a), 2.0);
else
out = 1;
return(out);
}
/* Z membership function */
static double
#ifdef __STDC__
fisZMf(double x, double *para)
#else
fisZMf(x, para)
double x, *para;
#endif
{
double a = para[0], b = para[1];
double out;
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);
#ifndef NO_PRINTF
printf("Given MF type (%s) is unknown.\n", mfType);
#endif
exit(1);
return(0); /* get rid of compiler warning */
}
/***********************************************************************
T-norm and T-conorm operators
**********************************************************************/
/* Copyright (c) 1994-98 by The MathWorks, Inc. */
/* $Revision: $ $Date: $ */
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);
}
/* Copyright (c) 1994-98 by 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
#ifdef __STDC__
defuzzCentroid(FIS *fis, int m, double *mf, int numofpoints)
#else
defuzzCentroid(fis, m, mf)
FIS *fis;
int m;
double *mf;
int numofpoints;
#endif
{
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) {
#ifndef NO_PRINTF
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");
#endif
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, int numofpoints)
#else
defuzzBisector(fis, m, mf)
FIS *fis;
int m;
double *mf;
int numofpoints;
#endif
{
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) {
#ifndef NO_PRINTF
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");
#endif
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
#ifdef __STDC__
defuzzMeanOfMax(FIS *fis, int m, double *mf, int numofpoints)
#else
defuzzMeanOfMax(fis, m, mf)
FIS *fis;
int m;
double *mf;
int numofpoints;
#endif
{
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
#ifdef __STDC__
defuzzSmallestOfMax(FIS *fis, int m, double *mf, int numofpoints)
#else
defuzzSmallestOfMax(fis, m, mf)
FIS *fis;
int m;
double *mf;
int numofpoints;
#endif
{
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
#ifdef __STDC__
defuzzLargestOfMax(FIS *fis, int m, double *mf, int numofpoints)
#else
defuzzLargestOfMax(fis, m, mf)
FIS *fis;
int m;
double *mf;
int numofpoints;
#endif
{
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 (c) 1994-98 by The MathWorks, Inc. */
/* $Revision: $ $Date: $ */
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 */
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
#ifndef NO_PRINTF
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");
#endif
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
#ifndef NO_PRINTF
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");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -