⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fis.cpp

📁 2002年
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -