📄 fis.cpp
字号:
#include "fis.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "smp_func.h"
/* Fuzzy inference system */
/* Static Member function */
/*triangular membership function
* three params
* input -> output
*/
void MemFunc::trimf(float input,float& output,int numparams,float* params){
if(numparams != 3) return;
if(input <= params[0] || input >= params[2])
output = 0.0f;
else if(input < params[1] )
output = (input - params[0])/( params[1] - params[0]);
else
output = (params[2] -input)/( params[2] - params[1]);
}
/* trapezoidal membership function */
void MemFunc::trapmf(float input,float& output,int numparams,float* params){
if(numparams != 4) return;
if(input <= params[0] || input >= params[3])
output = 0.0f;
else if(input >= params[1] && input <= params[2])
output=1.0f;
else if(input < params[1])
output = (input - params[0] )/( params[1] - params[0]);
else
output = (params[3] -input)/( params[3] - params[2]);
}
/*GAUSSMF(X, [SIGMA, C]) = EXP(-(X - C).^2/(2*SIGMA^2))*/
void MemFunc::gaussmf(float input,float& output,int numparams,float* params){
if(numparams != 2) return;
output = (float)exp(-0.5*Sqr((input - params[1])/params[0]));
}
void MemFunc::gauss2mf(float input,float& output,int numparams,float* params){
if(numparams != 4) return;
if(input < params[1])
output = (float)exp(-0.5*Sqr((input - params[1] )/params[0]));
else if(input > params[3])
output = (float)exp(-0.5*Sqr((input - params[3] )/params[2]));
else
output = 1.0f;
}
/* GBELLMF(X, [A, B, C]) = 1./((1+ABS((X-C)/A))^(2*B))*/
void MemFunc::gbellmf(float input,float& output,int numparams,float* params){
if(numparams != 3) return;
output=(float)(pow(fabs((input- params[2])/ params[0])+ 1.0, params[1] * -2.0));
}
/*SIGMF(X, [A, C]) = 1./(1 + EXP(-A*(X-C)))*/
void MemFunc::sigmf(float input,float& output,int numparams,float* params){
if(numparams != 2) return;
output=(float)(1.0f/(exp(params[0] * (params[1] - input) +1.0f)));
}
void MemFunc::dsigmf(float input,float& output,int numparams,float* params){
if(numparams != 4) return;
float sig1, sig2;
sigmf(input, sig1, 2, params);
sigmf(input, sig2, 2, params+2);
output = (float)fabs(sig1-sig2);
}
/*PSIGMF(X, PARAMS) = SIGMF(X, PARAMS(1:2)).*SIGMF(X, PARAMS(3:4));*/
void MemFunc::psigmf(float input,float& output,int numparams,float* params){
if(numparams != 4) return;
float sig1, sig2;
sigmf(input, sig1, 2, params);
sigmf(input, sig2, 2, params+2);
output=sig1 * sig2;
}
void MemFunc::zmf(float input,float& output,int numparams,float* params){
if(numparams != 2) return;
if(params[0] >= params[1]){
if(input <= 0.5f * (params[0] + params[1]))
output = 1.0f;
else
output = 0.0f;
}else{
if(input <= params[0])
output = 1.0f;
else if(input >= params[1])
output = 0.0f;
else if(input >= 0.5f * (params[0] + params[1]))
output=(float)(2.0f * Sqr((params[1]-input)/(params[1] - params[0])));
else
output=(float)(1.0f - 2.0f * (float)Sqr((input - params[0])/(params[1] - params[0])));
}
}
void MemFunc::smf(float input,float& output,int numparams,float* params){
if(numparams!=2) return;
if(params[0] <= params[1]){
if(input >= 0.5*(params[0] + params[1]))
output = 1.0f;
else
output = 0.0f;
}else{
if(input <= params[0])
output = 0.0f;
else if(input >= params[1])
output = 1.0f;
else if(input >= 0.5f * (params[0] + params[1]))
output=(float)(1.0f - 2.0f * pow((params[1]-input)/(params[1] - params[0]),2));
else
output=(float)(2.0f * pow((input - params[0])/(params[1] - params[0]),2));
}
}
/*PIMF(X, PARAMS) = SMF(X, PARAMS(1:2)).*ZMF(X, PARAMS(3:4))*/
void MemFunc::pimf(float input,float& output,int numparams,float* params){
if(numparams != 4) return;
float smfresult,zmfresult;
smf(input, smfresult, 2 ,params);
zmf(input, zmfresult, 2 ,params+2);
output=smfresult * zmfresult;
}
/* Constant */
void MemFunc::cmf(float input, float& output, int numparams, float* params){
if (numparams != 1) return;
output = params[0];
}
/* Linear */
void MemFunc::lmf(float input, float& output, int numparams, float* params){
if (numparams != 2) return;
output = params[0] + params[1] * input;
}
MemFunc::MemFunc(){
mftype = TRIMF;
numparams = 0;
name[0] = 0;
}
void MemFunc::SetMFType(MEMFUNC mftype){
this->mftype = mftype;
switch(mftype){
case TRIMF:
numparams = 3;
break;
case TRAPMF:
numparams = 4;
break;
case GAUSSMF:
numparams = 2;
break;
case GAUSS2MF:
numparams = 4;
break;
case GBELLMF:
numparams = 3;
break;
case SIGMF:
numparams = 2;
break;
case DSIGMF:
numparams = 4;
break;
case PSIGMF:
numparams = 4;
break;
case ZMF:
numparams = 2;
break;
case PIMF:
numparams = 4;
break;
case SMF:
numparams = 2;
break;
case LINEAR:
numparams = 2;
break;
case CONSTANT:
numparams = 1;
break;
}
}
float MemFunc::GetMembership(float input){
this->input = input;
output=0.0f;
switch(mftype){
case TRIMF:
trimf(input, output, numparams, params);
break;
case TRAPMF:
trapmf(input, output, numparams, params);
case GAUSSMF:
gaussmf(input, output, numparams, params);
break;
case GAUSS2MF:
gauss2mf(input,output,numparams,params);
break;
case GBELLMF:
gbellmf(input,output,numparams,params);
break;
case SIGMF:
sigmf(input,output,numparams,params);
break;
case DSIGMF:
dsigmf(input,output,numparams,params);
break;
case PSIGMF:
psigmf(input,output,numparams,params);
break;
case ZMF:
zmf(input,output,numparams,params);
break;
case PIMF:
pimf(input,output,numparams,params);
break;
case SMF:
smf(input,output,numparams,params);
break;
case LINEAR:
lmf(input, output, numparams, params);
break;
case CONSTANT:
cmf(input, output, numparams, params);
break;
}
return output;
}
/* Fuzzy Variables */
FuzzyVariable::FuzzyVariable(){
nummfs = 0;
mfs = NULL;
name[0] = 0;
input_inf = 0.0f;
input_sup = 1.0f;
}
void FuzzyVariable::ReleaseResource(){
if (mfs != NULL) delete mfs;
}
float FuzzyVariable::GetOutput(int idx){
if (idx <=0 || idx > nummfs)
return 0.0f;
return mfs[idx -1].GetOutput();
}
float FuzzyVariable::GetMembership(int idx, float input){
if (idx <=0 || idx > nummfs)
return 0.0f;
return mfs[idx -1].GetMembership(input);
}
void FuzzyVariable::Fuzzify(){
int idx;
for(idx = 1; idx <= nummfs; idx ++){
mfs[idx -1].GetMembership(input);
}
}
/* Rule */
Rule::Rule(int numinputs, int numoutputs){
SetRuleParams(numinputs, numoutputs);
}
void Rule::SetRuleParams(int numinputs, int numoutputs){
this->numinputs = numinputs;
this->numoutputs = numoutputs;
if (numinputs <= 0 || numoutputs <= 0){
numinputs = 0;
inputmfidx = NULL;
numoutputs = 0;
outputmfidx = NULL;
}
else{
inputmfidx = new int[numinputs];
outputmfidx = new int [numoutputs];
}
}
void Rule::ReleaseResource(){
if (inputmfidx != NULL) delete inputmfidx;
if (outputmfidx != NULL) delete outputmfidx;
inputmfidx = NULL;
outputmfidx = NULL;
}
/* FIS */
float MinAND(float x, float y){ return x < y ? x : y;}
float MaxOR(float x, float y){ return x > y ? x : y;}
float ProdAND(float x, float y){ return x * y;}
float ProbOR(float x, float y){ return x + y - x * y;}
float NOT(float x){ return 1 - x; }
FIS::FIS(){
andtype = MINAND;
ortype = MAXOR;
imptype = MINAND;
aggtype = MAXOR;
defzytype = CENTROID;
SYSTYPE systype = MAMDANI;
name[0] = 0;
numinputs = 0;
numoutputs = 0;
numrules = 0;
fuzzyinputs = NULL;
fuzzyoutputs = NULL;
rules = NULL;
}
FIS::~FIS(){
int i;
for(i = 0; i< numinputs; i ++)
fuzzyinputs[i].ReleaseResource();
for(i = 0; i< numoutputs; i ++)
fuzzyoutputs[i].ReleaseResource();
for(i = 0; i< numrules; i ++)
rules[i].ReleaseResource();
if (fuzzyinputs != NULL) delete fuzzyinputs;
if (fuzzyoutputs != NULL) delete fuzzyoutputs;
if (rules != NULL) delete rules;
}
char* FIS::getNextLine(FILE* fp){
if (!fgets(buf, STR_LEN, fp))
return NULL;
/* skip if it starts with '%' or '\n' */
if (buf[0] == '%' || buf[0] == '\n')
return getNextLine(fp);
/* get rid of trailing comment or new line */
int i;
for(i = 0; buf[i]!='%' && buf[i]!='\n' && i < STR_LEN; i++);
buf[i] = 0;
return buf;
}
Bool FIS::ParseLine(){
if (buf[0] == '[' && buf[strlen(buf) - 1] == ']'){
Islabel = True;
}
else{
Islabel = False;
if (sscanf(buf, " %[^=]", namebuf) != 1) return False;
strncpy(valuebuf, buf + strlen(namebuf) + 1, STR_LEN - strlen(namebuf) -1);
}
return True;
}
Bool FIS::AnalyzeNextEntry(FILE* fp){
if (!getNextLine(fp)) return False;
return ParseLine();
}
Bool FIS::getString(){
return Bool(sscanf(valuebuf, "'%[^']' ",stringbuf) == 1);
}
Bool FIS::RestoreFIS(char* filename){
FILE* fp;
if ((fp = fopen(filename, "r")) == NULL) return False;
/* Read system parameters */
if (!AnalyzeNextEntry(fp)) return False;
if (!Islabel || strncmp(namebuf, "System", 6) == 0) return False;
/* Reset Parameters */
name[0] = NULL;
numinputs = -1;
numoutputs = -1;
numrules = -1;
andtype = MINAND;
ortype = MAXOR;
imptype = MINAND;
aggtype = MAXOR;
defzytype = CENTROID;
systype = MAMDANI;
if (fuzzyinputs != NULL){
delete(fuzzyinputs);
}
if (fuzzyoutputs != NULL){
delete(fuzzyinputs);
}
if (rules != NULL){
delete(fuzzyinputs);
}
int tmp;
char tmpbuf1[STR_LEN], tmpbuf2[STR_LEN], tmpbuf3[STR_LEN], tmpbuf4[STR_LEN];
while(AnalyzeNextEntry(fp)){
if (Islabel) break;
if (strncmp(namebuf, "Name", 4) == 0){
if (getString()){
strcpy(name, stringbuf);
}
}
else if (strncmp(namebuf, "Type", 4) == 0){
if (getString()){
if (strncmp(stringbuf, "sugeno", 6) == 0){
systype = SUGENO;
}
else if (strncmp(stringbuf, "mamdani", 7) == 0){
systype = MAMDANI;
}
else{
//printf("Illegal system type\n");
}
}
}
else if (strncmp(namebuf, "Version", 7) == 0){
}
else if (strncmp(namebuf, "NumInputs", 9) == 0){
tmp = sscanf(valuebuf, "%d", &numinputs);
if (tmp != 1 || numinputs < 0)
return False;
}
else if (strncmp(namebuf, "NumOutputs", 10) == 0){
tmp = sscanf(valuebuf, "%d", &numoutputs);
if (tmp != 1 || numoutputs < 0)
return False;
}
else if (strncmp(namebuf, "NumRules", 8) == 0){
tmp = sscanf(valuebuf, "%d", &numrules);
if (tmp != 1 || numrules < 0)
return False;
}
else if (strncmp(namebuf, "AndMethod", 9) == 0){
if (getString()){
if (strncmp(stringbuf, "min", 3) == 0){
andtype = MINAND;
}
else if (strncmp(stringbuf, "prod", 4) == 0){
andtype = PRODAND;
}
else{
//printf("Illegal andmethod\n");
}
}
}
else if (strncmp(namebuf, "OrMethod", 8) == 0){
if (getString()){
if (strncmp(stringbuf, "max", 3) == 0){
ortype = MAXOR;
}
else if (strncmp(stringbuf, "probor", 6) == 0){
ortype = PROBOR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -