/// <summary> /// Calculates the defuzzification value with the CoG (Center of Gravity) technique. /// </summary> /// <returns>The defuzzification value.</returns> public double Defuzzify() { double numerator = 0; double denominator = 0; // Reset values foreach (MembershipFunction membershipFunction in this.GetConsequent().MembershipFunctionCollection) { membershipFunction.Value = 0; } foreach (FuzzyRule fuzzyRule in this.fuzzyRuleCollection) { fuzzyRule.Value = Parse(fuzzyRule.Conditions()); string[] tokens = fuzzyRule.Text.Split(); MembershipFunction membershipFunction = this.GetConsequent().MembershipFunctionCollection.Find(tokens[tokens.Length - 1]); if (fuzzyRule.Value > membershipFunction.Value) { membershipFunction.Value = fuzzyRule.Value; } } foreach (MembershipFunction membershipFunction in this.GetConsequent().MembershipFunctionCollection) { numerator += membershipFunction.Centorid() * membershipFunction.Area(); denominator += membershipFunction.Area(); } return(numerator / denominator); }
/// <summary> /// Implements the fuzzification of the linguistic variable. /// </summary> /// <param name="membershipFunctionName">The membership function for which fuzzify the variable.</param> /// <returns>The degree of membership.</returns> public double Fuzzify(string membershipFunctionName) { MembershipFunction membershipFunction = this.membershipFunctionCollection.Find(membershipFunctionName); /* * if ((membershipFunction.X0 <= this.Value) && (this.Value < membershipFunction.X1)) * return (this.Value - membershipFunction.X0) / (membershipFunction.X1 - membershipFunction.X0); * else if ((membershipFunction.X1 <= this.Value) && (this.Value <= membershipFunction.X2)) * return 1; * else if ((membershipFunction.X2 < this.Value) && (this.Value <= membershipFunction.X3)) * return (membershipFunction.X3 - this.Value) / (membershipFunction.X3 - membershipFunction.X2); * else */ return(0); }
/// <summary> /// Implements the fuzzification of the linguistic variable. /// </summary> /// <param name="membershipFunctionName">The membership function for which fuzzify the variable.</param> /// <returns>The degree of membership.</returns> public double Fuzzify(string membershipFunctionName) { MembershipFunction membershipFunction = this.membershipFunctionCollection.Find(membershipFunctionName); if ((membershipFunction.X0 <= this.InputValue) && (this.InputValue < membershipFunction.X1)) { return((this.InputValue - membershipFunction.X0) / (membershipFunction.X1 - membershipFunction.X0)); } else if ((membershipFunction.X1 <= this.InputValue) && (this.InputValue <= membershipFunction.X2)) { return(1); } else if ((membershipFunction.X2 < this.InputValue) && (this.InputValue <= membershipFunction.X3)) { return((membershipFunction.X3 - this.InputValue) / (membershipFunction.X3 - membershipFunction.X2)); } else { return(0); } }
/// <summary> /// Compute Activation of membership function. /// </summary> public void ComputeActivation(double activation) { if (Double.IsNaN(activation)) { throw new Exception("ComputeActivation: LinguisticVariable " + lvar.Name + " Activation is NaN !"); } activated_pointCollection.Clear(); if (Double.IsNaN(lvar.Range_min)) { throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Range_min is NaN !"); } if (Double.IsNaN(lvar.Range_max)) { throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Range_max is NaN !"); } this.Act_value = activation; bool first = true; Point previous = null; double rise; double run; double slope; double dist; activated_pointCollection.Clear(); foreach (Point pnt in this.pointCollection) { if (Double.IsNaN(pnt.P1_val)) { throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Membership Function " + this.Name + " Point.P1_val is NaN !"); } if (Double.IsNaN(pnt.P2_val)) { throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Membership Function " + this.Name + " Point.P2_val is NaN !"); } if (first) { if (pnt.P2_val > 0 && pnt.P1_val > lvar.Range_min) { Point start = new Point(lvar.Range_min, Math.Min(pnt.P2_val, activation)); activated_pointCollection.Add(start); } activated_pointCollection.Add(pnt.ClonePoint(activation)); } else // not first { rise = Math.Abs(pnt.P2_val - previous.P2_val); run = Math.Abs(pnt.P1_val - previous.P1_val); if ((activation == 0) || // activation == 0 (run == 0) || // pnt.P1_val == previous.P1_val (rise == 0)) // no slope { activated_pointCollection.Add(pnt.ClonePoint(activation)); } else if (previous.P2_val <= activation && pnt.P2_val <= activation) // both <= activation { activated_pointCollection.Add(pnt.ClonePoint(activation)); } else if (previous.P2_val > activation && pnt.P2_val > activation) // both > activation { activated_pointCollection.Add(pnt.ClonePoint(activation)); } else if (previous.P2_val <= activation) // previous below, pnt above activation { slope = rise / run; dist = (activation - previous.P2_val) / slope; Point intersect = new Point(previous.P1_val + dist, activation); activated_pointCollection.Add(intersect); activated_pointCollection.Add(pnt.ClonePoint(activation)); } else // previous above, pnt below activation { slope = rise / run; dist = (activation - pnt.P2_val) / slope; Point intersect = new Point(pnt.P1_val - dist, activation); activated_pointCollection.Add(intersect); activated_pointCollection.Add(pnt.ClonePoint(activation)); } } first = false; previous = pnt; } if (previous.P2_val > 0 && previous.P1_val < lvar.Range_max) { Point last = new Point(lvar.Range_max, Math.Min(previous.P2_val, activation)); activated_pointCollection.Add(last); } Console.WriteLine("ComputeActivation: LinguisticVariable " + lvar.Name + " Membership Function " + this.Name + " Point.Count=" + activated_pointCollection.Count + " activation=" + activation); MembershipFunction mfunc = this; this.activated_pointCollection.ComputeArea(ref lvar, ref mfunc); }
/// <summary> /// Accumulate the results of Membership functions. /// </summary> public void Accumulate() { Console.WriteLine("Accumulate: lvar = " + this.Name); double previousLoc = Double.NegativeInfinity; double location; int index; int index2; int prevMfunc = -1; int mfuncIndex = -1; bool finished = false; index2 = 0; this.accumulation.Clear(); foreach (MembershipFunction mfunc in this.MembershipFunctionCollection) { mfunc.index = index2++; index = 0; foreach (Point pnt in mfunc.activated_pointCollection) { pnt.index = index++; } } while (previousLoc < this.Range_max) { location = Double.PositiveInfinity; finished = false; while (!finished) { foreach (MembershipFunction mfunc in this.MembershipFunctionCollection) { finished = true; if (mfunc.Act_value > 0) { foreach (Point pnt in mfunc.activated_pointCollection) { if (pnt.P1_val >= location) { break; } if (pnt.P1_val > previousLoc) { location = pnt.P1_val; mfunc.pntIndex = pnt.index; finished = false; break; } } } } } double maximum = Double.NegativeInfinity; foreach (MembershipFunction mfunc in this.MembershipFunctionCollection) { if (mfunc.Act_value == 0) { continue; } if (mfunc.activated_pointCollection.Count == 0) { continue; } double value = mfunc.FindValue(ref mfunc.activated_pointCollection, location); if (value >= maximum) { maximum = Math.Round(value, 6); mfuncIndex = mfunc.index; mfunc.pntIndex = mfunc.loc1; if (prevMfunc < 0) { prevMfunc = mfuncIndex; } } } if (prevMfunc < 0) { throw new Exception("Accumulate: LinguisticVariable " + this.Name + " All MembershipFunction.Act_value == 0 !"); } if (mfuncIndex != prevMfunc) // Intersection { MembershipFunction mfunc = this.membershipFunctionCollection[mfuncIndex]; MembershipFunction mfunc2 = this.membershipFunctionCollection[prevMfunc]; Point thePoint = mfunc.activated_pointCollection[mfunc.pntIndex]; Point thePoint2 = mfunc2.activated_pointCollection[mfunc2.pntIndex]; if (mfunc.pntIndex == 0) // first point { if (location > previousLoc) { this.accumulation.Add(new Point(location, maximum)); } } else if (mfunc2.pntIndex == mfunc2.activated_pointCollection.Count - 1) // last point { if (location > previousLoc) { this.accumulation.Add(new Point(location, maximum)); } } else // get Intersection { Point thePoint1 = mfunc.activated_pointCollection[mfunc.pntIndex - 1]; Point thePoint3 = (mfunc2.pntIndex == 0) ? mfunc2.activated_pointCollection[mfunc2.pntIndex + 1] : mfunc2.activated_pointCollection[mfunc2.pntIndex - 1]; double run = Math.Abs(thePoint.P1_val - thePoint1.P1_val); double run2 = Math.Abs(thePoint3.P1_val - thePoint2.P1_val); double rise = thePoint.P2_val - thePoint1.P2_val; double rise2 = thePoint3.P2_val - thePoint2.P2_val; if (run == 0 || run2 == 0 || rise2 == 0) { if (location > previousLoc) { this.accumulation.Add(new Point(location, Math.Max(thePoint.P2_val, thePoint1.P2_val))); } } else { double x1 = thePoint2.P1_val; double x2 = thePoint3.P1_val; double x3 = thePoint1.P1_val; double x4 = thePoint.P1_val; double y1 = thePoint2.P2_val; double y2 = thePoint3.P2_val; double y3 = thePoint1.P2_val; double y4 = thePoint.P2_val; double num1 = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4); double num2 = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4); double den1 = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); double den2 = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); if (den1 == 0 || den2 == 0) { throw new Exception("Accumulate: Intersection is Undefined !"); } location = Math.Round(num1 / den1, 6); maximum = Math.Round(num2 / den1, 6); if (location > previousLoc) { this.accumulation.Add(new Point(location, maximum)); } } } } else // no Intersection { if (location > previousLoc) { this.accumulation.Add(new Point(location, maximum)); } } prevMfunc = mfuncIndex; previousLoc = location; } }
/// <summary> /// Compute Area of membership function. /// </summary> public double ComputeArea(ref LinguisticVariable lvar, ref MembershipFunction mfunc) { double area = 0; if (Double.IsNaN(lvar.Range_min)) { throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Range_min is NaN !"); } if (Double.IsNaN(lvar.Range_max)) { throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Range_max is NaN !"); } bool first = true; bool extend = false; bool extend2 = false; Point previous = null; double rise; double run; foreach (Point pnt in this) { if (Double.IsNaN(pnt.P1_val)) { throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Membership Function " + ((Object.ReferenceEquals(mfunc, null)) ? "" : mfunc.Name) + " Point.P1_val is NaN !"); } if (Double.IsNaN(pnt.P2_val)) { throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Membership Function " + ((Object.ReferenceEquals(mfunc, null)) ? "" : mfunc.Name) + " Point.P2_val is NaN !"); } if (first) { if (pnt.P2_val > 0) { area += Math.Abs(pnt.P1_val - lvar.Range_min) * pnt.P2_val; // extend area to min if (!Object.ReferenceEquals(mfunc, null)) { extend = true; } } } else // not first { run = Math.Abs(pnt.P1_val - previous.P1_val); if (run > 0) { rise = Math.Abs(pnt.P2_val - previous.P2_val); if (rise == 0) // equal { area += pnt.P2_val * run; // rectangle } else { area += Math.Min(pnt.P2_val, previous.P2_val) * run; // base area += rise * run / 2; // triangle } } } first = false; previous = pnt; } // foreach pnt if (previous.P1_val <= lvar.Range_max) { if (previous.P2_val > 0) { area += Math.Abs(previous.P1_val - lvar.Range_max) * previous.P2_val; // extend area to Range_max if (!Object.ReferenceEquals(mfunc, null)) { extend2 = true; } } } if (!Object.ReferenceEquals(mfunc, null)) { if ((extend || extend2) && lvar.Method == "COG_EXTEND") { mfunc.addArea = area; // Additional area Console.WriteLine("ComputeArea: LinguisticVariable " + lvar.Name + " Membership Function " + mfunc.Name + " addArea=" + area); if (extend) { lvar.addArea = area; } else { lvar.addArea2 = area; } } } Console.WriteLine("ComputeArea: LinguisticVariable " + lvar.Name + " Membership Function " + ((Object.ReferenceEquals(mfunc, null)) ? "" : mfunc.Name) + " Area=" + area); return(area); }