Example of the creation of a Fuzzy Value

Some of the Operations on FuzzyValues

A Comment on the Range of Membership Values

The FuzzyValue class allows one to create a specific fuzzy concept for a
given FuzzyVariable, say temperature. For example, one might want to represent
the concept *temperature is very cold*. Assuming that we have a
FuzzyVariable for temperature with the term *cold* defined, we simply
create the FuzzyValue by specifying the temperature FuzzyVariable and a *linguistic
expression *(in this case *very cold*). The expression is parsed and a
FuzzySet that mathematically defines the shape of this concept is created and stored
with the FuzzyValue. So a FuzzyValue is an association of a FuzzyVariable and a
linguistic expression to describe a fuzzy concept. Note that a FuzzyValue can
also be created using a FuzzyVariable and a FuzzySet, but it will have no
english-like expression associated with it (actually it gets the default
expression '???' that signifies that no expression composed of fuzzy terms,
modifiers and operators is available that describes the FuzzySet associated
with the FuzzyVariable). The user may choose to add a linguistic expression
string to the FuzzyValue with the setLinguisticExpression method.

The linguistic expression is formed using the terms defined for the
FuzzyVariable along with the operators *or* and *and* as well as the
set of system or user supplied modifiers such
as *very*, *not* and *slightly*. These english-like expressions
are used to describe the required fuzzy concepts for the variable. For example,
let’s consider the FuzzyVariable *temperature*, with terms *cold*, *warm*,
and *hot*. It is decided that we would like a FuzzyValue that represents
the concept "*slightly cold AND warm*" for the temperature
variable. This string is parsed, and based on the parse a suitable FuzzySet is
created for the FuzzyValue, and the linguistic expression is stored as "*slightly
cold AND warm*".

The FuzzySet in a FuzzyValue contains a set of points. This set of points is the mathematical representation of the fuzzy concept being expressed for this FuzzyValue.

The following code shows a simple example of creating a FuzzyVariable and a FuzzyValue:

`
// There are many ways to define the terms for the fuzzy variable`

`
// Here we use 2 of those methods:`

`
// 1. using two arrays of x and y values to define the shape of the
fuzzy set`

`
// 2. using already defined terms of the fuzzy variable and
linguistic`

`
// expressions`

`
double xHot[] = {25, 35};`

`
double yHot[] = {0, 1};`

`
double xCold[] = {5, 15};`

`
double yCold[] = {1, 0};`

`
FuzzyValue fval = null;`

`
...`

`
// Create a new fuzzy variable for temperature with Universe of discourse`

`
// from 0 to 100 and units "C".`

`
FuzzyVariable temp = new FuzzyVariable("temperature", 0, 100,
"C");`

`
...`

`
// Add three terms hot, cold and medium`

`
temp.addTerm("hot", xHot, yHot, 2);`

`
temp.addTerm("cold", xCold, yCold, 2);`

`
// Note: once a term is added it can be used to define other terms`

`
temp.addTerm("medium", "not hot and not cold");`

`
...`

`
// Now we can define fuzzy values using the terms in the fuzzy variable.`

`
// Note: fuzzy values can also be created using fuzzy sets, etc and not`

`
// just with linguistic expressions.`

`
fval = new FuzzyValue(temp, "very hot or cold");`

`
System.out.println(fval);`

The output from this would be:

` FuzzyVariable
-> temperature [ 0.0, 100.0 ] C`

` Linguistic
Expression -> very hot or cold`

` FuzzySet
-> { 1/5 0/15 0/25 0.01/26 0.04/27 0.09/28 0.16/29 0.25/30`

`
0.36/31 0.49/32 0.64/33 0.81/34 1/35 }`

After this has been done we will have defined a fuzzy variable that has the 3 terms hot, cold and medium defined and shown below graphically.

The fuzzy value that we created, *temperature is very hot or cold*, will
have a physical depiction as follows:

The API
documentation describes a large number of operations and manipulations that
can be applied to FuzzyValues. Most often there is a corresponding capability
for FuzzySets with the restriction that the UOD (universe of discourse) must be
observed for the FuzzyValues and for binary operations, such as intersection
and union, the two FuzzyValues __must__ have the same FuzzyVariable.

The UOD defines the range of x values that are allowed for
the FuzzySets that are used when defining a FuzzyValue. If one tries to
associate a FuzzySet with a FuzzyValue and any of the x values are outside of
this range then an exception is raised. A rather specific case might be when
one **fuzzifies** a crisp value, creating a FuzzyValue. Assuming that we use
a simple TriangleFuzzySet or a PIFuzzySet it would be possible for all or some
of this fuzzy set to lie outside of the UOD bounds. Since this would cause an
exception one would have to do some special coding to handle the cases where
the value is close to the upper or lower bounds. Instead it is possible to use
the static method setConfineFuzzySetsToUOD of the FuzzyValue class to
automatically adjust the fuzzy set by ‘clipping’ it at the x boundaries so that
it does not have values outside the bounds. A bit of code that might be useful
for fuzzifying a crisp value is:

`
// Create new fuzzy variable for temperature with Universe of discourse`

`
// from 0 to 100 and units "C".`

`
FuzzyVariable temp = new FuzzyVariable("temperature", 0, 100,
"C");`

`
...`

`
// Now we define fuzzify a crisp value` that would normally generate
an exception

FuzzyValue.setConfineFuzzySetsToUOD(true);

`
FuzzyValue fval = new FuzzyValue(temp, new TriangleFuzzySet(0.0, 0.1));`

The triangular fuzzy set is one centered on 0.0 with a width
of 0.1. This is one way of representing the imprecision or error bounds for a
temperature reading from a sensor. Even though the crisp temperature value is
within bounds, the fuzzified value is not. We have a FuzzySet where the point
(-0.05, 0) is outside of the UOD for the FuzzyValue. However, by using
setConfineFuzzySetsToUOD method the system will *clip* the fuzzy set to
remove the parts that would lie outside of the UOD. In this case it is
equivalent to creating a fuzzy set for the fuzzy value defined by the points
(0.0, 0.0), (0.0, 1.0) and (0.05, 0.0).

It is required that binary operations on two FuzzyValues be
restricted to FuzzyValues that share the **same** FuzzyVariable instance
because it doesn’t make sense to do a union or intersection of a Temperature
FuzzyValue and a Pressure FuzzyValue. This would have no meaning (like adding
apples and oranges).

Getting back to the operations defined for FuzzyValues we describe some of the most commonly used operations:

**fuzzyComplement**

Takes the compliment of a FuzzyValue. More specifically, it takes the
compliment of the membership (y) values of the SetPoints of the FuzzySet
associated with the FuzzyValue. Mathematically (NOT), u(x) = 1 - u(x) for all x
values, or y = 1 – y for all y values.

**fuzzyIntersection**

Returns the intersection of two FuzzyValues. More specifically it operates on
the FuzzySets associated with the FuzzyValues. The visual representation of the
intersection of two example FuzzySets is depicted below. One set is black with
green SetPoints, and the other set is grey with orange SetPoints. The diagram
on the left is of the two FuzzySets, and the diagram on the right is of the two
sets overlaid by the intersection set in red. Intersection is synonymous with
the logical operator AND. The intersection of two fuzzy sets is (often and
specifically in FuzzyJ) defined such that the membership (y) value at any x
value is the minimum of the membership values of the two fuzzy sets.

**fuzzyUnion**

Returns the union of two FuzzyValues. More specifically it operates on the
FuzzySets associated with the FuzzyValues. The visual representation of the
union of two example FuzzySets is depicted below. One set is black with green SetPoints,
and the other set is grey with orange SetPoints. The diagram on the left is of
the two FuzzySets, and the diagram on the right is of the two sets overlaid by
the union set in red. Union is synonymous with the logical operator OR. The
union of two fuzzy sets is (often and specifically in FuzzyJ) defined such that
the membership (y) value at any x value is the maximum of the membership values
of the two fuzzy sets.

**maximumOfIntersection**

Returns the maximum membership value on the intersection of this FuzzyValue
with the FuzzyValue argument. More specifically it operates on the FuzzySets
associated with the FuzzyValues. Consider the two diagrams below. On the right
appears a diagram of two sets, one set in black with green SetPoints, and the
other set in grey with orange SetPoints. The maximum y value of the
intersection is denoted by a red dot on the graph on the right.

**Some Defuzzification Operations on FuzzyValues**

Below are some methods that convert a FuzzyValue back into a single crisp
(non-fuzzy) value. This is something that is normally done after a fuzzy
decision has been made and the fuzzy result must be used in the real world. For
example, if the final fuzzy decision were to adjust the temperature setting on
the thermostat a ‘little higher’, then it would be necessary to convert this
‘little higher’ fuzzy value to the ‘best’ crisp value to actually move the
thermostat setting by some real amount.

**maximumDefuzzify**

Finds the mean of the maximum values of the FuzzySet of the FuzzyValue as the
defuzzification value. NOTE: This doesn't always work well because there can be
x ranges where the y value is constant at the max value and other places where
the max is only reached for a single x value. When this happens the single
value gets too much of a say in the defuzzified value.

**momentDefuzzify**

Moment defuzzification defuzzifies the FuzzySet of the FuzzyValue returning a
floating point (double value) that represents the fuzzy set. It calculates the first
moment of the area of a fuzzy set about the y axis. The set is subdivided into
different shapes by partitioning vertically at each point in the set, resulting
in rectangles, triangles, and trapezoids. The centre of gravity (moment) and
area of each subdivision is calculated using the appropriate formulas for
each shape. The first moment of area of the whole set is then:

where x_{i}´ is the local centre of gravity, A_{i} is the local
area of the shape underneath line segment (p_{i-1}, p_{i}), and
n is the total number of points. As an example,

For each shaded subsection in the diagram above, the area and centre of gravity
is calculated according to the shape identified (i.e., triangle, rectangle or
trapezoid). The centre of gravity of the whole set is then determined:

**weightedAverageDefuzzify (new in version 1.3)**

Finds the weighted average of the x values of the points that define a fuzzy set using the membership values of the points as the weights. This value is returned as the defuzzification value. For example, if we have the following fuzzy set definition:

Then the weighted average value of the fuzzy set points will be:

(1.0*0.9 + 4.0*1.0) / (0.9 + 1.0) = 2.579

This is only moderately useful since the value at 1.0 has too much influence
on the defuzzified result. The moment defuzzification is probably most useful in
this case. However, a place where this defuzzification method is very useful is
when the fuzzy set is in fact a series of singleton values. It might be that a
set of rules is of the Takagi-Sugeno-Kang type (1^{st} order) with
formats like:

If x is A and y is B then c = k

where x and y are fuzzy variables and k is a constant that is represented by a singleton fuzzy set. For example we might have rules that look like:

If temperature is low and pressure is low then set hot valve to medium_high position

If temperature is high and pressure is high then set hot valve to medium_low position

**. . .**

where the setting of the hot valve has several possibilities, say full_closed, low, medium_low, medium_high, high and full_open, and these are singleton values rather than normal fuzzy sets. In this case medium_low might be 2 on a scale from 0 to 5.

An aggregated conclusion for setting the hot valve position (after all of the rules have contributed to the decision) might look like:

And the weighted average defuzzification value for this output would be:

(1.0*0.25 + 2.0*1.0 + 3.0*0.5 + 4.0*0.5) / (0.25 + 1.0 + 0.5 + 0.5) = 2.556

Note that neither a maximum defuzzification nor a moment defuzzification would produce a useful result in this situation. The maximum version would use only 1 of the points (the maximum one) giving a result of 2.0 (the x value of that point), while the moment version would not find any area to work with and would generate an exception. This description of the weightedAverageDefuzzify method will be clearer after you have completed the section on FuzzyRules.

**fuzzyMatch**

Determine if two FuzzyValues *match* or intersect with a membership of at
least that specified by the FuzzyValue class variable matchThreshold. This is
used primarily in rules to determine if an input fuzzy value matches with a
corresponding antecedent. If all patterns in the rule match to a degree at
least as large as the matchThreshold, then the rule will fire.

**getLinguisticExpression**

Returns the String which represents the linguistic expression of this
FuzzyValue.

**getMaxUOD, getMinUOD**

Returns the x value which represents the maximum (minimum) x value in the
Universe of Discourse of the FuzzyVariable to which this FuzzyValue belongs.

**getMaxY, getMinY**

Returns the maximum (minimum) membership value of the FuzzyValue.

**similarity**

Calculates the similarity measure of two fuzzy sets Given two fuzzy values, f1
and f2, similarity is defined as:

`
similarity = if necessity(f1,f2) > 0.5`

`
then possibility(f1,f2)`

`
else (necessity(f1,f2) + 0.5) * possibility(f1,f2)`

`
and`

`
necessity(f1,f2) = 1 - possibility(not f1,f2)`

`
and`

`
possibility(f1,f2) = max _{x}(min(u_{f1}(x),u_{f2}(x))`

Note that the two fuzzy values must have the same FuzzyVariable.

Below is a grapical example of the calcualtion of similarity of 2 fuzzy values.

First we have 2 fuzzy values to compare for similarity.

necessity(f1, f2) = 1 - possibility(not f1, f2) = 1 - 0.75 = 0.25

possibility(f1, f2) = 0.9

Finally since necessity is less than 0.5,

similarity(f1,f2) = (necessity(f1,f2) + 0.5) *
possibility(f1,f2) = (0.25+0.5) * 0.9 = 0.675

Many other useful methods are available. Check the toolkit
API documentation.

Although
the range of allowed membership values is normally [0, 1], it is possible to
form FuzzySets with membership values > 1.0. There are instances where this
is desirable. For example in some approaches it is preferred to collect the
outputs of fuzzy rules by doing a **fuzzySum** of the resultant FuzzyValues
(global contribution of rules). The fuzzySum operation can result in FuzzySets
with membership values > 1.0. When a FuzzySet/FuzzyValue is created with a
constructor (that uses arrays of Doubles or an array of SetPoints) the values
are restricted to being between 0 and 1. However, when the fuzzySum operation
or the methods appendSetPoint and insertSetPoint are used to add points to the
FuzzySet, membership values > 1 are allowed.

This does have some implications of which the user needs to be aware. For example, the fuzzyComplement operation on a FuzzySet will treat membership values > 1 as if they were 1. It may be desirable at certain times to normalize (or scale) FuzzySets that have membership values > 1.

Do note that membership values are always restricted to values >= 0. In most cases the negative value is simply changed to a value of 0.

A case where a user might want to allow this to happen is when one wants to use the SAM (Standard Additive Model) method as described in Bart Kosko’s book, Fuzzy Engineering (see reference section). In this case, the collection of fuzzy outputs from multiple rules (global contribution) is done by adding (a fuzzySum of) the outputs. The resultant sum is then defuzzified using the momentDefuzzify method to give the required result. In order to completely perform the SAM method one would also need to ensure that the RuleExecutor was set to be a MamdaniMinMaxMinRuleExecutor and that the operator used to collect the results from multiple antecedents in a rule was the ProductAntecedentCombineOperator. This is explained in more detail elsewhere.