📄 fis.c
字号:
#endif
fisFreeFisNode(fis);
fisError("Exiting ...");
}
}
}
/* check if there is a rule whose premise MF indice are all zeros */
for (i = 0; i < fis->rule_n; i++) {
found = 1;
for (j = 0; j < fis->in_n; j++) {
mf_index = fis->rule_list[i][j];
if (mf_index != 0) {
found = 0;
break;
}
}
if (found == 1) {
#ifndef NO_PRINTF
printf("Rule %d has no premise part.\n", i+1);
#endif
fisFreeFisNode(fis);
fisError("Exiting ...");
}
}
/* check if it's sugeno system with "NOT" consequent */
if (strcmp(fis->type, "sugeno") == 0)
for (i = 0; i < fis->rule_n; i++)
for (j = 0; j < fis->out_n; j++) {
mf_index = fis->rule_list[i][fis->in_n+j];
if (mf_index < 0) {
#ifndef NO_PRINTF
printf("Rule %d has a 'NOT' consequent.\n", i+1);
printf("Sugeno fuzzy inference system does not allow this.\n");
#endif
fisError("Exiting ...");
}
}
/* check if it's sugeno system with zero consequent */
if (strcmp(fis->type, "sugeno") == 0)
for (i = 0; i < fis->rule_n; i++)
for (j = 0; j < fis->out_n; j++) {
mf_index = fis->rule_list[i][fis->in_n+j];
if (mf_index == 0) {
#ifndef NO_PRINTF
printf("\nWarning: Output %d in rule %d has a zero MF index.\n", j+1, i+1);
printf("This output in the rule is assumed zero in subsequent calculation.\n\n");
#endif
}
}
}
/* Build FIS node and load parameter from fismatrix directly */
/* col_n is the number of columns of the fismatrix */
static void
#ifdef __STDC__
fisBuildFisNode(FIS *fis, double **fismatrix, int col_n, int numofpoints)
#else
fisBuildFisNode(fis, fismatrix, col_n)
FIS *fis;
double **fismatrix;
int col_n;
int numofpoints;
#endif
{
int i, j, k;
int *in_mf_n, *out_mf_n;
IO *io_list;
int start;
fisGetString2(fis->name, fismatrix[0], col_n);
fisGetString2(fis->type, fismatrix[1], col_n);
fis->in_n = fismatrix[2][0];
fis->out_n = fismatrix[2][1];
/* create input node list */
in_mf_n = (int *)calloc(fis->in_n, sizeof(int));
for (i = 0; i < fis->in_n; i++)
in_mf_n[i] = fismatrix[3][i];
io_list = fisBuildIoList(fis->in_n, in_mf_n);
free(in_mf_n);
fis->input = (IO **)calloc(fis->in_n, sizeof(IO *));
for (i = 0; i < fis->in_n; i++)
fis->input[i] = io_list+i;
/* create output node list */
out_mf_n = (int *)calloc(fis->out_n, sizeof(int));
for (i = 0; i < fis->out_n; i++)
out_mf_n[i] = fismatrix[4][i];
io_list = fisBuildIoList(fis->out_n, out_mf_n);
free(out_mf_n);
fis->output = (IO **)calloc(fis->out_n, sizeof(IO *));
for (i = 0; i < fis->out_n; i++)
fis->output[i] = io_list+i;
fis->rule_n = fismatrix[5][0];
fisGetString2(fis->andMethod, fismatrix[6], col_n);
fisGetString2(fis->orMethod, fismatrix[7], col_n);
fisGetString2(fis->impMethod, fismatrix[8], col_n);
fisGetString2(fis->aggMethod, fismatrix[9], col_n);
fisGetString2(fis->defuzzMethod, fismatrix[10], col_n);
start = 11;
/* For efficiency, I/O names and MF labels are not stored */
for (i = 0; i < fis->in_n; i++) {
fis->input[i]->name[0] = '\0';
for (j = 0; j < fis->input[i]->mf_n; j++)
fis->input[i]->mf[j]->label[0] = '\0';
}
for (i = 0; i < fis->out_n; i++) {
fis->output[i]->name[0] = '\0';
for (j = 0; j < fis->output[i]->mf_n; j++)
fis->output[i]->mf[j]->label[0] = '\0';
}
start = start + fis->in_n + fis->out_n;
for (i = start; i < start + fis->in_n; i++) {
fis->input[i-start]->bound[0] = fismatrix[i][0];
fis->input[i-start]->bound[1] = fismatrix[i][1];
}
start = start + fis->in_n;
for (i = start; i < start + fis->out_n; i++) {
fis->output[i-start]->bound[0] = fismatrix[i][0];
fis->output[i-start]->bound[1] = fismatrix[i][1];
}
/* update "start" to skip reading of MF labels */
for (i = 0; i < fis->in_n; start += fis->input[i]->mf_n, i++);
for (i = 0; i < fis->out_n; start += fis->output[i]->mf_n, i++);
start = start + fis->out_n;
for (i = 0; i < fis->in_n; i++)
for (j = 0; j < fis->input[i]->mf_n; j++) {
fisGetString2(fis->input[i]->mf[j]->type, fismatrix[start], col_n);
start++;
}
for (i = 0; i < fis->out_n; i++)
for (j = 0; j < fis->output[i]->mf_n; j++) {
fisGetString2(fis->output[i]->mf[j]->type, fismatrix[start], col_n);
start++;
}
fisAssignMfPointer(fis);
fisAssignFunctionPointer(fis);
/* get input MF parameters */
for (i = 0; i < fis->in_n; i++) {
for (j = 0; j < fis->input[i]->mf_n; j++) {
for (k = 0; k < MF_PARA_N; k++)
fis->input[i]->mf[j]->para[k] =
fismatrix[start][k];
start++;
}
}
/* get Mamdani output MF parameters and compute MF value array */
if (strcmp(fis->type, "mamdani") == 0) {
for (i = 0; i < fis->out_n; i++)
for (j = 0; j < fis->output[i]->mf_n; j++) {
fis->output[i]->mf[j]->value_array =
(double *)calloc(numofpoints, sizeof(double));
for (k = 0; k < MF_PARA_N; k++)
fis->output[i]->mf[j]->para[k] =
fismatrix[start][k];
start++;
}
fisComputeOutputMfValueArray(fis, numofpoints);
/* get Sugeno output equation parameters */
} else if (strcmp(fis->type, "sugeno") == 0) {
for (i = 0; i < fis->out_n; i++)
for (j = 0; j < fis->output[i]->mf_n; j++) {
fis->output[i]->mf[j]->sugeno_coef =
(double *)calloc(fis->in_n+1, sizeof(double));
for (k = 0; k < fis->in_n+1; k++)
fis->output[i]->mf[j]->sugeno_coef[k] =
fismatrix[start][k];
start++;
}
} else {
#ifndef NO_PRINTF
printf("fis->type = %s\n", fis->type);
#endif
fisError("Unknown fis type!");
}
fis->rule_list = (int **)fisCreateMatrix
(fis->rule_n, fis->in_n + fis->out_n, sizeof(int));
fis->rule_weight = (double *)calloc(fis->rule_n, sizeof(double));
fis->and_or = (int *)calloc(fis->rule_n, sizeof(int));
for (i = 0; i < fis->rule_n; i++) {
for (j = 0; j < fis->in_n + fis->out_n; j++)
fis->rule_list[i][j] = (int)fismatrix[start][j];
fis->rule_weight[i] = fismatrix[start][fis->in_n+fis->out_n];
fis->and_or[i] = (int)fismatrix[start][fis->in_n+fis->out_n+1];
start++;
}
fis->firing_strength = (double *)calloc(fis->rule_n, sizeof(double));
fis->rule_output = (double *)calloc(fis->rule_n, sizeof(double));
if (strcmp(fis->type, "mamdani") == 0) {
fis->BigOutMfMatrix = (double *)
calloc(fis->rule_n*numofpoints, sizeof(double));
fis->BigWeightMatrix = (double *)
calloc(fis->rule_n*numofpoints, sizeof(double));
}
fis->mfs_of_rule = (double *)calloc(fis->in_n, sizeof(double));
fisCheckDataStructure(fis);
}
/* load parameters and rule list from given fismatrix */
static void
#ifdef __STDC__
fisLoadParameter(FIS *fis, double **fismatrix, int numofpoints)
#else
fisLoadParameter(fis, fismatrix)
FIS *fis;
double **fismatrix;
int numofpoints;
#endif
{
int start;
int i, j, k;
start = 11 + 2*(fis->in_n + fis->out_n);
for (i = 0; i < fis->in_n; start += fis->input[i]->mf_n, i++);
for (i = 0; i < fis->out_n; start += fis->output[i]->mf_n, i++);
for (i = 0; i < fis->in_n; start += fis->input[i]->mf_n, i++);
for (i = 0; i < fis->out_n; start += fis->output[i]->mf_n, i++);
/* get input MF parameters */
for (i = 0; i < fis->in_n; i++) {
for (j = 0; j < fis->input[i]->mf_n; j++) {
for (k = 0; k < MF_PARA_N; k++)
fis->input[i]->mf[j]->para[k] =
fismatrix[start][k];
start++;
}
}
/* get Mamdani output MF parameters */
if (strcmp(fis->type, "mamdani") == 0) {
for (i = 0; i < fis->out_n; i++)
for (j = 0; j < fis->output[i]->mf_n; j++) {
for (k = 0; k < MF_PARA_N; k++)
fis->output[i]->mf[j]->para[k] =
fismatrix[start][k];
start++;
}
fisComputeOutputMfValueArray(fis, numofpoints);
/* get Sugeno output equation parameters */
} else if (strcmp(fis->type, "sugeno") == 0) {
for (i = 0; i < fis->out_n; i++)
for (j = 0; j < fis->output[i]->mf_n; j++) {
for (k = 0; k < fis->in_n+1; k++)
fis->output[i]->mf[j]->sugeno_coef[k] =
fismatrix[start][k];
start++;
}
} else {
#ifndef NO_PRINTF
printf("fis->type = %s\n", fis->type);
#endif
fisError("Unknown fis type!");
}
for (i = 0; i < fis->rule_n; i++) {
for (j = 0; j < fis->in_n + fis->out_n; j++)
fis->rule_list[i][j] = (int)fismatrix[start][j];
fis->rule_weight[i] = fismatrix[start][fis->in_n+fis->out_n];
fis->and_or[i] = (int)fismatrix[start][fis->in_n+fis->out_n+1];
start++;
}
}
/* load parameters contain in the given parameter array */
/* (Note that the array is compact, no zero padding */
static void
#ifdef __STDC__
fisLoadParameter1(FIS *fis, double *para_array, int numofpoints)
#else
fisLoadParameter1(fis, para_array)
FIS *fis;
double *para_array;
int numofpoints;
#endif
{
int start = 0;
int paraN;
int i, j, k;
/* get input MF parameters */
for (i = 0; i < fis->in_n; i++)
for (j = 0; j < fis->input[i]->mf_n; j++) {
paraN = fisGetMfParaN(fis->input[i]->mf[j]->type);
for (k = 0; k < paraN; k++)
fis->input[i]->mf[j]->para[k] = para_array[start++];
}
/* get Mamdani output MF parameters */
if (strcmp(fis->type, "mamdani") == 0) {
for (i = 0; i < fis->out_n; i++)
for (j = 0; j < fis->output[i]->mf_n; j++) {
paraN = fisGetMfParaN(fis->input[i]->mf[j]->type);
for (k = 0; k < paraN; k++)
fis->output[i]->mf[j]->para[k] = para_array[start++];
}
fisComputeOutputMfValueArray(fis, numofpoints);
/* get Sugeno output equation parameters */
} else if (strcmp(fis->type, "sugeno") == 0) {
for (i = 0; i < fis->out_n; i++)
for (j = 0; j < fis->output[i]->mf_n; j++)
for (k = 0; k < fis->in_n+1; k++)
fis->output[i]->mf[j]->sugeno_coef[k] =
para_array[start++];
} else {
#ifndef NO_PRINTF
printf("fis->type = %s\n", fis->type);
#endif
fisError("Unknown fis type!");
}
}
/* Returns a FIS pointer if there is a match; otherwise signals error */
static FIS *
#ifdef __STDC__
fisMatchHandle(FIS *head, int handle)
#else
fisMatchHandle(head, handle)
FIS *head;
int handle;
#endif
{
FIS *p;
for (p = head; p != NULL; p = p->next)
if (p->handle == handle)
break;
if (p == NULL) {
#ifndef NO_PRINTF
printf("Given handle is %d.\n", handle);
#endif
fisError("Cannot find an FIS with this handle.");
}
return(p);
}
/* Returns the FIS handle that matches a given name */
/* If more than two are qualified, the largest handle is returned. */
static FIS *
#ifdef __STDC__
fisMatchName(FIS *head, char *name)
#else
fisMatchName(head, name)
FIS *head;
char *name;
#endif
{
FIS *p, *matched_p = NULL;
for (p = head; p != NULL; p = p->next)
if (strcmp(p->name, name) == 0)
matched_p = p;
return(matched_p);
}
static int
#ifdef __STDC__
fisFindMaxHandle(FIS *head)
#else
fisFindMaxHandle(head)
FIS *head;
#endif
{
FIS *p;
int max_handle = 0;
if (head == NULL)
return(0);
for (p = head; p != NULL; p = p->next)
if (p->handle > max_handle)
max_handle = p->handle;
return(max_handle);
}
/***********************************************************************
Main functions for fuzzy inference
**********************************************************************/
/* Copyright (c) 1994-98 by The MathWorks, Inc. */
/* $Revision: $ $Date: $ */
/* Compute MF values for all input variables */
static void
#ifdef __STDC__
fisComputeInputMfValue(FIS *fis)
#else
fisComputeInputMfValue(fis)
FIS *fis;
#endif
{
int i, j;
MF *mf_node;
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];
if (!mf_node->userDefined)
mf_node->value = (*mf_node->mfFcn)
(fis->input[i]->value, mf_node->para);
else {
#ifdef MATLAB_MEX_FILE
mf_node->value =
fisCallMatlabMf(fis->input[i]->value, mf_node->para, mf_node->type);
#else
#ifndef NO_PRINTF
printf("Given MF %s is unknown.\n", mf_node->label);
#endif
fisError("Exiting ...");
#endif
}
}
}
/* Compute rule output (for Sugeno model only) */
static void
#ifdef __STDC__
fisComputeTskRuleOutput(FIS *fis)
#else
fisComputeTskRuleOutput(fis)
FIS *fis;
#endif
{
int i, j, k;
double out;
MF *mf_node;
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];
out = 0;
for (k = 0; k < fis->in_n; k++)
out += (fis->input[k]->value)*(mf_node->sugeno_coef[k]);
out = out + mf_node->sugeno_coef[fis->in_n];
mf_node->value = out;
}
}
/* Compute firing strengths */
static void
#ifdef __STDC__
fisComputeFiringStrength(FIS *fis)
#else
fisComputeFiringStrength(fis)
FIS *fis;
#endif
{
double out = 0, mf_value;
int i, j, which_mf;
/* Compute original firing strengths via andFcn or orFcn */
for (i = 0; i < fis->rule_n; i++) {
if (fis->and_or[i] == 1) { /* AND premise */
for (j = 0; j < fis->in_n; j++) {
which_mf = fis->rule_list[i][j];
if (which_mf > 0)
mf_value =fis->input[j]->mf[which_mf-1]->value;
else if (which_mf == 0) /* Don't care */
mf_value = 1;
else /* Linguistic hedge NOT */
mf_value = 1 - fis->input[j]->mf[-which_mf-1]->value;
fis->mfs_of_rule[j] = mf_value;
}
if (!fis->userDefinedAnd)
out = fisArrayOperation(
fis->mfs_of_rule, fis->in_n, fis->andFcn);
else {
#ifdef MATLAB_MEX_FILE
out = fisCallMatlabFcn(
fis->mfs_of_rule, fis->in_n, fis->andMethod);
#else
#ifndef NO_PRINTF
printf("Given AND method %s is unknown.\n", fis->andMethod);
#endif
fisError("Exiting ...");
#endif
}
} else { /* OR premise */
for (j = 0; j < fis->in_n; j++) {
which_mf = fis->rule_list[i][j];
if (which_mf > 0)
mf_value =fis->input[j]->mf[which_mf-1]->value;
else if (which_mf == 0) /* Don't care */
mf_value = 0;
else /* Linguistic hedge NOT */
mf_value = 1 - fis->input[j]->mf[-which_mf-1]->value;
fis->mfs_of_rule[j] = mf_value;
}
if (!fis->userDefinedOr)
out = fisArrayOperation(
fis->mfs_of_rule, fis->in_n, fis->orFcn);
else {
#ifdef MATLAB_MEX_FILE
out = fisCallMatlabFcn(
fis->mfs_of_rule, fis->in_n, fis->orMethod);
#else
#ifndef NO_PRINTF
printf("Given OR method %s is unknown.\n", fis->orMethod);
#endif
fisError("Exiting ...");
#endif
}
}
fis->firing_strength[i] = out;
}
/*
for (i = 0; i < fis->rule_n; i++)
printf("%f ", fis->firing_strength[i]);
printf("\n");
*/
/* Scale the original firing strength by rule_weight */
for (i = 0; i < fis->rule_n; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -