You are on page 1of 14

using

using
using
using
using
using
using

System;
System.Collections.Generic;
System.Linq;
System.Text;
System.IO;
System.Windows.Forms;
System.Collections;

namespace WindowsFormsApplication1
{
class MamdaniFIS
{
public string FISName;
private int NumInputs, NumOutputs, NumRules;
private string AndMethod, OrMethod, ImpMethod, AggMethod, DefuzzMethod;
private ArrayList MFs;
private ArrayList FVs;
private int[,] Rules;
private int[] RuleOperator;
private double[,] outSpace;
double outputprecision;
int nofel;
private ArrayList ROs;
private double[] inputs;
public MamdaniFIS(double prec)
{
FISName = "noname";
NumInputs = NumOutputs = NumRules = 0;
AndMethod = ImpMethod = "min";
DefuzzMethod = "com";
OrMethod = AggMethod = "max";
MFs = new ArrayList();
FVs = new ArrayList();
outputprecision = prec;
ROs = new ArrayList();
}

// **************STRUCT******************
public struct MF
{
public string mfname, mftype;
public double a,b,c,d,sigma;
public MF(string mfname, string mftype, double a, double b, double c, double d, double
sigma)

{
this.mfname = mfname;

this.mftype = mftype;
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.sigma = sigma;
}
}
// pokusaj sa listom unutar liste
#region
/*
public struct fuzzyset
{
public string fuzzysetname;
public string mftype;
public double a, b, c, d, sigma;
}
public struct fvar
{
public string fvarname;
public double minrange, maxrange;
public fuzzyset[] values;
}
*/
#endregion
public struct FV
{
public string fvname;
public double minrange, maxrange;
public int firstmfindex, lastmfindex;
public FV(string fvname, double minrange, double maxrange, int firstmfindex, int
lastmfindex)
{

this.fvname = fvname;
this.minrange = minrange;
this.maxrange = maxrange;
this.firstmfindex = firstmfindex;
this.lastmfindex = lastmfindex;

}
// **************MFs******************
private double trimf(double a, double b, double c, double x)
{

return Math.Max(Math.Min((x - a) / (b - a), (c - x) / (c - b)), 0);


}
private double trapmf(double a, double b, double c, double d, double x)
{
return Math.Max(Math.Min(Math.Min((x - a) / (b - a), 1), (d - x) / (d - c)), 0);
}
private double gaussmf(double sigma, double c, double x)
{
//MessageBox.Show("sigma=" + sigma.ToString() + " c=" + c.ToString());
return Math.Exp((Math.Pow((x - c), 2) * (-1)) / (Math.Pow(sigma, 2) * 2));
}
// **************STRING MANAGEMENT******************
private string Strget(string sa, char dlt, int i)
{
string[] splitArray = sa.Split(new char[] { dlt });
return splitArray[i];
}
private double[] StrgetDouble(string sa, char dlt, int nofinputs)
{
double[] dinput = new double[nofinputs];
string[] splitArray = sa.Split(new char[] { dlt });
for (int j = 0; j < nofinputs; j++)
{
dinput[j] = System.Convert.ToDouble(splitArray[j]);
}

return dinput;

}
private string[] Getparams(string sa)
{
string[] splitArray = sa.Split(new char[] {'[' ,']' , ' '});
return splitArray;
}
private string[] GetIF(string sa)
{
string ss;
string[] splitArray = sa.Split(new char[] {','});
ss=splitArray[0];
string[] splitArray1 = ss.Split(new char[]{' '});
return splitArray1;
}

private string[] GetTHEN(string sa)


{
string ss,sss;
string[] splitArray = sa.Split(new char[] { ',' });
ss = splitArray[1];
string[] splitArray1 = ss.Split(new char[] { '(' });
sss = splitArray1[0];
string[] splitArray2 = sss.Split(new char[] { ' ' });
return splitArray2;
}
private string GetOperator(string sa)
{
string s;
string[] splitArray = sa.Split(new char[] { ':' });
s = splitArray[1];
string[] splitArray1 = s.Split(new char[] { ' ' });
return splitArray1[1];
}
private string GetMFname(string sa)
{
string[] splitArray = sa.Split(new char[] {'=',':',','});
return splitArray[1];
}
private string GetMFtype(string sa)
{
string[] splitArray = sa.Split(new char[] { '=', ':',',' });
return splitArray[2];
}
// **************OPEN FIS******************
public void Open(string f)
{
try
{
string s;
TextReader tr = new StreamReader(f);
if (tr == null) throw new FileNotFoundException();
s = tr.ReadLine();
//MessageBox.Show(s);
s = tr.ReadLine();
//MessageBox.Show(s);
s = tr.ReadLine();
//MessageBox.Show(s);
FISName = Strget(s,'=',1);

//MessageBox.Show(FISName);
s = tr.ReadLine();// type is not relevant
s = tr.ReadLine();
//MessageBox.Show(s);
NumInputs = System.Convert.ToInt16(Strget(s, '=',1));
inputs = new double[NumInputs];
//MessageBox.Show("NumInputs "+NumInputs.ToString());
NumOutputs = System.Convert.ToInt16(Strget(tr.ReadLine(),'=', 1));
//MessageBox.Show("NumOutputs "+NumOutputs.ToString());
NumRules = System.Convert.ToInt16(Strget(tr.ReadLine(),'=', 1));
// MessageBox.Show("NumRules " + NumRules.ToString());
AndMethod = Strget(tr.ReadLine(), '=', 1);
// MessageBox.Show(AndMethod);
OrMethod = Strget(tr.ReadLine(), '=', 1);
//MessageBox.Show(OrMethod);
ImpMethod = Strget(tr.ReadLine(), '=', 1);
//MessageBox.Show(ImpMethod);
AggMethod = Strget(tr.ReadLine(), '=', 1);
// MessageBox.Show(AggMethod);
DefuzzMethod = Strget(tr.ReadLine(), '=', 1);
// MessageBox.Show(DefuzzMethod);
// HERE!!!
string tfvname;
double minrange, maxrange;
int numMFs;
int tfirstmfindex = 1;
int tlastmfindex = 1;
string ss;
string[] mfparams;
string tmfname, tmftype;
double ta, tb, tc, td, tsigma;
ta = tb = tc = td = tsigma = 0;
for (int i = 1; i <= NumInputs+NumOutputs; i++)
{
tr.ReadLine();// empty line
tr.ReadLine();//[Input1],...
tfvname = Strget(tr.ReadLine(), '=', 1);
//MessageBox.Show("FVName: " + tfvname);
s = Strget(tr.ReadLine(),'=',1);//range
mfparams = Getparams(s);
minrange = System.Convert.ToDouble(mfparams[1]);
maxrange = System.Convert.ToDouble(mfparams[2]);
numMFs = System.Convert.ToInt16(Strget(tr.ReadLine(), '=', 1));
// MessageBox.Show("numMFs= " + numMFs.ToString());
FVs.Add(new FV(tfvname, minrange, maxrange,
tfirstmfindex,tfirstmfindex+numMFs-1));
//for j reads Mfs from i-th input
#region
for (int j = 1; j <= numMFs; j++)
{
s = tr.ReadLine();
//tempmf.mfname = GetMFname(s);
tmfname = GetMFname(s);
//MessageBox.Show(tmfname);

//tempmf.mftype = GetMFtype(s);
tmftype = GetMFtype(s);
//MessageBox.Show(tmftype);
ss = Strget(s, ',', 1);
//MessageBox.Show("MF params" + ss);
mfparams = Getparams(ss);
//MessageBox.Show(mfparams[1]);
//MessageBox.Show(mfparams[2]);
//switch for mftype
#region
switch (tmftype)
{
case "'gaussmf'":
ta = 0;
tb = 0;
tc = System.Convert.ToDouble(mfparams[2]);
td = 0;
tsigma = System.Convert.ToDouble(mfparams[1]);
//tempmf.c = mfparams[1];
//tempmf.sigma = mfparams[2];
break;
case "'trimf'":
ta = System.Convert.ToDouble(mfparams[1]);
tb = System.Convert.ToDouble(mfparams[2]);
tc = System.Convert.ToDouble(mfparams[3]);
td = 0;
tsigma = 0;
//tempmf.a=mfparams[1];
//tempmf.b = mfparams[2];
//tempmf.c = mfparams[3];
break;
case "'trapmf'":
ta = System.Convert.ToDouble(mfparams[1]);
tb = System.Convert.ToDouble(mfparams[2]);
tc = System.Convert.ToDouble(mfparams[3]);
td = System.Convert.ToDouble(mfparams[4]);
tsigma = 0;
//tempmf.a = System.Convert.ToDouble(mfparams[1]);
//tempmf.b = System.Convert.ToDouble(mfparams[2]);
//tempmf.c = System.Convert.ToDouble(mfparams[3]);
//tempmf.d = System.Convert.ToDouble(mfparams[4]);
break;
} //switch
#endregion
//endswitch for mf type
MFs.Add(new MF(tmfname, tmftype, ta, tb, tc, td, tsigma));
tfirstmfindex++;
} // for j
//tlastmfindex = tfirstmfindex;

//if (tlastmfindex < tfirstmfindex) tlastmfindex = tfirstmfindex;


#endregion
} //for i
// RULE LOADING
tr.ReadLine();
tr.ReadLine();
Rules=new int[NumRules,NumInputs+NumOutputs];
RuleOperator = new int[NumRules];
string[] tIF, tTHEN;
int tOperator;
for (int i = 0; i < NumRules; i++)
{
s = tr.ReadLine();
tOperator=System.Convert.ToInt16(GetOperator(s));
//MessageBox.Show(tOperator.ToString());
int j;
tIF = GetIF(s);
tTHEN = GetTHEN(s);
//MessageBox.Show("Then part: "+tTHEN[1]);
//MessageBox.Show("Length= " + tIF.Length.ToString());
for (j = 0; j < NumInputs+NumOutputs; j++)
{
if (j<NumInputs) Rules[i, j] = System.Convert.ToInt16(tIF[j]);
else if (j >= NumInputs) Rules[i, j] = System.Convert.ToInt16(tTHEN[1]);
//MessageBox.Show(Rules[i, j].ToString());
}
RuleOperator[i] = tOperator;
}

// foreach (MF ar in MFs)


//{
//
// MessageBox.Show("..." + ar.mfname);
//
//}
//the way to read arraylist struct by index!!!!
// MF pr = (MF)MFs[1];
// MessageBox.Show("++++" + pr.mfname);

// Pokusaj sa listom objekata


#region

/*
//fvar[] Inputs = new fvar[NumInputs];
//ArrayList Input = new ArrayList;
object[] Inputs = new object[NumInputs];
fvar ftemp;
for (int i = 0; i == NumInputs; i++)
{
int NumMFs;
tr.ReadLine();// [Input1],...
ftemp.fvarname = Strget(tr.ReadLine(), '=', 1);
tr.ReadLine();// range is irelevant for now.
ftemp.minrange = 0;
ftemp.maxrange = 10;
NumMFs = System.Convert.ToInt16(Strget(tr.ReadLine(), '=', 1));
ftemp.values = new fuzzyset[NumMFs];
for (int j = 0; j == NumMFs; j++)
{
s = tr.ReadLine();
ftemp.values[j].fuzzysetname=Strget(Strget(s,'=',1),':',0);
ftemp.values[j].mftype = Strget(Strget(s, ':', 1), ',', 0);
}
Inputs[i] = ftemp;
s=((fvar)Inputs[0]).fvarname;
MessageBox.Show(s);
}
*/
#endregion
tr.Close();

}
catch (FileNotFoundException ex)
{
MessageBox.Show(ex.Message);
}

// **************SAVE FIS******************
public void Save(string f)
{
TextWriter tw = new StreamWriter(f);
tw.WriteLine("Name=" + FISName);

tw.WriteLine("NumInputs=" + System.Convert.ToString(NumInputs));
tw.WriteLine("NumOutputs=" + System.Convert.ToString(NumOutputs));

for (int i = 0; i <= NumInputs; i++)


{
FV tfv = (FV)FVs[i];
tw.WriteLine();
if (i < NumInputs)
tw.WriteLine("[Input" + (i + 1).ToString() + "]");
else tw.WriteLine("[Output]");
tw.WriteLine("Name="+tfv.fvname);
tw.WriteLine("Range=[" + tfv.minrange.ToString() + " " + tfv.maxrange.ToString() +
"]");
tw.WriteLine("FirstMF= "+tfv.firstmfindex.ToString());
tw.WriteLine("LastMF= " + tfv.lastmfindex.ToString());
for (int j = tfv.firstmfindex; j <= tfv.lastmfindex; j++)
{
MF tmf = (MF)MFs[j-1];
tw.WriteLine("MF" + j.ToString() + "=" + tmf.mfname + ":" + tmf.mftype + " [a=" +
tmf.a.ToString() + " b=" + tmf.b.ToString() + " c=" + tmf.c.ToString() + " d=" + tmf.d.ToString() +
" sigma=" + tmf.sigma.ToString() + "]");
}
//tw.WriteLine();
} // FVs and MVs
tw.WriteLine();
tw.WriteLine("[Rules]");
for (int i = 0; i < NumRules; i++)
{
//tw.WriteLine("[Rule " + i.ToString()+"]");
for (int j = 0; j < NumInputs + NumOutputs; j++)
{
if (j == 0) tw.Write("IF ");
if (j == NumInputs) tw.Write("THEN ");
tw.Write(Rules[i, j] + " ");
}
tw.Write("Operator: "+RuleOperator[i].ToString());
tw.WriteLine();
}
tw.Close();

} // savefis

private double DefuzzCoM()


{
int i, j, ti, tj;
double tmax;
ti = 0;
tmax = outSpace[NumRules, 0];
for (i = 0; i < nofel; i++)
if (outSpace[NumRules, i] > tmax)
{
tmax = outSpace[NumRules, i];
ti = i;
}
//MessageBox.Show("ti="+ti.ToString());
tmax = outSpace[NumRules,nofel-1];
tj = nofel - 1;
for (j = nofel-1; j >= 0; j--)
if (outSpace[NumRules, j] > tmax)
{
tmax = outSpace[NumRules, j];
tj = j;
}
// MessageBox.Show("tj=" + tj.ToString());
return ((ti+tj)/2)*outputprecision;
}
private double NaryMin(double[] inp, int nofin)
{
double res = 1;
for (int i = 0; i < nofin; i++)
if (inp[i] < res) res = inp[i];
return res;
}
private double NaryMax(double[] inp, int nofin)
{
double res = 0;
for (int i = 0; i < nofin; i++)
if (inp[i] > res) res = inp[i];
return res;
}
private double NaryProd(double[] inp, int nofin)
{
double res = 1;
for (int i = 0; i < nofin; i++) res = res * inp[i];
return res;

}
private double NaryProbOr(double[] inp, int nofin)
{
double a, b;
a = inp[0];
b = inp[1];
double res = a+b-(a*b);
for (int i = 2; i < nofin; i++) res = res + inp[i] - (res * inp[i]);
return res;
}
private double CalculateAlfa(int r)
{
double alfa = 0;
int i;
double[] tout=new double[NumInputs];
for (i=0; i<NumInputs;i++)
{
FV tfv = (FV)FVs[i];
//MessageBox.Show(tfv.fvname);
int t = Rules[r - 1, i];//broj mf iz matrice
MF tmf = (MF)MFs[tfv.firstmfindex+Rules[r - 1, i]-2];
//MessageBox.Show(tmf.mfname);
switch (tmf.mftype)
{
case "'trimf'":
tout[i] = trimf(tmf.a, tmf.b, tmf.c, inputs[i]);
//MessageBox.Show("trimf");
break;
case "'trapmf'":
tout[i] = trapmf(tmf.a, tmf.b, tmf.c, tmf.d, inputs[i]);
//MessageBox.Show("trapmf");
//MessageBox.Show(tout[i].ToString());
break;
case "'gaussmf'":
tout[i] = gaussmf(tmf.sigma, tmf.c, inputs[i]);
//MessageBox.Show("gaussmf");
//MessageBox.Show(tout[i].ToString());
break;
}//switch mftype
}//for i
//MessageBox.Show("RuleOperator " + RuleOperator[r-1].ToString());
switch (RuleOperator[r-1])
{
case 1:
alfa = NaryMin(tout, NumInputs);
break;
case 2:
alfa = NaryMax(tout, NumInputs);
break;
} //switch ruleOperator

return alfa;
}
private void InitoutSpace()
{
FV tfv = (FV)FVs[NumInputs];// ovo je Output, poslednji element niza
double mino=tfv.minrange;
double maxo=tfv.maxrange;
nofel =System.Convert.ToInt32((maxo-mino)/outputprecision);// broj elemenata u vrsti
izlaznogprostora
outSpace = new double[NumRules+1,nofel];//+1 za vektor agregacije, velicina izlazne
matrice
//MessageBox.Show(nofel.ToString());
// inicijalizacija izlazne matrice prema Then delovima pravila
int tfirstmfindex=tfv.firstmfindex;
int cmfindex, i,j;
double tvalue;
for (i = 0; i < NumRules; i++)
{
cmfindex=Rules[i,NumInputs];// then deo pravila
//MessageBox.Show("cmfindex"+cmfindex.ToString());
MF tmf = (MF)MFs[tfv.firstmfindex+cmfindex-2];
tvalue=mino;
for ( j = 0; j < nofel; j++)
{
tvalue = tvalue + outputprecision;
switch(tmf.mftype)
{
case "'trimf'":
outSpace[i, j] = trimf(tmf.a, tmf.b, tmf.c, tvalue);
break;
case "'trapmf'":
outSpace[i, j] = trapmf(tmf.a, tmf.b, tmf.c,tmf.d, tvalue);
break;
case "'gaussmf'":
outSpace[i, j] = gaussmf(tmf.sigma,tmf.c,tvalue);
break;
}//case
}//for j
}//for i
/*
TextWriter tw = new StreamWriter("initoutspace.txt");
for (i = 0; i < NumRules; i++)
{
for (j = 0; j < nofel; j++) tw.Write(outSpace[i, j] + ",");
tw.WriteLine();
}

tw.Close();
*/

private void CutOut(int r, double alfa)


{
int i, j;
for ( i = 0; i < nofel; i++) if (outSpace[r - 1, i] > alfa) outSpace[r - 1, i] = alfa;
/*
TextWriter tw = new StreamWriter("cutoutspace.txt");
for (i = 0; i < NumRules; i++)
{
for (j = 0; j < nofel; j++) tw.Write(outSpace[i, j] + ",");
tw.WriteLine();
}

tw.Close();
*/

private void OutputAggreagtion()


{
int i, j;
for (i = 0; i < nofel; i++) outSpace[NumRules, i] = 0;
for (j = 0; j < nofel; j++)
for (i = 0; i < NumRules; i++) if (outSpace[i, j] > outSpace[NumRules, j])
outSpace[NumRules, j] = outSpace[i, j];
/*
TextWriter tw = new StreamWriter("outputagg.txt");
for (i = 0; i < nofel; i++)
tw.Write(outSpace[NumRules, i].ToString()+",");

tw.WriteLine();
tw.Close();
*/

public void GOFIS(string fin, string fout)


{
int i, j, nofin;
string s;
TextReader tr = new StreamReader(fin);
TextWriter tw = new StreamWriter(fout);
nofin=System.Convert.ToInt32(tr.ReadLine());
for (i = 1; i <= nofin; i++)
{
inputs = StrgetDouble(tr.ReadLine(), ',', NumInputs);
InitoutSpace();
for (j = 1; j <= NumRules; j++) CutOut(j, CalculateAlfa(j));
OutputAggreagtion();

// for (i = 0; i < nofel; i++) MessageBox.Show("m("+i.ToString()


+")="+outSpace[NumRules, i].ToString());
s=System.Convert.ToString(DefuzzCoM());
MessageBox.Show(s);
tw.WriteLine(s);
}

tr.Close();
tw.Close();
}

} // class
} // namespace

You might also like