📄 fis.c
字号:
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 < MF_POINT_N; j++)
fis->BigOutMfMatrix[j*fis->rule_n+i] = 0;
}
/* fill in BigWeightMatrix */
for (i = 0; i < fis->rule_n; i++)
for (j = 0; j < MF_POINT_N; 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)*MF_POINT_N; 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, MF_POINT_N, fis->impMethod, fis->BigOutMfMatrix);
#else
printf("Given IMP method %s is unknown.\n", fis->impMethod);
fisError("Exiting ...");
#endif
}
/* apply MATLAB aggregate operator */
if (!fis->userDefinedAgg)
for (i = 0; i < MF_POINT_N; 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,
MF_POINT_N, fis->aggMethod, aggMF);
#else
printf("Given AGG method %s is unknown.\n", fis->aggMethod);
fisError("Exiting ...");
#endif
}
}
/***********************************************************************
Evaluate the constructed FIS based on given input vector
**********************************************************************/
/* compute outputs and put them into output nodes */
static void
#ifdef __STDC__
fisEvaluate(FIS *fis)
#else
fisEvaluate(fis)
FIS *fis;
#endif
{
double out = 0;
double total_w, total_wf;
int i, j, k, which_mf;
if (fis == NULL) {
printf("FIS data structure has not been built yet.\n");
fisError("Exiting ...");
}
fisComputeInputMfValue(fis);
fisComputeFiringStrength(fis);
total_w = fisArrayOperation(fis->firing_strength, fis->rule_n, fisSum);
if (total_w == 0) {
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");
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 {
printf("Unknown method (%s) for Sugeno model!", fis->defuzzMethod);
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 min = fis->output[i]->bound[0];
double max = fis->output[i]->bound[1];
double step = (max - min)/(MF_POINT_N - 1);
for (j = 0; j < MF_POINT_N; j++)
X[j] = min + step*j;
/* fill in aggMF */
fisFinalOutputMf2(fis, i, aggMF);
/* defuzzification */
if (!fis->userDefinedDefuzz)
out = (*fis->defuzzFcn)(fis, i, aggMF);
else { /* user defined defuzzification */
#ifdef MATLAB_MEX_FILE
out = fisCallMatlabDefuzz(X, aggMF,
MF_POINT_N, fis->defuzzMethod);
#else
printf("Given defuzzification method %s is unknown.\n", fis->defuzzMethod);
fisError("Exiting ...");
#endif
}
fis->output[i]->value = out;
}
else {
printf("Given FIS %s is unknown.\n", fis->name);
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);
/* dispatch output */
for (i = 0; i < fis->out_n; i++)
output[i] = fis->output[i]->value;
}
/* 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)
break;
}
/* find IO names, MF labels, MF types */
while (getNextLine(buf, fp) != NULL) {
if (sscanf(buf, " Name = '%[^']' ", IoName) == 1)
col_n = MAX(col_n, (int)strlen(IoName));
if (sscanf(buf, " %[^'] '%[^']' : '%[^']' , [ %[^]] ",
tmp1, tmp2, tmp3, tmp4) == 4) {
col_n = MAX(col_n, (int)strlen(tmp2));
col_n = MAX(col_n, (int)strlen(tmp3));
}
}
if (!strcmp(fisType, "mamdani"))
col_n = MAX(col_n, MF_PARA_N);
else if (!strcmp(fisType, "sugeno"))
col_n = MAX(col_n, in_n+out_n+2);
else
fisError("Unknown FIS type!");
fclose(fp);
/*
printf("row_n = %d\n", row_n);
printf("col_n = %d\n", col_n);
*/
*row_n_p = row_n;
*col_n_p = col_n;
fismatrix = (double **)fisCreateMatrix(row_n, col_n, sizeof(double));
return(fismatrix);
}
/* return a FIS matrix with all information */
static double **
#ifdef __STDC__
returnFismatrix(char *fis_file, int *row_n_p, int *col_n_p)
#else
returnFismatrix(fis_file, row_n_p, col_n_p)
char *fis_file;
int *row_n_p;
int *col_n_p;
#endif
{
int i, j, k;
FILE *fp;
char buf[STR_LEN];
char str1[STR_LEN], str2[STR_LEN], str3[STR_LEN], str4[STR_LEN];
char fisType[STR_LEN];
int in_n, out_n, rule_n;
int mf_n;
int now;
double **fismatrix;
double *in_mf_n, *out_mf_n;
fismatrix = returnEmptyFismatrix(fis_file, row_n_p, col_n_p);
fp = fisOpenFile(fis_file, "r");
/* looping till it finds "[System]" */
while (1) {
if (getNextLine(buf, fp) == NULL)
fisError("Cannot find [System] in FIS file!");
if (!strcmp(buf, "[System]")) /* found it! */
break;
}
/* get FIS information */
now = 0;
getString(buf, fp, fismatrix[now++]); /* name */
getString(buf, fp, fismatrix[now++]); /* type */
for (i = 0; i < STR_LEN && fismatrix[1][i] != 0; i++)
fisType[i] = (int) fismatrix[1][i];
fisType[i] = 0;
in_n = (int)getNumber(buf, fp);
out_n = (int)getNumber(buf, fp);
fismatrix[now][0] = (double) in_n;
fismatrix[now][1] = (double) out_n;
now++;
/* create in_mf_n and out_mf_n */
in_mf_n = (double *)calloc(in_n, sizeof(double));
out_mf_n = (double *)calloc(out_n, sizeof(double));
getMfN(fis_file, in_n, in_mf_n, out_n, out_mf_n);
for (i = 0; i < in_n; i++)
fismatrix[now][i] = in_mf_n[i];
now++;
for (i = 0; i < out_n; i++)
fismatrix[now][i] = out_mf_n[i];
now++;
rule_n = (int)getNumber(buf, fp);
fismatrix[now++][0] = (double) rule_n;
getString(buf, fp, fismatrix[now++]); /* and method */
getString(buf, fp, fismatrix[now++]); /* or method */
getString(buf, fp, fismatrix[now++]); /* imp method */
getString(buf, fp, fismatrix[now++]); /* agg method */
getString(buf, fp, fismatrix[now++]); /* defuzz method */
fclose(f
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -