📄 fis.c
字号:
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 fisLoadParameter1(FIS *fis, DOUBLE *para_array, int numofpoints){ 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); fis->input[i]->mf[j]->nparams = paraN; fis->input[i]->mf[j]->params = (DOUBLE *)fisCalloc(MF_PARA_N,sizeof(DOUBLE)); for (k = 0; k < paraN; k++) fis->input[i]->mf[j]->params[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); fis->output[i]->mf[j]->nparams = paraN; fis->output[i]->mf[j]->params = (DOUBLE *)fisCalloc(MF_PARA_N,sizeof(DOUBLE)); for (k = 0; k < paraN; k++) fis->output[i]->mf[j]->params[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++) fis->output[i]->mf[j]->nparams = fis->in_n+1; fis->output[i]->mf[j]->params = (DOUBLE *)fisCalloc(fis->in_n+1, sizeof(DOUBLE)); for (k = 0; k < fis->in_n+1; k++) fis->output[i]->mf[j]->params[k] = para_array[start++]; } else { PRINTF("fis->type = %s\n", fis->type); fisError("Unknown fis type!"); }}/* Returns a FIS pointer if there is a match; otherwise signals error */static FIS *fisMatchHandle(FIS *head, int handle){ FIS *p; for (p = head; p != NULL; p = p->next) if (p->handle == handle) break; if (p == NULL) { PRINTF("Given handle is %d.\n", handle); 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 *fisMatchName(FIS *head, char *name){ 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 fisFindMaxHandle(FIS *head){ 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 1994-2005 The MathWorks, Inc. *//* $Revision: $ $Date: $ *//* Compute MF values for all input variables */static void fisComputeInputMfValue(FIS *fis){ 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->params); else {#ifdef MATLAB_MEX_FILE mf_node->value = fisCallMatlabMf(fis->input[i]->value, mf_node->nparams, mf_node->params, mf_node->type);#else PRINTF("Given MF %s is unknown.\n", mf_node->label); fisError("Exiting ...");#endif } }}/* Compute rule output (for Sugeno model only) */static void fisComputeTskRuleOutput(FIS *fis){ 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->params[k]); out = out + mf_node->params[fis->in_n]; mf_node->value = out; }}/* Compute firing strengths */static void fisComputeFiringStrength(FIS *fis){ 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 PRINTF("Given AND method %s is unknown.\n", fis->andMethod); 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 PRINTF("Given OR method %s is unknown.\n", fis->orMethod); fisError("Exiting ...");#endif } } fis->firing_strength[i] = out; } /* Scale the original firing strength by rule_weight */ for (i = 0; i < fis->rule_n; i++) 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 fisFinalOutputMf(FIS *fis, int m, int n){ 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 fisFinalOutputMf2(FIS *fis, int m, DOUBLE *aggMF, int numofpoints){ 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 PRINTF("Given IMP method %s is unknown.\n", fis->impMethod); 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 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 */void fisEvaluate(FIS *fis, int numofpoints){ 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) {#ifdef SS_SFCN /* Do not generate warning for S-function */ 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 for each output variable is used as default output.\n\n");#endif if (fis->isbias) { for (i = 0; i < fis->out_n; i++) fis->output[i]->value = fis->bias[i]; } else { 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 *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 *)fisCalloc(numofpoints, sizeof(DOUBLE)); aggMF = (DOUBLE *)fisCalloc(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 PRINTF("Given defuzzification method %s is unknown.\n", fis->defuzzMethod); fisError("Exiting ...");#endif } fis->output[i]->value = out; FREE(X); FREE(aggMF); } 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 getFisOutput(DOUBLE *input, FIS *fis, DOUBLE *output){ 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 1994-2007 The MathWorks, Inc. *//* $Revision: $ $Date: 2006/01/01 00:00:00 $ *//* compare strings to skip Version field */int compareString(char *string1, char *string2) { int i; for (i = 0; i<7; i++) { if (string1[i] != string2[i]) { return 0; } } return 1;}/* return the next valid line without comments */static char *#ifdef __STDC__getNextLine(char *buf, FILE *fp)#elsegetNextLine(buf, fp)char *buf;FILE *fp;#endif{ char *returned_value; int i, j; returned_value = fgets(buf, STR_LEN, fp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -