📄 fis.c
字号:
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 + -