Click here to Skip to main content
15,896,484 members
Articles / Programming Languages / C#

Fuzzy Framework

Rate me:
Please Sign up or sign in to vote.
4.93/5 (107 votes)
27 Jan 2011CPOL26 min read 140.2K   12.5K   185  
In the following article, we briefly introduce Fuzzy Framework library which supports calculations based on fuzzy logic in .NET.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FuzzyFramework.Dimensions;
using FuzzyFramework.Intervals;
using PolyLib;

namespace FuzzyFramework.Defuzzification
{
    public class CenterOfGravity : Defuzzification
    {
        /// <summary>
        /// Defuzzifies the output set using defuzzifioncation method Center-Of-Gravity
        /// </summary>
        public CenterOfGravity(FuzzyRelation relation, Dictionary<IDimension, System.Decimal> inputs)
            : base(relation, inputs)
        {
        }
        
        public override decimal CrispValue
        {
            get
            {
                IntervalSet functionCourse = Relation.GetFunction(this._inputs, this._outputDimension);
                
                decimal[] areaOffsets = new decimal[functionCourse.Intervals.Length];
                decimal[] areas = new decimal[functionCourse.Intervals.Length];
                decimal areaOffset = 0;

                for (uint i = 0; i < functionCourse.Intervals.Length; i++)
                {
                    areaOffsets[i] = areaOffset;
                    areas[i] = functionCourse.Intervals[i].Area;
                    areaOffset += areas[i];
                }

                decimal centreOfGravity = areaOffset / 2;

                for (uint i = 0; i < functionCourse.Intervals.Length; i++)
                {
                    if (i<(functionCourse.Intervals.Length-1) && areaOffsets[i] == centreOfGravity && areaOffsets[i + 1] == centreOfGravity)
                        return (functionCourse.Intervals[i].UpperBound + functionCourse.Intervals[i + 1].LowerBound) / 2;

                    if (
                            (i < (functionCourse.Intervals.Length-1) && areaOffsets[i] <= centreOfGravity && areaOffsets[i + 1] >= centreOfGravity)
                            ||
                            (i == (functionCourse.Intervals.Length-1) && areaOffsets[i] <= centreOfGravity )
                        )
                    {
                        //What is the area we still have to "cut" from the selected interval?
                        decimal remainingArea = centreOfGravity - areaOffsets[i];
                        //take the integral
                        Polynomial integral = Polynomial.Integral(functionCourse.Intervals[i].Polynomial);
                        decimal startPoint = (decimal) integral.Evaluate( new Complex( (double) functionCourse.Intervals[i].LowerBound)).Re;
                        decimal endPoint = (decimal)integral.Evaluate(new Complex((double)functionCourse.Intervals[i].UpperBound)).Re;
                        if (Math.Round(remainingArea,5) > Math.Round(endPoint - startPoint,5)) throw new ApplicationException("Unexpected behaviour 1");
                        Polynomial difference = integral - new Polynomial(new Complex((double)(startPoint + remainingArea))); 
                        //solve the equation
                        decimal[] roots = Interval.RealRoots(difference, functionCourse.Intervals[i].LowerBound, functionCourse.Intervals[i].UpperBound);
                        
                        if (roots.Length == 0)
                        { //no area at all
                            IContinuousDimension dim = (IContinuousDimension) this._outputDimension;
                            return (dim.MinValue + dim.MaxValue) / 2;
                        }
                        
                        if (roots.Length != 1)
                            throw new ApplicationException("Unexpected behaviour 2");

                        return roots[0];

                    }
                }

                throw new ApplicationException("Unexpected behaviour 3");

            }
        }

        /// <summary>
        /// Returns the membership degree at the point of the horizontal centre of gravity. Another possibility is to implement this property as the vertical centre of gravity. This would require an integral of inverse function.
        /// </summary>
        public override double MembershipDegree
        {
            get
            {
                IntervalSet functionCourse = Relation.GetFunction(this._inputs, this._outputDimension);
                decimal crispValue = this.CrispValue;
                Interval? t = functionCourse.GetSubinterval(crispValue, crispValue);
                if (!t.HasValue) throw new ApplicationException("Unexpected behaviour 4");
                return t.Value.GetMembershipDegree(crispValue);

            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Student
Czech Republic Czech Republic
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions