Tour of Fuzzy Logic Functions

Creating Fuzzy sets and relations

Sets

In order to work with fuzzy logic, we start by creating an object which describes a fuzzy definition of truth. These definitions work on discrete values in a finite range. So let's set the range in which we are working.

<< FuzzyLogic`

SetOptions[FuzzySet, UniversalSpace -> {0, 50}];

The simplest way to create a fuzzy variable is with FuzzyTrapezoid. You give it the first value at which truth is non-zero, the value at which it reaches maximum, the value at which it starts to become not true and the last value where it has any truth.

fz = FuzzyTrapezoid[0, 29, 36, 40]

The result is a list of values and the level of membership in the set from 0 to 1. We can visualize this.

FuzzyPlot[fz];

Another way to create fuzzy sets is with FuzzyGaussian.

FuzzyPlot[fz2 = FuzzyGaussian[8, 3]];

We are also able to make arbitrary fuzzy sets from functions or from individually chosen values.

Relations

There is also support for fuzzy relations where the level of truth is dependand on two input variables

fzrel = 
      FuzzyTrapezoid[{1, 2, 3, 4}, {5, 7, 8, 15}, 
        UniversalSpace -> {{0, 20}, {0, 20}}]

FuzzySurfacePlot[fzrel, UniversalSpace -> {{0, 20}, {0, 20}}];

Partitioning the universal space

There is also a quick method for dividing the universal space into overlapping fuzzy variables. Here we divide it into 5 sets, each with a Gaussian distribution. We can see that 9 can be considered to be very much in the blue set and only slightly a member of the red set.

FuzzyPlot[CreateFuzzySets[5, Type -> Gaussian[4]], 
      PlotJoined -> True];

Modifying fuzzy sets

Having created our fuzzy sets, we can then modify them to form new fuzzy sets.

Concentrate

Concentrate modifies the set to behave more like a traditional logic set, changing more rapidly from True to False.

FuzzyPlot[fz, Concentrate[fz], PlotJoined -> True];

Dilate

Conversely, Dilate makes a fuzzy set which is more fuzzy than the original. It changes more slowly between True and False.

FuzzyPlot[fz, Dilate[fz], PlotJoined -> True];

Users can also write their own modifier functions.

Defuzzification

If we are going to use fuzzy sets to make decisions then ultimately getting fuzzy answers is no help to us. We need to be able to convert from a fuzzy answer to an actual number. There are several ways to do this.

Center of area

CenterOfArea takes a weighted average of the points which are members of the set. 1/m in effect, the center-of-gravity of the graph.

CenterOfArea[fz, ShowGraph -> True];

Mean of maximum

Another method is to take only those points which have a maximum membership grade and take the average of those.

MeanOfMax[fz, ShowGraph -> True]

ALPHALevelSet

A related function is AlphaLevelSet which finds all the values of the fuzzy set whose membership grades exceed some value.

AlphaLevelSet[fz, 0.8]

Again, users can write any function they want to convert from fuzzy sets to values.

Aggregation

Having created and tailored our fuzzy sets and having a method to convert back from them, we now need to look at the other traditional logic operations.

Intersection ≈ And

The closest equivalent of an And operation to combine two sets is Intersection.

FuzzyPlot[fz, fz2, PlotJoined -> True];

FuzzyPlot[Intersection[fz, fz2], PlotJoined -> True];

Here the result is only considered in the set to the extent that it was in both input sets. The default is to take the Min of the two sets, but there are a whole range of alternative methods and the usercan define their own.

FuzzyPlot[Intersection[fz, fz2, Type -> Hamacher[20]], 
        PlotJoined -> True];

Union ≈ Or

The equivalent of Or is Union. The default here is to take the Max of the two sets

FuzzyPlot[Union[fz, fz2], PlotJoined -> True];

But again there are many alternative ways to do this.

FuzzyPlot[Union[fz, fz2, Type -> Hamacher[200]], PlotJoined -> True];

Difference ≈ Xor

Difference can perhaps be considered an equivalent to Xor.

FuzzyPlot[Difference[fz, fz2], PlotJoined -> True];

Inferencing

Inferencing ≈ If

Inferencing is making decisions based on fuzzy sets and so is perhaps an equivalent to If in logic. To show this we will look at an involved example. Here is a truck in a 100m  × 100m yard which must reverse to a bay at {50,100} and attempt also to be perpendicular at that point. We do not know any solution equations but come equipped with basic knowledge about how we would steer in different circumstances.

Define Linguistic Terms

Before we can start solving the problem, we must define the linguistic terms which we use in our description of how to steer.

Truck position relative to target

SetOptions[FuzzySet, UniversalSpace -> {0, 100}];

Following are our terms for the left-right positioning of the truck. For example, anywhere between 0 and 10m can be considered on the far left of the yard.

\(FarLeft = FuzzyTrapezoid[0, 0, 10, 35]; 

    LeftOfCentre = FuzzyTrapezoid[30, 40, 40, 50]; 

    AtCentre = FuzzyTrapezoid[45, 50, 50, 55]; 

    RightOfCentre = FuzzyTrapezoid[50, 60, 60, 70]; 

    FarRight = FuzzyTrapezoid[65, 90, 100, 100]; \)

TruckPosition = {FarLeft, LeftOfCentre, AtCentre, RightOfCentre, 
        FarRight};

Here are all our positioning terms. We can see that 55m can be equally considered AtCenter or RightOfCenter.

FuzzyPlot[TruckPosition, PlotJoined -> True];

Truck orientation

We do exactly the same for the linguistic terms that we use to describe the angle which the truck is facing.

SetOptions[FuzzySet, UniversalSpace -> {-90, 270}];

\(RightBelow = 
      FuzzyTrapezoid[\(-90\), \(-45\), \(-45\), 9] ⋃ 
        FuzzySet[{{\(-90\),  .1}}]; 

    RightUpper = FuzzyTrapezoid[\(-9\), 23, 23, 54]; 

    RightVertical = FuzzyTrapezoid[36, 63, 63, 90]; 

    Vertical = FuzzyTrapezoid[72, 90, 90, 108]; 

    LeftVertical = FuzzyTrapezoid[90, 117, 117, 144]; 

    LeftUpper = FuzzyTrapezoid[126, 157, 157, 189]; 

    LeftBelow = 
      FuzzyTrapezoid[171, 225, 225, 270] ⋃ FuzzySet[{{270,  .1}}]; 
    \)

Angle = {RightBelow, RightUpper, RightVertical, Vertical, 
        LeftVertical, LeftUpper, LeftBelow};

FuzzyPlot[Angle, PlotJoined -> True];

Truck steering angle

And again we define terms for describing the angle that the steering wheel is set at. For example, anywhere between -5° and 5° can be considered, to some extent, zero.

SetOptions[FuzzySet, UniversalSpace -> {-30, 30}];

\(NegativeBig = FuzzyTrapezoid[\(-30\), \(-30\), \(-30\), \(-15\)]; 

    NegativeMedium = FuzzyTrapezoid[\(-25\), \(-15\), \(-15\), \(-5\)]; 

    NegativeSmall = FuzzyTrapezoid[\(-12\), \(-6\), \(-6\), 0]; 

    Zero = FuzzyTrapezoid[\(-5\), 0, 0, 5]; 

    PositiveSmall = FuzzyTrapezoid[0, 6, 6, 12]; 

    PositiveMedium = FuzzyTrapezoid[5, 15, 15, 25]; 

    PositiveBig = FuzzyTrapezoid[15, 30, 30, 30]; \)

SteeringAngle = {NegativeBig, NegativeMedium, NegativeSmall, Zero, 
        PositiveSmall, PositiveMedium, PositiveBig};

FuzzyPlot[SteeringAngle, PlotJoined -> True];

Control Program

Now that we have our terms, we can consider the solution. Using our knowledge of driving, we define the rules for the solution using our linguistic terms. For example, "If the truck is on the FarLeft of the yard and angled RightBelow, then turn the steering wheel to a PositiveSmall setting". This is the intelligence of our solution.

If truck position...		and truck angle...		then steer...

ControlRules=	(({{FarLeft, RightBelow, PositiveSmall}, {LeftOfCentre, RightBelow, PositiveMedium}, {AtCentre, RightBelow, PositiveMedium}, {RightOfCentre, RightBelow, PositiveBig}, {FarRight, RightBelow, PositiveBig}, {FarLeft, RightUpper, NegativeSmall}, {LeftOfCentre, RightUpper, PositiveSmall}, {AtCentre, RightUpper, PositiveMedium}, {RightOfCentre, RightUpper, PositiveBig}, {FarRight, RightUpper, PositiveBig}, {FarLeft, RightVertical, NegativeMedium}, {LeftOfCentre, RightVertical, NegativeSmall}, {AtCentre, RightVertical, PositiveSmall}, {RightOfCentre, RightVertical, PositiveMedium}, {FarRight, RightVertical, PositiveBig}, {FarLeft, Vertical, NegativeMedium}, {LeftOfCentre, Vertical, NegativeMedium}, {AtCentre, Vertical, Zero}, {RightOfCentre, Vertical, PositiveMedium}, {FarRight, Vertical, PositiveMedium}, {FarLeft, LeftVertical, NegativeBig}, {LeftOfCentre, LeftVertical, NegativeMedium}, {AtCentre, LeftVertical, NegativeSmall}, {RightOfCentre, LeftVertical, PositiveSmall}, {FarRight, LeftVertical, PositiveMedium}, {FarLeft, LeftUpper, NegativeBig}, {LeftOfCentre, LeftUpper, NegativeBig}, {AtCentre, LeftUpper, NegativeMedium}, {RightOfCentre, LeftUpper, NegativeSmall}, {FarRight, LeftUpper, PositiveSmall}, {FarLeft, LeftBelow, NegativeBig}, {LeftOfCentre, LeftBelow, NegativeBig}, {AtCentre, LeftBelow, NegativeMedium}, {RightOfCentre, LeftBelow, NegativeMedium}, {FarRight, LeftBelow, NegativeSmall}}));

And this is the program for making decisions based on that intelligence. RuleBasedInference takes those rules and some input values and returns a decision given as a fuzzy set. CenterOfArea then converts that to a value for the steering angle. We now have a complete control program.

Steer[phi_, x_] := 
      CenterOfArea[
        RuleBasedInference[TruckPosition, Angle, SteeringAngle, ControlRules, 
          x, phi]]

Simulation Functions

If we want to see how it behaves, then we have a little more work to create a simulation. Here we repeatedly use our control program 'Steer' to decide the steering angle and then work out where the truck will actually move to until the truck reaches the top of the yard.

simulateTruck[x0_, y0_, phi0_] := 
      Module[{x = x0, y = y0, phi = phi0, newPhi, result = {}}, 
        While[y ≤ 95, newPhi = phi + Steer[phi, x]; 
          AppendTo[result, 
            {x, y, phi} = 
              N[{x + 4 Cos[((newPhi π)/180)], 
                  y + 4 Sin[((newPhi π)/180)], newPhi}]];]; result]

Visualization

And purely for the purposes of this demo, we create a graphic to show the truck's position and orientation

showTruck[{x_, y_, phi_}, {l_, w_}] := 
        Module[{s = N[Sin[((phi π)/180)]], 
            c = N[Cos[((phi π)/180)]]}, 
          Show[Graphics[
              {Hue[0.7], 
                Line[Transpose[
                    {x, y} + 
                      {{-((s w)/2), ((s w)/2), 
                          ((s w)/2) - c l, ((s w)/4) - c l, 
                          ((s w)/4) - 1.2 c l, 
                          -((s w)/4) - 1.2 c l, 
                          -((s w)/4) - c l, 
                          -((s w)/2) - c l, -((s w)/2)}, 
                        {((c w)/2), -((c w)/2), 
                          -((c w)/2) - s l, 
                          -((c w)/4) - s l, 
                          -((c w)/4) - 1.2 s l, 
                          ((c w)/4) - 1.2 s l, ((c w)/4) - s l, 
                          ((c w)/2) - s l, ((c w)/2)}}]], GrayLevel[0], 
                Line[{{0, 100}, {100, 100}}], Line[{{100, 100}, {100, 0}}], 
                Line[{{50, 100}, {50, 95}}]}, Axes -> True, 
              AspectRatio -> Automatic, 
              PlotRange -> {{0, 100}, {0, 100}}, 
              AxesOrigin -> {0, 0}]]];

Examples

Let's start the truck at {85,20} facing at 190°

simlist = simulateTruck[85, 20, 190]

Here is an animation of those positions...

graph1 = (showTruck[#1, {10, 5}] &) /@ simlist;

or the whole journey on a single picture.

Show[graph1];

We can repeat this with alternative start positions and see that it is quite robust in finding solutions.

test2 = simulateTruck[30, 20, 260];

graph2 = (showTruck[#1, {10, 5}] &) /@ test2;

Show[graph2];

Other operations on fuzzy sets

• Addition
• Subtraction
• Image
• ConstantMultiply
• Height
• RelativeCardinality