📄 fis.c
字号:
fis->firing_strength[i] =
fis->rule_weight[i]*fis->firing_strength[i];
}
#ifdef MATLAB_MEX_FILE
/* Returns the n-th value of combined m-th output MF. */
/* (n is the index into the MF value arrays of the m-th output.) */
/* Both m and n are zero-offset */
/* (for Mamdani's model only */
/* This is used in mexFunction() of evalfis.c only */
static double
#ifdef __STDC__
fisFinalOutputMf(FIS *fis, int m, int n)
#else
fisFinalOutputMf(fis, m, n)
FIS *fis;
int m;
int n;
#endif
{
int i, which_mf;
double mf_value, out;
/* The following should not be based on t-conorm */
for (i = 0; i < fis->rule_n; i++) {
/* rule_list is 1-offset */
which_mf = fis->rule_list[i][fis->in_n+m];
if (which_mf > 0)
mf_value = fis->output[m]->mf[which_mf-1]->value_array[n];
else if (which_mf == 0) /* Don't care */
mf_value = 0;
else
mf_value = 1-fis->output[m]->mf[-which_mf-1]->value_array[n];
if (!fis->userDefinedImp)
fis->rule_output[i] = (*fis->impFcn)(mf_value,
fis->firing_strength[i]);
else {
double tmp[2];
tmp[0] = mf_value;
tmp[1] = fis->firing_strength[i];
fis->rule_output[i] = fisCallMatlabFcn(tmp, 2, fis->impMethod);
}
}
if (!fis->userDefinedAgg)
out = fisArrayOperation(fis->rule_output, fis->rule_n, fis->aggFcn);
else
out = fisCallMatlabFcn(fis->rule_output, fis->rule_n, fis->aggMethod);
return(out);
}
#endif
/* Returns the aggregated MF aggMF of the m-th output variable . */
/* (for Mamdani's model only */
static void
#ifdef __STDC__
fisFinalOutputMf2(FIS *fis, int m, double *aggMF, int numofpoints)
#else
fisFinalOutputMf2(fis, m, aggMF)
FIS *fis;
int m;
double *aggMF;
int numofpoints;
#endif
{
int i, j, which_mf;
/* fill in BigOutMfMatrix */
/* The following should not be based on t-conorm */
for (i = 0; i < fis->rule_n; i++) {
which_mf = fis->rule_list[i][fis->in_n+m];
if (which_mf > 0)
for (j = 0; j < numofpoints; j++)
/*
fis->BigOutMfMatrix[i][j] =
fis->output[m]->mf[which_mf-1]->value_array[j];
*/
fis->BigOutMfMatrix[j*fis->rule_n+i] =
fis->output[m]->mf[which_mf-1]->value_array[j];
else if (which_mf < 0)
for (j = 0; j < numofpoints; j++)
/*
fis->BigOutMfMatrix[i][j] =
1-fis->output[m]->mf[-which_mf-1]->value_array[j];
*/
fis->BigOutMfMatrix[j*fis->rule_n+i] =
1 - fis->output[m]->mf[-which_mf-1]->value_array[j];
else /* which_mf == 0 */
for (j = 0; j < numofpoints; j++)
fis->BigOutMfMatrix[j*fis->rule_n+i] = 0;
}
/* fill in BigWeightMatrix */
for (i = 0; i < fis->rule_n; i++)
for (j = 0; j < numofpoints; j++)
fis->BigWeightMatrix[j*fis->rule_n+i] =
fis->firing_strength[i];
/* apply implication operator */
if (!fis->userDefinedImp)
for (i = 0; i < (fis->rule_n)*numofpoints; i++)
fis->BigOutMfMatrix[i] = (*fis->impFcn)(
fis->BigWeightMatrix[i], fis->BigOutMfMatrix[i]);
else {
#ifdef MATLAB_MEX_FILE
fisCallMatlabFcn2(fis->BigWeightMatrix, fis->BigOutMfMatrix,
fis->rule_n, numofpoints, fis->impMethod, fis->BigOutMfMatrix);
#else
#ifndef NO_PRINTF
printf("Given IMP method %s is unknown.\n", fis->impMethod);
#endif
fisError("Exiting ...");
#endif
}
/* apply MATLAB aggregate operator */
if (!fis->userDefinedAgg)
for (i = 0; i < numofpoints; i++)
aggMF[i] = fisArrayOperation(
fis->BigOutMfMatrix+i*fis->rule_n,
fis->rule_n, fis->aggFcn);
else {
#ifdef MATLAB_MEX_FILE
fisCallMatlabFcn1(fis->BigOutMfMatrix, fis->rule_n,
numofpoints, fis->aggMethod, aggMF);
#else
#ifndef NO_PRINTF
printf("Given AGG method %s is unknown.\n", fis->aggMethod);
#endif
fisError("Exiting ...");
#endif
}
}
/***********************************************************************
Evaluate the constructed FIS based on given input vector
**********************************************************************/
/* compute outputs and put them into output nodes */
void
#ifdef __STDC__
fisEvaluate(FIS *fis, int numofpoints)
#else
fisEvaluate(fis)
FIS *fis;
int numofpoints
#endif
{
double out = 0;
double total_w, total_wf;
int i, j, k, which_mf;
if (fis == NULL) {
#ifndef NO_PRINTF
printf("FIS data structure has not been built yet.\n");
#endif
fisError("Exiting ...");
}
fisComputeInputMfValue(fis);
fisComputeFiringStrength(fis);
total_w = fisArrayOperation(fis->firing_strength, fis->rule_n, fisSum);
if (total_w == 0) {
#ifndef NO_PRINTF
printf("Warning: no rule is fired for input [");
for (i = 0; i < fis->in_n; i++)
printf("%f ", fis->input[i]->value);
printf("]!\n");
printf("Average of the range of each output variable is used as default output.\n\n");
#endif
for (i = 0; i < fis->out_n; i++)
fis->output[i]->value = (fis->output[i]->bound[0] +
fis->output[i]->bound[1])/2;
return;
}
if (strcmp(fis->type, "sugeno") == 0) {
fisComputeTskRuleOutput(fis);
/* Find each rule's output */
for (i = 0; i < fis->out_n; i++) {
for (j = 0; j < fis->rule_n; j++) {
which_mf = fis->rule_list[j][fis->in_n + i] - 1;
if (which_mf == -1) /* don't_care consequent */
fis->rule_output[j] = 0;
else
fis->rule_output[j] = fis->output[i]->mf[which_mf]->value;
}
/* Weighted average to find the overall output*/
total_wf = 0;
for (k = 0; k < fis->rule_n; k++)
total_wf += (fis->firing_strength[k]*
fis->rule_output[k]);
if (strcmp(fis->defuzzMethod, "wtaver") == 0)
fis->output[i]->value = total_wf/total_w;
else if (strcmp(fis->defuzzMethod, "wtsum") == 0)
fis->output[i]->value = total_wf;
else {
#ifndef NO_PRINTF
printf("Unknown method (%s) for Sugeno model!", fis->defuzzMethod);
#endif
fisError("Legal methods: wtaver, wtsum");
}
}
}
else if (strcmp(fis->type, "mamdani") == 0)
for (i = 0; i < fis->out_n; i++) {
/* double aggMF[MF_POINT_N];
double X[MF_POINT_N];*/
double *aggMF;
double *X;
double min = fis->output[i]->bound[0];
double max = fis->output[i]->bound[1];
double step = (max - min)/(numofpoints - 1);
X = (double *)calloc(numofpoints, sizeof(double));
aggMF = (double *)calloc(numofpoints, sizeof(double));
for (j = 0; j < numofpoints; j++)
X[j] = min + step*j;
/* fill in aggMF */
fisFinalOutputMf2(fis, i, aggMF, numofpoints);
/* defuzzification */
if (!fis->userDefinedDefuzz)
out = (*fis->defuzzFcn)(fis, i, aggMF, numofpoints);
else { /* user defined defuzzification */
#ifdef MATLAB_MEX_FILE
out = fisCallMatlabDefuzz(X, aggMF,
numofpoints, fis->defuzzMethod);
#else
#ifndef NO_PRINTF
printf("Given defuzzification method %s is unknown.\n", fis->defuzzMethod);
#endif
fisError("Exiting ...");
#endif
}
fis->output[i]->value = out;
free(X);
free(aggMF);
}
else {
#ifndef NO_PRINTF
printf("Given FIS %s is unknown.\n", fis->name);
#endif
fisError("Exiting ...");
}
}
/* given input vector and FIS data structure, return output */
/* this is a wrap-up on fisEvaluate () */
/* used in fismain() only */
static void
#ifdef __STDC__
getFisOutput(double *input, FIS *fis, double *output)
#else
getFisOutput(input, fis, output)
double *input;
FIS *fis;
double *output;
#endif
{
int i;
/* dispatch input */
for (i = 0; i < fis->in_n; i++)
fis->input[i]->value = input[i];
/* evaluate FIS */
fisEvaluate(fis, 101);
/* dispatch output */
for (i = 0; i < fis->out_n; i++)
output[i] = fis->output[i]->value;
}
/* Copyright (c) 1994-98 by The MathWorks, Inc. */
/* $Revision: $ $Date: $ */
/* return the next valid line without comments */
static char *
#ifdef __STDC__
getNextLine(char *buf, FILE *fp)
#else
getNextLine(buf, fp)
char *buf;
FILE *fp;
#endif
{
char *returned_value;
int i, j;
returned_value = fgets(buf, STR_LEN, fp);
if (NULL == returned_value)
return(NULL);
/* skip if it starts with '%' or '\n' */
if (buf[0] == '%' || buf[0] == '\n')
return(getNextLine(buf, fp));
/* get rid of trailing comment or new line */
for (i = 0; buf[i]!='%' && buf[i]!='\n' && i < STR_LEN; i++);
/*
printf("%s\n", buf);
printf("i = %d\n", i);
*/
for (j = i; j < STR_LEN; j++)
buf[j] = 0;
return(returned_value);
}
/* find number x in "******=x" */
static double
#ifdef __STDC__
getNumber(char *buf, FILE *fp)
#else
getNumber(buf, fp)
char *buf;
FILE *fp;
#endif
{
int tmp;
char string[STR_LEN];
double num;
if (getNextLine(buf, fp) == NULL)
fisError("getNumber: Incomplete FIS file!");
tmp = sscanf(buf, " %[^=] = %lf ", string, &num);
if (tmp != 2) {
printf("Error format in FIS file when parsing\n");
printf("\"%s\"\n", buf);
fisError("Error in getNumber().");
}
/*
printf("getNumber --> %s%lf\n", string, num);
printf("getNumber --> %lf\n", num);
*/
return(num);
}
/* find string x in "*******='x'" */
static void
#ifdef __STDC__
getString(char *buf, FILE *fp, double *array)
#else
getString(buf, fp, array)
char *buf;
FILE *fp;
double *array;
#endif
{
int i;
char string1[STR_LEN];
char string2[STR_LEN];
int tmp;
if (getNextLine(buf, fp) == NULL)
fisError("getString: Incomplete FIS file!");
tmp = sscanf(buf, " %[^'] '%[^']' ", string1, string2);
if (tmp != 2) {
printf("Error format in FIS file when parsing\n");
printf("\"%s\"\n", buf);
fisError("Error in getString().");
}
/* copy it to output array */
for (i = 0; i < (int)strlen(string2); i++)
array[i] = string2[i];
/*
printf("getString --> %s\n", string2);
*/
}
/* put a string "a b c" to an array [a b c]*/
/* return number of elements */
static int
#ifdef __STDC__
getArray(char *string, double *array)
#else
getArray(string, array)
char *string;
double *array;
#endif
{
int i;
int start, end, index;
char tmp[STR_LEN];
start = 0; /* start of a number */
end = 0; /* end of a number */
index = 0; /* index of array */
while (start <= (int)strlen(string)-1) {
/* find end */
for (end = start; end < (int)strlen(string); end++)
if (string[end] == ' ')
break;
for (i = start; i <= end; i++)
tmp[i-start] = string[i];
tmp[i-start] = 0;
array[index++] = atof(tmp);
/* find new start */
for (start = end; start < (int)strlen(string); start++)
if (string[start] != ' ')
break;
}
/*
printf("%s\n", string);
fisPrintArray(array, 8);
*/
return(index);
}
static void
#ifdef __STDC__
getMfN(char *filename, int in_n, double *in_mf_n, int out_n, double *out_mf_n)
#else
getMfN(filename, in_n, in_mf_n, out_n, out_mf_n)
char *filename;
int in_n;
double *in_mf_n;
int out_n;
double *out_mf_n;
#endif
{
int i, tmp;
char buf[STR_LEN];
FILE *fp = fisOpenFile(filename, "r");
for (i = 0; i < in_n+out_n; i++) {
while (1) {
if (getNextLine(buf, fp) == NULL)
fisError("Not enough NumMFs in FIS file!");
if (sscanf(buf, " NumMFs = %d ", &tmp) == 1)
break;
}
if (i < in_n)
in_mf_n[i] = tmp;
else
out_mf_n[i-in_n] = tmp;
}
fclose(fp);
/*
fisPrintArray(in_mf_n, in_n);
fisPrintArray(out_mf_n, out_n);
*/
}
/* return an empty FIS matrix with right size */
static double **
#ifdef __STDC__
returnEmptyFismatrix(char *filename, int *row_n_p, int *col_n_p)
#else
returnEmptyFismatrix(filename, row_n_p, col_n_p)
char *filename;
int *row_n_p;
int *col_n_p;
#endif
{
int in_n, out_n, rule_n, total_in_mf_n, total_out_mf_n;
int row_n, col_n;
char buf[STR_LEN], fisType[STR_LEN];
char fisName[STR_LEN], IoName[STR_LEN];
char tmp1[STR_LEN], tmp2[STR_LEN], tmp3[STR_LEN], tmp4[STR_LEN];
FILE *fp;
double *in_mf_n;
double *out_mf_n;
double **fismatrix;
/* find the row_n */
fp = fisOpenFile(filename, "r");
/* find in_n */
while (1) {
if (getNextLine(buf, fp) == NULL)
fisError("Cannot find NumInputs in FIS file!");
if (sscanf(buf, " NumInputs = %d ", &in_n) == 1)
break;
}
/* find out_n */
while (1) {
if (getNextLine(buf, fp) == NULL)
fisError("Cannot find NumOutputs in FIS file!");
if (sscanf(buf, " NumOutputs = %d ", &out_n) == 1)
break;
}
/* find rule_n */
while (1) {
if (getNextLine(buf, fp) == NULL)
fisError("Cannot find NumRules in FIS file!");
if (sscanf(buf, " NumRules = %d ", &rule_n) == 1)
break;
}
fclose(fp);
in_mf_n = (double *)calloc(in_n, sizeof(double));
out_mf_n = (double *)calloc(out_n, sizeof(double));
getMfN(filename, in_n, in_mf_n, out_n, out_mf_n);
total_in_mf_n = fisArrayOperation(in_mf_n, in_n, fisSum);
total_out_mf_n = fisArrayOperation(out_mf_n, out_n, fisSum);
row_n = 11 + 2*(in_n+out_n) +
3*(total_in_mf_n + total_out_mf_n) + rule_n;
free(in_mf_n);
free(out_mf_n);
/* find the col_n */
fp = fisOpenFile(filename, "r");
/* find FIS name */
while (1) {
if (getNextLine(buf, fp) == NULL)
fisError("Cannot find FIS Name in FIS file!");
if (sscanf(buf, " Name = '%[^']' ", fisName) == 1)
break;
}
col_n = (int)strlen(fisName);
col_n = MAX(col_n, 8); /* 'centroid' defuzzification */
/* find FIS type */
while (1) {
if (getNextLine(buf, fp) == NULL)
fisError("Cannot find FIS Type in FIS file!");
if (sscanf(buf, " Type = '%[^']' ", fisType) == 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -