/// <summary> /// Returns the degree of membership in this set of the given value. This does not set /// <see cref="FuzzySet._dom" /> to the degree of membership of the value passed as the /// parameter. This is because the centroid defuzzification method also uses this method to /// determine the DOMs of the values it uses as its sample points. /// </summary> /// <param name="givenValue">The given value.</param> /// <returns> /// The degree of membership in this set of the given value. /// </returns> public override float CalculateDom(float givenValue) { // test for the case where the left or right offsets are zero // (to prevent divide by zero errors below) if (Epsilon.IsEqual(RightOffset, 0.0f) && Epsilon.IsEqual(PeakPoint, givenValue) || Epsilon.IsEqual(LeftOffset, 0.0f) && Epsilon.IsEqual(PeakPoint, givenValue)) { return(1.0f); } // find DOM if left of center if (givenValue <= PeakPoint && givenValue > PeakPoint - LeftOffset) { var grad = 1.0f / LeftOffset; return(grad * (givenValue - (PeakPoint - LeftOffset))); } // find DOM if right of center and less than center + right offset if (givenValue > PeakPoint && givenValue <= PeakPoint + RightOffset) { return(1.0f); } // out of range of this FLV, return zero return(0f); }
/// <summary> /// Returns the degree of membership in this set of the given value. This does not set /// <see cref="FuzzySet._dom" /> to the degree of membership of the value passed as the /// parameter. This is because the centroid defuzzification method also uses this method to /// determine the DOMs of the values it uses as its sample points. /// </summary> /// <param name="givenValue">The given value.</param> /// <returns> /// The degree of membership in this set of the given value. /// </returns> public override float CalculateDom(float givenValue) { // test for the case where the triangle's left or right offsets are // zero (to prevent divide by zero errors below) if (Epsilon.IsEqual(RightOffset, 0.0f) && Epsilon.IsEqual(PeakPoint, givenValue) || Epsilon.IsEqual(LeftOffset, 0.0f) && Epsilon.IsEqual(PeakPoint, givenValue)) { return(1.0f); } // find DOM if left of center if (givenValue <= PeakPoint && givenValue >= PeakPoint - LeftOffset) { var leftGrad = 1.0f / LeftOffset; return(leftGrad * (givenValue - (PeakPoint - LeftOffset))); } // find DOM if right of center if (!(givenValue > PeakPoint) || !(givenValue < PeakPoint + RightOffset)) { return(0.0f); } var rightGrad = 1.0f / -RightOffset; return(rightGrad * (givenValue - PeakPoint) + 1.0f); // out of range of this FLV, return zero }
/// <summary> /// Defuzzify the variable using the centroid method. /// </summary> /// <param name="sampleCount">The number of samples to use.</param> /// <returns>A crisp value.</returns> public float DeFuzzifyCentroid(int sampleCount) { // calculate the step size var stepSize = (MaxRange - MinRange) / sampleCount; var totalArea = 0.0f; var sumOfMoments = 0.0f; // step through the range of this variable in increments equal to // stepSize adding up the contribution (lower of CalculateDOM or // the actual DOM of this variable's fuzzified value) for each // subset. This gives an approximation of the total area of the // fuzzy manifold. (This is similar to how the area under a curve // is calculated using calculus... the heights of lots of 'slices' // are summed to give the total area.) // // In addition the moment of each slice is calculated and summed. // Dividing the total area by the sum of the moments gives the // centroid. (Just like calculating the center of mass of an object) for (var sample = 1; sample <= sampleCount; ++sample) // for each set get the contribution to the area. This is the // lower of the value returned from CalculateDOM or the actual // DOM of the fuzzified value itself { foreach (var kvp in MemberSets) { var contribution = Mathf.Min( kvp.Value.CalculateDom(MinRange + sample * stepSize), kvp.Value.Dom); totalArea += contribution; sumOfMoments += (MinRange + sample * stepSize) * contribution; } } // make sure total area is not equal to zero if (Epsilon.IsEqual(0, totalArea)) { return(0.0f); } return(sumOfMoments / totalArea); }
/// <summary> /// Defuzzifies the value by averaging the maxima of the sets that have fired. /// </summary> /// <returns>Sum (maxima * DOM) / sum (DOMs).</returns> public float DeFuzzifyMaxAv() { var bottom = 0.0f; var top = 0.0f; foreach (var kvp in MemberSets) { bottom += kvp.Value.Dom; top += kvp.Value.RepresentativeValue * kvp.Value.Dom; } // make sure bottom is not equal to zero if (Epsilon.IsEqual(0, bottom)) { return(0.0f); } return(top / bottom); }
public static bool EQ(this float a, float b) { return(e.IsEqual(a, b)); }
public static bool EQ(this double a, double b) { return(e.IsEqual(a, b)); }
public static bool EQ(this double a, double b, Epsilon e) { return e.IsEqual (a, b); }
public static bool GE(this double a, double b) { return(Epsilon.IsEqual(a, b) || (a > b)); }
public static bool LE(this double a, double b, Epsilon e) { return(e.IsEqual(a, b) || (a < b)); }
private static bool EQ(this double a, double b, Epsilon e) { return(e.IsEqual(a, b)); }