//--------------------------------------------------------------------------- #include #include #include #include "fclasses.h" /* ************************************************************************** ************** MembershipFunction ************** create a new instance of a trapez membership function object. input: from - the intersection point of the left side with the X axis (start of the left side) max1 - the point where the trapez's upper side starts. max2 - the point where the trapez's upper side ends. to - the intersection point of the right side with the X axis. creation date: last update: */ MembershipFunction::MembershipFunction(double from,double max1,double max2,double to,char *name) { this->from=from; this->max1=max1; this->max2=max2; this->to=to; if (name) strcpy(this->name,name); } /**************************************************************************/ /* ************ calculate **************** purpose: calculate the output of a trapez membership functions. inputs: value - the input value. output: the result of placing the value "value" in the membership function. creation date: last update: */ double MembershipFunction::calculate(double value) { if (valueto) return(0); /* out of the function's range */ if (value>=max1 && value<=max2) return(1); /* the top of the trapez */ if (valuemax2) return(1-(value-max2)/(to-max2)); return(0); /* this line should never run */ } /****************************************************************************/ /* *********** calculate ************** purpose: calculate the level of truth of a rule, according to the given inputs (altitude, azimuth). This method is called during the infference computation inputs: altitude,azimuth - the given inputs. output: the level of truth of that rule. note: This method is used both by one dimension models and two dimensional models. When the model has only one dimension, the "azimuth" parameter is ignored. */ double FuzzyRule::calculate(double value1,double value2,double value3) { double res; if (func1 && func2 && func3) res=this->func1->calculate(value1)* this->func2->calculate(value2)* this->func3->calculate(value3); else if (func1 && func2) res=this->func1->calculate(value1)* /* altitude */ this->func2->calculate(value2); /* azimuth */ else res=this->func1->calculate(value1); return(res); } /***************************************************************************/ /* ********** constructor of the fuzzy rule object *********** purpose: to create an instance of the fuzzy rule class. When the model has only one dimension, func2 should be NULL. inputs: func1, func2 - the two membership functions. creation date: last update: */ FuzzyRule::FuzzyRule(MembershipFunction *func1,MembershipFunction *func2,MembershipFunction *func3,double value) { this->func1=func1; this->func2=func2; this->func3=func3; this->value=value; } //--------------------------------------------------------------------------- int FuzzyModelBody::CreateMembershipFunctions(char *datafile) { FILE *dataset; char record[200],*not_eof,*p_record; int AzFuncIndex,AltFuncIndex,RuleIndexX,RuleIndexY; double value; for (AzFuncIndex=0;AzFuncIndex3 && record[0]!='/') { /* create the membership functions */ p_record=strtok(record," \n"); value=atof(p_record); AltitudeFunctions[AltFuncIndex]=new MembershipFunction(value-4,value,value,value+4,NULL); p_record=strtok(NULL," \n"); value=atof(p_record); AzimuthFunctions[AzFuncIndex]=new MembershipFunction(value-16,value,value,value+16,NULL); /* create the fuzzy rules for X and Y coordinates */ p_record=strtok(NULL," \n"); value=atof(p_record); RulesX[RuleIndexX]=new FuzzyRule(AltitudeFunctions[AltFuncIndex],AzimuthFunctions[AzFuncIndex],NULL,value); p_record=strtok(NULL," \n"); value=atof(p_record); RulesY[RuleIndexY]=new FuzzyRule(AltitudeFunctions[AltFuncIndex],AzimuthFunctions[AzFuncIndex],NULL,value); /* increment all the indices */ AltFuncIndex++; AzFuncIndex++; RuleIndexX++; RuleIndexY++; /* get the next recoed */ } not_eof=fgets(record,sizeof(record),dataset); } fclose(dataset); return(1); /* function ended successfully */ } //----------------------------------------------------------------------- FuzzyModelBody::~FuzzyModelBody() { int RuleIndex,FuncIndex; for (RuleIndex=0;RuleIndexcalculate(altitude,azimuth,0); /* infference */ counter+=res*RulesX[RuleIndex]->value; /* defuzzification */ common+=res; } if (common>0) return(counter/common); else return(0); } //------------------------------------------------------------------------- double FuzzyModelBody::CalcRulesY(double altitude,double azimuth) { int RuleIndex; double counter,common,res; counter=0; common=0; for (RuleIndex=0;RuleIndexcalculate(altitude,azimuth,0); /* infference */ counter+=res*RulesY[RuleIndex]->value; /* defuzzification */ common+=res; } if (common>0) return(counter/common); else return(0); } //------------------------------------------------------------------------- int OneDimModel::CreateMembershipFunctions(char *DataFileName) { FILE *dataset; char record[200],*p_record; int FuncIndex,RuleIndex,FuncNum,a,b,len,not_eof; DataValue values[MAX_FUNC_NUM],temp; double start,end,top; float data; for (FuncIndex=0;FuncIndex3 && record[0]!='/') { /* unpack the record */ // len=strlen(record); // for (a=0;avalues[b+1].in) { temp=values[b]; values[b]=values[b+1]; values[b+1]=temp; a=1; } } /* create the membership functions */ for (RuleIndex=0;RuleIndexcalculate(parameter,0,0); /* infference */ counter+=res*Rules[RuleIndex]->value; /* defuzzification */ common+=res; } else break; if (common>0) return(counter/common); else return(0); } //------------------------------------------------------------------------- OneDimModel::~OneDimModel() { int RuleIndex,FuncIndex; for (RuleIndex=0;RuleIndex3 && record[0]!='/') { /* create the membership functions */ p_record=strtok(record," \n"); values[FuncIndex].in1=atof(p_record); p_record=strtok(NULL," \n"); values[FuncIndex].in2=atof(p_record); p_record=strtok(NULL," \n"); values[FuncIndex].out=atof(p_record); } FuncIndex++; not_eof=fgets(record,sizeof(record),dataset); } FuncNum=FuncIndex; fclose(dataset); /* sort the data using bubble sort */ /* create a lexicografic sort */ a=1; while (a==1) { a=0; for (b=0;bvalues[b+1].in1) { temp=values[b]; values[b]=values[b+1]; values[b+1]=temp; a=1; } } a=1; while (a==1) { a=0; for (b=0;bvalues[b+1].in2 && values[b].in1==values[b+1].in1) { temp=values[b]; values[b]=values[b+1]; values[b+1]=temp; a=1; } } /* create the membership functions */ for (RuleIndex=0;RuleIndex0 && values[FuncIndex].in1==values[a].in1) a--; /* search for the first different value */ start=values[a].in1; } if (FuncIndex==FuncNum-1) end=values[FuncIndex].in1; /* the first membership function only goes down */ else { a=FuncIndex; while(acalculate(parameter1,parameter2,0); /* infference */ counter+=res*Rules[RuleIndex]->value; /* defuzzification */ common+=res; } else break; if (common>0) return(counter/common); else return(0); } //------------------------------------------------------------------------- TwoDimModel::~TwoDimModel() { int RuleIndex,FuncIndex; for (RuleIndex=0;RuleIndexname)==0) return(MembershipFunctions[FuncIndex]); return(NULL); } //------------------------------------------------------------------------- int ThreeDimModel::LoadRules(char *filename) { char line[300],*p_line; double value; int RulesCounter=0,RulesSection=0; MembershipFunction *func1,*func2,*func3; FILE *file; file=fopen(filename,"r"); if (!file) return(0); p_line=fgets(line,300,file); /* read the file and create the rules */ while (p_line) { if (strstr(p_line,"rules:")) RulesSection=1; if (strlen(p_line)>8) /* make sure that the line is not empty */ if (p_line[0]!='/' && RulesSection) { p_line=strtok(line," \n\t"); func1=FindMembershipFunction(p_line); p_line=strtok(NULL," \n\t"); func2=FindMembershipFunction(p_line); p_line=strtok(NULL," \n\t"); func3=FindMembershipFunction(p_line); p_line=strtok(NULL," \n\t"); value=atof(p_line); Rules[RulesCounter]=new FuzzyRule(func1,func2,func3,value); Rules[RulesCounter+1]=NULL; RulesCounter++; } p_line=fgets(line,300,file); } fclose(file); return(1); } //------------------------------------------------------------------------- int ThreeDimModel::LoadMembershipFunctions(char *filename) { char line[300],*p_line; int FunctionCounter=0; double from,max1,max2,to; char *name; FILE *file; file=fopen(filename,"r"); if (!file) return(0); p_line=fgets(line,300,file); /* read the file and create the rules */ while (p_line) { if (strstr(p_line,"rules:")) break; /* the rules section started and ended to membership functions section */ if (strlen(p_line)>4) /* make sure that the line is not empty */ if (p_line[0]!='/') { p_line=strtok(line," \n\t"); name=p_line; p_line=strtok(NULL," \n\t"); from=atof(p_line); p_line=strtok(NULL," \n\t"); max1=atof(p_line); p_line=strtok(NULL," \n\t"); max2=atof(p_line); p_line=strtok(NULL," \n\t"); to=atof(p_line); MembershipFunctions[FunctionCounter]=new MembershipFunction(from,max1,max2,to,name); MembershipFunctions[FunctionCounter+1]=NULL; FunctionCounter++; } p_line=fgets(line,300,file); } fclose(file); return(1); } //------------------------------------------------------------------------- double ThreeDimModel::CalculateRules(double value1, double value2, double value3) { int RuleIndex; double counter,common,res; counter=0; common=0; for (RuleIndex=0;RuleIndexcalculate(value1,value2,value3); /* infference */ counter+=res*Rules[RuleIndex]->value; /* defuzzification */ common+=res; } else break; if (common>0) return(counter/common); else return(0); } //--------------------------------------------------------------------------- ThreeDimModel::~ThreeDimModel() { int RuleIndex,FuncIndex; for (RuleIndex=0;RuleIndex