Introduction to Fuzzy Logic and Fuzzy Sets

Introduction to Fuzzy Logic

Classical logic is based on binary logic with two values of truth.  In Maple, these two values are true  and false .
Fuzzy logic is a multivalued logic with truth represented by a value on the closed interval [0, 1], where 0 is equated with the classical
false  value and 1 is equated with the classical true  value.  Values in (0, 1) indicate varying degrees of truth.

For example, the question
Is that person over 180 cm feet tall?  has only two answers, yes  or no .
On the other hand, the question
Is that person tall?  has many answers.  Someone over 190 cm is almost universally considered to be tall.  Someone who is 180 cm may be considered to be sort of tall , while someone who is under 160 cm is not usually considered to be tall.

This could be described by the following graph:
                                
[Maple Plot]  

This graph has a value 0 for any value under 160 (persons under 160 cm are not tall) and a value of 1 for any value over 190 cm (persons who are over 190 cm are tall) and varying degrees of membership in the set people who are tall  for values between 160 and 190.  This graph is called the membership function of the fuzzy set of people who are tall.

Simple fuzzy operations may be defined in numerous ways, but the simplest will be discussed here.
Given two fuzzy values x and y, we define the following operations:
     
(x and y) = min(x,y)  
     
(x or y) = max(x,y)  
     
(not x) = 1-x
      
(x implies y) = max(x,1-y)   
The operators
xor  and implies  may be defined using their standard definitions.  Note that if we treat the classical values true  and false  as 0 and 1, respectively, then the above definitions describe classical logic.

Consider another subset set of people:  people how are approximately 6 ft ( 182.88  cm) tall. Anyone within 2 cm of 6 ft (approximately 1/2 an inch) is usually considered to be 6 ft tall, while someone who is 4'' (10 cm) taller or shorter is not considered to be 6 ft tall.  This fuzzy of people may be described by the following graph:
                                 
[Maple Plot]
One may ask, is someone whose height is
187  cm both approximately 6  ft and  tall.  Using fuzzy logic, membership in the fuzzy set of tall people is .9  while membership in the fuzzy set of people approximately 6  ft tall is .75 .  Thus, their mebership in the class of people who are 6 ft and tall is min(.75,.9) = .75 .

Similarly, one may ask whether a person whose height is
175  cm whether or not they are both approximately 6  ft or  tall.  Using fuzzy logic, membership in the fuzzy set of tall people is .5  while membership in the fuzzy set of people approximately 6  ft tall is .25 .  Thus, their membership in the class of people who are 6  ft or tall is max(.5,.25) = .50 .

In general, a fuzzy set can be defined on any universal set U  of objects. The membership function of a fuzzy set S  is a function:
     
mu[S] : proc (U) options operator, arrow; [0, 1] end proc

The RealDomain  package restricts itself  the universal set of real numbers R .  Thus, any membership function is a function mu[S] : proc (R) options operator, arrow; [0, 1] end proc .  The FiniteDomain  routine generates packages which restrict themselves to fuzzy subsets of a given finite set.

We define the operator
in  to be:
      
`in`(x,S) = mu[S](x)
Thus,
in  is no longer a boolean operator when the right hand side is a fuzzy set.

Given our definitions for
and , or , not , and implies , we will now generalize the set operators.  Given two fuzzy sets S and T, we define the membership functions of `union`(S,T)  , `intersect`(S,T)  and S^`'`  (i.e., complement(S) ) as:
    
mu[`union`(S,T)](x) = (mu[S](x) or mu[T](x)) `` = max(mu[S](x),mu[T](x))  
    
mu[`intersect`(S,T)](x) = (mu[S](x) and mu[T](x)) `` = min(mu[S](x),mu[T](x))  
    
mu[S^`'`](x) = (not mu[S](x)) `` = 1-mu[S](x)
    
mu[`minus`(S,T)] = max(0,mu[S](x)-mu[T](x))
     
`subset`(S,T)   iff mu[S](x) <= mu[T](x)  for all `in`(x,U)
respectively.

The following three graphs show the fuzzy sets of 1. people who are 6 ft and tall (intersection), 2. people who are 6 ft or tall (union), and 3. people who are not 6 ft tall.
[Maple Plot]
[Maple Plot] [Maple Plot]  

To see different techniques of determining the result of operators on fuzzy values, see the section
UseNorm  below.

The function
evalb  converts a fuzzy value into a boolean value:
     
evalb(x) = PIECEWISE([true, 1/2 < x],[FAIL, x = 1/2],[false, x < 1/2])  
The function
evalfz  converts a boolean value into a fuzzy value:
     
evalfz(x) = PIECEWISE([0, x = false],[1/2, x = FAIL],[1, x = true])

The process of converting a fuzzy set to a single real number is called defuzzification.

Two methods are provided with the function Defuzzify  to make this conversion, each returning a single value nu .
Both require that the associated membership function has finite area.

Centre of Gravity:
    
nu = 1/int(mu[S](x),x = -infinity .. infinity).int(x*mu[S](x),x = -infinity .. infinity)  

Centre of Area:

      int(mu[S](x),x = -infinity .. nu) = int(mu[S](x),x = nu .. infinity)  
   

As well as including the aforementioned operators, the FuzzySets  package also includes a number of fuzzy set constructors:

      
FuzzySet, Gamma, L, Lambda, Partition  

The function FuzzySet is similar to the piecewise function with the following exceptions:
      1.  
FuzzySet(`...`,x < x[n],f[n](x),x = x[n+1],y[n+1],`...`)  interpolates the interval [x[n], x[n+1]] with a linear function connecting the points ( x[n] , f[n](x[n]) ) and ( x[n+1] , y[n+1] ).

      2.  The values x[n]  must be in order.  
 
The names of the constructors
Gamma , L , and Lambda  are chosen because the shape of the letter represents the object being represented.
     
Gamma  generates fuzzy sets which are zero at a given point and increase as x becomes greater.
     
L  generates fuzzy sets which decrease to zero at a given point.
     
Lambda  generates fuzzy sets which achieve a maximum at a point and decrease to zero on both sides.

Partition takes a sequence of three or more ordered points and creates a Lambda fuzzy set for each set of three consecutive points which satisfies:
     
mu[Lambda[i]](x[i]) = 0  

      mu[Lambda[i]](x[i+1]) = 1  
     
mu[Lambda[i]](x[i+2]) = 0  

The fuzzy sets package contains five exports which are described below.

>    with( FuzzySets );

Warning, the protected name RealDomain has been redefined and unprotected

[Controller, FiniteDomain, Logic, RealDomain, Tools]

Each section describes a separate portion of the package.

Fuzzy Logic Package

>    restart;

>    with( FuzzySets[Logic] );

Warning, these protected names have been redefined and unprotected: and, evalb, implies, not, or

[`and`, booleanum, evalb, evalfz, `implies`, `not`, `or`]

and

The and  of two fuzzy values indicates the degree of truth of both values at the same time.
For example, if a person is 0.8 tall (e.g., 180 cm) and 0.4 heavy (e.g., 60 kg) then that person is 0.4 tall and heavy, that is, not very much.
By default,
x and y = min(x,y) .
The fuzzy
and  of two fuzzy values is defined by a t-norm .  To change the default definition, see the Tools[UseTNorm]  function.

>    true and false;

0

>    1 and 0;

0

>    0.32523 and 0.53234;

.32523

or

The or  of two fuzzy values indicates the degree of truth to which at least one of the values is true.
For example, if a person is 0.8 tall (e.g., 180 cm) and 0.3 heavy (e.g., 60 kg) then that person is 0.8 tall or heavy.
By default,
x or y = max(x,y) .
The fuzzy
or  of two fuzzy values is defined by a s-norm .  To change the default definition, see the Tools[UseSNorm]  function.

>    true or false;

1

>    1 or 0;

1

>    0.32523 or 0.53234;

.53234

not

The not  of a fuzzy value indicates the degree to which the converse is true.
For example, if a person is 0.8 tall (e.g., 180 cm) then he is 0.3 not tall, or 0.3 short.
By default,
(not x) = 1-x .
The fuzzy
not  of a fuzzy value is defined by a negation .  To change the default definition, see the Tools[UseComplement]  function.

>    not true;

false

>    not 1;

0

>    not 0.32523;

.67477

>    not x;

not x

>    not (x = y);

true

implies

Fuzzy implications are a field of significant study.
By default,
(x implies y) = (not x or y) , but numerous other definitions are available.
The fuzzy implication of one fuzzy value to another is defined by an
implication  function. To change the default definition, see the Tools[UseImplication]  function.

>    true implies false;

max(false,1-true)

>    1 implies 0;

0

>    0.32523 implies 0.53234;

.67477

>    not 0.32523 or 0.53234;

.67477

evalb

The routine evalb  has been overridden to accept numeric values in [0, 1]  and return true , false , or FAIL .
Numeric values less than 0 are treated as
false , and values greater than 1 are treated as true .
For numeric arguments, it can be thought of as:
evalb(r) = PIECEWISE([true, 1/2 < r],[FAIL, r = 1/2],[false, r < 1/2]) .

>    evalb( true );

true

>    evalb( 1 );

true

>    evalb( 0.73253 );

true

>    evalb( 0.32523 );

false

>    evalb( 0.5 );

FAIL

>    evalb( x );

x

booleanum

The routine booleanum  is the equivalent of signum  for generating boolean values.
It will call
signum  to determine whether a value is less than, equal to, or greater than 0.5.
A second argument may dictate the value at 0.5.
Unlike
evalb  and evalfz , booleanum  returns unevaluated if it cannot determine the truth of the statement.

>    booleanum( true );

true

>    booleanum( Pi/4 );

true

>    booleanum( 0.5 );

FAIL

>    booleanum( 0.5, true );

true

>    booleanum( x );

booleanum(x)

evalfz

The routine evalfz  converts a boolean value into a fuzzy value.
For boolean values, it can be thought of as:
evalfz(b) = PIECEWISE([1, b = true],[1/2, b = FAIL],[0, b = false]) .

>    evalfz( true );

1

>    evalfz( false );

0

>    evalfz( FAIL );

1/2

>    evalfz( 1 );

1

>    evalfz( 0.32523 );

.32523

>    evalfz( x );

x

Real Fuzzy Sets Package

The RealDomain subpackage allows the user to construct fuzzy subsets of the real line.
A membership of a real value
r  in a fuzzy subset of the real line is represented by a piecewise function, the range of which is [0, 1].
The RealDomain subpackage includes a number of constructors of fuzzy subsets of
R .
As well, the plot function is overridden to allow plot to display fuzzy sets as well as normal functions.
A number of operators and functions for working with fuzzy subsets of
R  are provided.

In general, this package tries as much as possible to treat fuzzy sets like sets.  You may take the union of two fuzzy sets like you would take the union of two normal sets in Maple.  Membership is determined by using the
in  operator.

>    restart;

>    with( FuzzySets[RealDomain] );

Warning, these protected names have been redefined and unprotected: implies, intersect, minus, plot, subset, union

[Arithmetic, Complement, Concentrate, Controller, Core, Cut, Defuzzify, Dilate, FuzzySet, Gamma, Height, IntensifyContrast, IntervalOfInterest, L, Lambda, Map, Map2, Normalize, PI, Partition, Support, ...
[Arithmetic, Complement, Concentrate, Controller, Core, Cut, Defuzzify, Dilate, FuzzySet, Gamma, Height, IntensifyContrast, IntervalOfInterest, L, Lambda, Map, Map2, Normalize, PI, Partition, Support, ...

Constructors

Note that even though a fuzzy set is displayed like a piecewise function, it does not intended to behave like one.  It is a set, and should be opoerated on as such.
The fuzzy set cannot be
evaluated  at a point, as this makes no sense.  Instead, you must use the in  operator or mu  function to convert the fuzzy set to its associated membership function (which could be a piecewise function.)

fuzzyset type

Each of the constructors returns an object which is of type fuzzyset .

While numeric values in the interval [0, 1] are not considered to be fuzzy sets, if they are used in a union or intersection, they will be interpreted as fuzzy sets.

>    Fz := L( 3, 4 );

Fz := PIECEWISE([1, r <= 3],[-r+4, r < 4],[0, otherwise])

>    type( Fz, fuzzyset );

true

FuzzySet Constructor

The fuzzy set constructor FuzzySet  is similar to the piecewise  function.
An odd number of arguments must be given.

>    FuzzySet( x < 3, 0, x = 4, 1, x = 5, 1/2, x = 6, 1, x = 7, 0, 0 );

PIECEWISE([0, r < 3],[r-3, r <= 4],[-1/2*r+3, r <= 5],[1/2*r-2, r <= 6],[-r+7, r <= 7],[0, otherwise])

>    plot(%);

[Maple Plot]

>    FuzzySet( x < 3, 0, x < 4, 1/2, x = 6, 1, 1 );

PIECEWISE([0, r < 3],[1/2, r <= 4],[1/4*r-1/2, r <= 6],[1, otherwise])

>    plot( %, 2..7, axes = none );

[Maple Plot]

Other Constructors and Models

The constructors Gamma ( Gamma ), L ( L ), Lambda ( Lambda ), and PI ( PI ) are named to suggest the shape of the resulting membership function.
For example, Gamma produces fuzzy sets whose functions monotonically increasing from 0 to 1, while L produces fuzzy sets whose membership function decreases from 1 to 0.

In words, these subsets of R would be described as:

  1.  Real numbers approximately less than a given value ( L ),
  2.  Real numbers approximately greater than a given value (
Gamma ),
  3.  Real numbers approximately equal to a given value (
Lambda ).
  4.  Real numbers on or close to an interval (
PI ).

The transition from real numbers having full membership (1) in the associated set and having no membership (0) depends on the type of membership function used.
The membership functions provided use standard algebraic expressions to describe the membership of a real number within the fuzzy set, and the type of expression (or model) used may be specified.
For example, the linear model uses a piecewise linear function to represent the transition from 0 to 1 (or 1 to 0.)

Linear

The linear model of fuzzy sets defines fuzzy sets through piecewise linear functions.
The linear model is the default for the constructors
Gamma , L , Lambda , and Partition .

>    Gamma( 1, 4 );

PIECEWISE([0, r <= 1],[1/3*r-1/3, r < 4],[1, otherwise])

>    plot( [Gamma( 1, 4 ), Lambda( 2, 3, 4 )], 0..5,
  thickness=2, color = [red, blue],
  legend = ["Significatly greater than 1", "Approximately 3"]
);

[Maple Plot]

Quadratic

The quadratic model defines the membership function of fuzzy sets using piecewise quadratic functions with smooth transitions to constant regions.

>    Gamma( 1, 4, model = 'quadratic' );

PIECEWISE([0, r <= 1],[2/9*(r-1)^2, r < 5/2],[1-2/9*(r-4)^2, r < 4],[1, otherwise])

>    plot(
  [Gamma( 1, 4, model = quadratic ), Lambda( 2, 3, 4, model = quadratic )], 0..5,
  thickness=2, color = [red, blue],
  legend = ["Significatly greater than 1", "Approximately 3"]
);

[Maple Plot]

Cubic

>    plot(
  [Gamma( 1, 4, model = cubic ), Lambda( 2, 3, 4, model = cubic )], 0..5,
  thickness=2, color = [red, blue],
  legend = ["Significatly greater than 1", "Approximately 3"]
);

[Maple Plot]

Rational

>    Gamma( 4, model = rational );

PIECEWISE([1-(r-4)^2/(1+(r-4)^2), r < 4],[1, otherwise])

>    plot(
  [Gamma( 4, model = rational ), Lambda( 3, model = rational )], 0..5,
  thickness=2, color = [red, blue],
  legend = ["Greater than or approximately 4", "Approximately 3"]
);

[Maple Plot]

A positive parameter can be used to indicate the amount the rate at which the membership function drops off.  The default parameter value is 1.

>    plot(
  [Gamma( 4, model = rational ), Gamma( 4, model = rational[2] ), Gamma( 4, model = rational[1/2] )], 0..5,
  thickness=2, color = [red, blue, black]
);

[Maple Plot]

Exponential

>    plot(
  [Gamma( 4, model = exp ), Lambda( 3, model = exp )], 0..5,
  thickness=2, color = [red, blue],
  legend = ["Greater than or approximately 4", "Approximately 3"]
);

[Maple Plot]

A positive parameter can be used to indicate the amount the rate at which the membership function drops off.  The default parameter value is 1.

>    plot(
  [Gamma( 4, model = exp ), Gamma( 4, model = exp[2] ), Gamma( 4, model = exp[1/2] )], 0..5,
  thickness=2, color = [red, blue, black]
);

[Maple Plot]

Arctangent

>    plot( Gamma( 5, model = arctan ), 0..10, 0..1,
  thickness=2,
  legend = ["Approximately greater than 5"]
);

[Maple Plot]

A positive parameter can be used to indicate the amount the rate at which the membership function approachas 0 and 1.  The default parameter value is 1.

>    plot(
  [Gamma( 5, model = arctan ), Gamma( 5, model = arctan[2] ), Gamma( 5, model = arctan[1/2] )], 0..10, 0..1,
  thickness=2, color = [red, blue, black]
);

[Maple Plot]

Hyperbolic Tangent

>    plot( Gamma( 5, model = tanh ), 0..10, 0..1,
  thickness=2,
  legend = "Approximately greater than 5"
);

[Maple Plot]

A positive parameter can be used to indicate the amount the rate at which the membership function approachas 0 and 1.  The default parameter value is 1.

>    plot(
  [Gamma( 5, model = tanh ), Gamma( 5, model = tanh[2] ), Gamma( 5, model = tanh[1/2] )], 0..10, 0..1,
  thickness=2, color = [red, blue, black]
);

[Maple Plot]

The constructors Gamma ( Gamma ), L ( L ), Lambda ( Lambda ), and PI ( PI ) are named to suggest the shape of the resulting membership function.
For example, Gamma produces fuzzy sets whose functions monotonically increasing from 0 to 1, while L produces fuzzy sets whose membership function decreases from 1 to 0.

Gamma

The Gamma  constructor is used to represent real numbers approximately greater than or equal to a given value.

The linear model takes two arguments a, b and creates a linear function which interpolates the points (a, 0), (b, 1).
        
PIECEWISE([0, r <= a],[(r-a)/(b-a), r < b],[1, otherwise])

The quadratic model (Zadeh's S function) interpolates the points with two quadratics which are smooth at each end point.
        
PIECEWISE([0, r <= a],[2*((x-a)/(b-a))^2, r <= (a+b)/2],[1-2*((x-c)/(a-c))^2, x < b],[1, otherwise])

The cubic model interpolates the two points which a cubic
p(r)  the derivative of which is 0 at each end point.
        
PIECEWISE([0, r <= a],[p(r), r < b],[1, otherwise])

The rational model takes one argument a and creates a rational function
f(r)  which is zero at a and approaches 1  as proc (r) options operator, arrow; infinity end proc .
It takes a parameter
0 < k  which is 1 by default.
        
PIECEWISE([0, r <= a],[k*(r-a)^2/(1+k*(r-a)^2), otherwise])

The exponential model does the same, but uses an exponential function.
It takes a parameter
0 < k  which is 1 by default.
       
PIECEWISE([0, r <= a],[1-exp(-k*(r-a)^2), otherwise])
The arctangent and hyperbolic tangent models take one argument a creates a fuzzy set S such that
`in`(a,S) = 1/2 .
They both take parameters
0 < k .
      
1/2+arctan(k*(r-a))/Pi  
      
1/2+tanh(k*(r-a))/2  

Parameters are passed by using an index.  See the examples below.

>    Gamma( 3, 4 );

PIECEWISE([0, r <= 3],[r-3, r < 4],[1, otherwise])

>    plot( [
  Gamma( 1, 4 ), Gamma( 1, 4, model=quadratic ), Gamma( 1, 4, model=cubic )
], 0..5, legend=["Linear", "Quadratic", "Cubic"], color=[red, blue, black] );

[Maple Plot]

>    plot( [
  Gamma( 1, model=rational ), Gamma( 1, model=exp ),
  Gamma( 1, model=rational[2] ), Gamma( 1, model=exp[2] )
], -2..2, color = [red, blue, black, magenta], legend=[
  "Rational", "Exponential",
  "Rational with parameter 2", "Exponential with parameter 2"
] );

[Maple Plot]

>    plot( [
  Gamma( 1, model=arctan ), Gamma( 1, model=tanh ),
  Gamma( 1, model=arctan[2] ), Gamma( 1, model=tanh[2] )
], -3..5, color = [red, blue, black, magenta], legend=[
  "Arctangent", "Hyperbolic Tangent",
  "Arctangent with parameter 2", "Hyperbolic Tangent with parameter 2"
] );

[Maple Plot]

L

The L  constructor does the same as the Gamma constructor, except it goes down from (a, 1) to (b, 0).

>    L( 3, 4 );

PIECEWISE([1, r <= 3],[-r+4, r < 4],[0, otherwise])

>    plot( [
  L( 1, 4 ), L( 1, 4, model=quadratic ), L( 1, 4, model=cubic )
], 0..5, color = [red, blue, black], legend=["Linear", "Quadratic", "Cubic"] );

[Maple Plot]

>    plot( [
  L( 1, model=rational ), L( 1, model=exp ),
  L( 1, model=rational[2] ), L( 1, model=exp[2] )
], 0..5, color = [red, blue, black, magenta], legend=[
  "Rational", "Exponential",
  "Rational with parameter 2", "Exponential with parameter 2"
] );

[Maple Plot]

>    plot( [
  L( 1, model=arctan ), L( 1, model=tanh ),
  L( 1, model=arctan[2] ), L( 1, model=tanh[2] )
], -3..5, color = [red, blue, black, magenta], legend=[
  "Arctangent", "Hyperbolic Tangent",
  "Arctangent with parameter 2", "Hyperbolic Tangent with parameter 2"
] );

[Maple Plot]

Lambda

The Lambda  function takes models similar to that of the Gamma  and L  functions except that it is used to model an approximation to a point, so

the definitions must be appropriately adjusted.

The arctangent and hyperbolic tangent models do not apply to the
Lambda  function.

>    Lambda( 3, 4, 5 );

PIECEWISE([0, r <= 3],[r-3, r < 4],[-r+5, r < 5],[0, otherwise])

>    plot( [
  Lambda( 1, 3, 5 ), Lambda( 1, 3, 5, model=quadratic ), Lambda( 1, 3, 5, model=cubic )
], 0..6, color = [red, blue, black], legend=["Linear", "Quadratic", "Cubic"] );

[Maple Plot]

>    plot( [
  Lambda( 3, model=rational ), Lambda( 3, model=exp ),
  Lambda( 3, model=rational[2] ), Lambda( 3, model=exp[2] )
], 0..6, color = [red, blue, black, magenta], legend=[
  "Rational", "Exponential",
  "Rational with parameter 2", "Exponential with parameter 2"
] );

[Maple Plot]

PI

The PI function is similar to the Lambda function except it contains an interval on which fuzzy membership is 1.

>    PI( 3, 4, 5, 6 );

PIECEWISE([0, r <= 3],[r-3, r < 4],[1, r <= 5],[-r+6, r < 6],[0, otherwise])

>    plot( [
  PI( 1, 3, 5, 7 ), PI( 1, 3, 5, 7, model=quadratic ), PI( 1, 3, 5, 7, model=cubic )
], 0..8, color = [red, blue, black], legend=["Linear", "Quadratic", "Cubic"] );

[Maple Plot]

>    plot( [
  PI( 3, 4, model=rational ),    PI( 3, 4, model=exp ),
  PI( 3, 4, model=rational[2] ), PI( 3, 4, model=exp[2] )
], 0..7, legend=[
  "Rational", "Exponential",
  "Rational with parameter 2", "Exponential with parameter 2"
] );

[Maple Plot]

Partition

For a linear, quadratic, or cubic model, the Partition  function takes a sequence of points and generates a set of Lambda  functions of each triplet of points.
For the other models, it creates the associated
Lambda  fuzzy set for each point.
The arguments must be ordered apriori.

>    Partition( 3, 4, 6, 8, 9 );

PIECEWISE([0, r < 3],[1, r = 3],[0, otherwise]), PIECEWISE([0, r < 4],[1, r = 4],[0, otherwise]), PIECEWISE([0, r < 6],[1, r = 6],[0, otherwise]), PIECEWISE([0, r < 8],[1, r = 8],[0, otherwise]), PIECE...

>    plot( [Partition( 3, 5, 7, 9, 11 )], 1..13 );

[Maple Plot]

>    plot( [Partition( 3, 5, 7, 9, 11, model = quadratic )], 1..13 );

[Maple Plot]

>    plot( [Partition( 3, 5, 7, 9, 11, model = cubic )], 1..13 );

[Maple Plot]

>    plot( [Partition( 3, 5, 7, 9, 11, model = rational[2] )], 1..13 );

[Maple Plot]

Plotting

The plot  command is overloaded so that if the first argument is a fuzzy set or a set or list of fuzzy sets that they display properly.
A second argument indicating a range should not give a variable (as a fuzzy set does not have a variable.)

Alternatively, the fuzzy set
S  can be converted to a regular function in x  by using mu[S](x) .

>    plot( Gamma( 2, 4 ), 1..5 );

[Maple Plot]

>    plot( [Partition( -3, -2, 0, 1, 3, 6, 7 )], -4..8, filled=true );

[Maple Plot]

>    S := Lambda( -2, 0, 2 ):

>    f := mu[S](x);

f := PIECEWISE([0, x <= -2],[1+1/2*x, x < 0],[-1/2*x+1, x < 2],[0, otherwise])

>    plot( f, x = -4..4, axes = none );

[Maple Plot]

Operators on Fuzzy Sets with a Real Domain

We will consider the various operators and functions as applied to the following three fuzzy sets.

>    restart;

>    with( FuzzySets[RealDomain] );

Warning, these protected names have been redefined and unprotected: implies, intersect, minus, plot, subset, union

[Arithmetic, Complement, Concentrate, Controller, Core, Cut, Defuzzify, Dilate, FuzzySet, Gamma, Height, IntensifyContrast, IntervalOfInterest, L, Lambda, Map, Map2, Normalize, PI, Partition, Support, ...
[Arithmetic, Complement, Concentrate, Controller, Core, Cut, Defuzzify, Dilate, FuzzySet, Gamma, Height, IntensifyContrast, IntervalOfInterest, L, Lambda, Map, Map2, Normalize, PI, Partition, Support, ...

>    S := L( 3, 4 ):

>    T := Lambda( 2, 5, 8 ):

>    U := L( 4, 6 ):

>    plot( [S, T, U], 1..9, color = [red, blue, black], legend = ["S", "T", "U"] );

[Maple Plot]

Union (union)

The union of two fuzzy sets S and T has the membership function mu[`union`(S,T)](x) = (mu[S](x) or mu[T](x)) .
By default, this is equal to:  
mu[`union`(S,T)](x) = max(mu[S](x),mu[T](x)) .  This is equal to the join  of the two membership functions.
The default s-norm used to calculate the union may be changed using the
Tools[UseTNorm]  function.

>    plot( [S, T, S union T], 1..9, thickness=[1, 1, 3], color=[red, blue, black] );

[Maple Plot]

>    S union T;

PIECEWISE([1, r <= 3],[-r+4, r < 7/2],[1/3*r-2/3, r < 5],[-1/3*r+8/3, r < 8],[0, otherwise])

Intersection (intersect)

The intersection of two fuzzy sets S and T has the membership function mu[`intersect`(S,T)](x) = (mu[S](x) and mu[T](x)) .
By default, this is equal to:  
mu[`intersect`(S,T)](x) = min(mu[S](x),mu[T](x)) .  This is equal to the meet  of the two membership functions.
The default t-norm used to calculate the union may be changed using the
Tools[UseTNorm]  function.

>    plot( [S, T, S intersect T], 1..9, thickness=[1, 1, 3], color=[red, blue, black] );

[Maple Plot]

Implication (implies)

The amount to which one fuzzy set implies another has numerous member functions.  According to classical logic, the definition may have the membership function mu[`implies`(S,T)](x) = (not mu[S](x)) and mu[T](x) .
By default, this is equal to:  
mu[`implies`(S,T)](x) = max(1-mu[S](x),mu[T](x)) .
The default implication used to calculate implication may be changed using the
Tools[UseImplication]  function.

>    plot( [S, T, S implies T], 1..9, thickness=[1, 1, 3], color=[red, blue, black] );

[Maple Plot]

>    plot( [S, 0.3, S implies 0.3, 0.3 implies S], 1..9, thickness=[1, 1, 3, 3], color=[red, blue, black, cyan] );

[Maple Plot]

Membership (in)

The in  operator returns the degree of membership of the left hand side in the given fuzzy set.  The following are equivalent for numeric x :   `in`(x,S) = mu[S](x) .

>    3.2 in S;

.8

>    3.2 in T;

.4000000003

>    3.2 in U;

1

>    plot( [S, T, U], 3..4, color = [red, blue, black] );

[Maple Plot]

Set Minus (minus)

The minus operator is defined as mu[`minus`(S,T)](x) = (not (mu[S](x) implies mu[T](x))) .
Alternatively, one may define it as
mu[`minus`(S,T)](x) = max(0,mu[S](x)-mu[T](x)) , but the Arithmetic  subpackage may be used for this purpose.  Otherwise, there would be no access to fuzzy implications through the FuzzySets[RealDomains]  package.

>    (S minus T) subset S;

true

>    FuzzySets:-Logic:-`not`( 0.2 );

.8

>    plot( [S, T, S minus T], 1..9, color=[red, blue, cyan], thickness = [1, 1, 3] );

[Maple Plot]

Subset (subset)

A fuzzy set S is a subset of a fuzzy set T if mu[S](x) <= mu[T](x)  for all real x .

>    T subset S;

false

>    S subset U;

true

>    U subset S;

false

Arithmetic Subpackage

The Arithmetic  subpackage allows you to take sums, differences, and products of fuzzy sets.
As such operations are less common on fuzzy sets, they are included in a subpackage so as to not interfer with the standard Maple interface.
As these are not common, they are placed in a separate subpackage rather than overriding +, -, and * when you load the
FuzzySet[RealDomains]  package.

>    use FuzzySets:-RealDomain:-Arithmetic in
  plot( [S, T, S + T, S - T, S * T], 0..9, color = [red, blue, black, cyan, magenta], thickness = [1, 1, 3, 3, 3], legend = ["S", "T", "S + T", "S - T", "S * T"] );
end use;

[Maple Plot]

Functions on Fuzzy Sets with a Real Domain

We will consider the various operators and functions as applied to the following three fuzzy sets.

>    restart;

>    with( FuzzySets[RealDomain] );

Warning, these protected names have been redefined and unprotected: implies, intersect, minus, plot, subset, union

[Arithmetic, Complement, Concentrate, Controller, Core, Cut, Defuzzify, Dilate, FuzzySet, Gamma, Height, IntensifyContrast, IntervalOfInterest, L, Lambda, Map, Map2, Normalize, PI, Partition, Support, ...
[Arithmetic, Complement, Concentrate, Controller, Core, Cut, Defuzzify, Dilate, FuzzySet, Gamma, Height, IntensifyContrast, IntervalOfInterest, L, Lambda, Map, Map2, Normalize, PI, Partition, Support, ...

>    S := L( 3, 4 ):

>    T := Lambda( 2, 5, 8 ):

>    U := L( 4, 6 ):

>    plot( [S, T, U], 1..9, color = [red, blue, black], legend = ["S", "T", "U"] );

[Maple Plot]

Complement

The complement of a fuzzy set has the membership function mu[Complement(S)](x) = (not mu[S](x)) .

By default, it is equal to mu[Complement(S)](x) = 1-mu[S](x) .
The default complement used may be changed using the
Tools[UseComplement]  function.

>    plot( [T, Complement( T )], 1..9, color=[red, black] );

[Maple Plot]

Converting Fuzzy Sets to Piecewise Functions ( mu )

The mu  operator can be thought of as the equivalent of convert(S,piecewise,x) .
The notation
mu[S](x)  is used throughout the literature of fuzzy sets.

>    mu[S](x);

PIECEWISE([1, x <= 3],[-x+4, x < 4],[0, otherwise])

Defuzzify

>    Defuzzify( T );

5

>    Defuzzify( Lambda( 0, 3, 9 ) );

4

>    Defuzzify( S );   # Error

Error, (in FuzzySets:-RealDomain:-Defuzzify) cannot defuzzify an unbounded fuzzy set on an infinite interval

Cut

The fuzzy weak alpha -level cut A[alpha]  of a fuzzy set A  is defined as the fuzzy set whose membership function is:

     
mu[A[alpha]](x) = PIECEWISE([mu[A](x), alpha <= mu[A](x)],[0, otherwise])  

This is the default result given by the function
Cut .

The crisp weak
alpha -level cut A[alpha]  for a fuzzy set A  is defined as the fuzzy set whose membership function is:
     
mu[A[alpha]](x) = PIECEWISE([1, alpha <= mu[A](x)],[0, otherwise])  


This result may be achieved through the use of the option
crisp = true .

The strong alpha-level cut
A[alpha]  of a fuzzy set A is defined as the fuzzy set whose membership function is:

    
mu[A[alpha]](x) = PIECEWISE([mu[A](x), alpha < mu[A](x)],[0, otherwise])  

This result may be achieved through the use of the option
strong = true .

Both options may be used together to get a crisp set which is
1  whenever alpha < mu[A](x) .

>    Cut( S, 0.3 );                 # fuzzy and weak

PIECEWISE([1, r <= 3],[-r+4, r <= 3.7],[0, otherwise])

>    Cut( S, 0.3, crisp );          # crisp and weak

PIECEWISE([1, r <= 3.7],[0, otherwise])

>    Cut( S, 0.3, strong );         # fuzzy and strong

PIECEWISE([1, r <= 3],[-r+4, r < 3.7],[0, otherwise])

>    Cut( S, 0.3, crisp, strong );  #crisp and strong

PIECEWISE([1, r < 3.7],[0, otherwise])

>    plot( [S, Cut( S, 0.3 ), Cut( S, 0.3, crisp )], 2..5, color=[red, blue, black], thickness = [1, 3, 4] );

[Maple Plot]

Core

The core of a fuzzy set S is the set of all points for which mu[S](x) = 1 .
It may be thought of as the crisp weak 1-level cut of a fuzzy set.

>    Core( S );

PIECEWISE([1, r <= 3],[0, otherwise])

Support

The support of a fuzzy set S is the set of all points for which 0 < mu[S](x) .
It may be thought of as the crisp strong 0-level cut of a fuzzy set.

>    Support( S );

PIECEWISE([1, r < 4],[0, otherwise])

Height

The height of a fuzzy set is the supremum of the membership function mu[S](x) .

>    Height( S );

1

>    Height( S intersect T );

1/2

Normalize

A fuzzy set is called normal if it is either the empty set (0) or there exists an element `in`(x,S)  such that mu[S](x) = 1 , that is, Height(S) = 1 .
The normalize function divides a fuzzy set by its height to produce a normal fuzzy set.

>    Normalize( S );

PIECEWISE([1, r <= 3],[-r+4, r < 4],[0, otherwise])

>    Normalize( S intersect T );

PIECEWISE([0, r <= 2],[2/3*r-4/3, r < 7/2],[-2*r+8, r < 4],[0, otherwise])

>    plot(
  [S intersect T, Normalize( S intersect T )],
  1..5, color=[red, blue], legend = ["U = S intersect T", "Normalize( U )"]
);

[Maple Plot]

Concentate

>    C1 := Lambda( 3, 4, 5 );

C1 := PIECEWISE([0, r <= 3],[-3+r, r < 4],[5-r, r < 5],[0, otherwise])

>    C2 := Concentrate( C1 );

C2 := PIECEWISE([0, r <= 3],[(-3+r)^2, r < 4],[(5-r)^2, r < 5],[0, otherwise])

>    C3 := Concentrate( C1, 3 );

C3 := PIECEWISE([0, r <= 3],[(-3+r)^3, r < 4],[(5-r)^3, r < 5],[0, otherwise])

>    plot( [C1, C2, C3], 2..6, color = [red, blue, black] );

[Maple Plot]

Dilate

>    D1 := Lambda( 3, 4, 5 );

D1 := PIECEWISE([0, r <= 3],[-3+r, r < 4],[5-r, r < 5],[0, otherwise])

>    D2 := Dilate( D1 );

D2 := PIECEWISE([0, r <= 3],[(-3+r)^(1/2), r < 4],[(5-r)^(1/2), r < 5],[0, otherwise])

>    D3 := Dilate( D1, 3 );

D3 := PIECEWISE([0, r <= 3],[(-3+r)^(1/3), r < 4],[(5-r)^(1/3), r < 5],[0, otherwise])

>    plot( [D1, D2, D3], 2..6, color = [red, blue, black] );

[Maple Plot]

IntensifyContrast

>    IC1 := Lambda( 3, 4, 5, model=quadratic );

IC1 := PIECEWISE([0, r <= 3],[2*(-3+r)^2, r < 7/2],[1-2*(r-4)^2, r <= 4],[1-2*(r-4)^2, r < 9/2],[2*(r-5)^2, r < 5],[0, otherwise])

>    IC2 := IntensifyContrast( IC1 );

IC2 := PIECEWISE([0, r <= 3],[8*(-3+r)^4, r <= 7/2],[-2047-8*r^4+128*r^3-768*r^2+2048*r, r < 9/2],[8*(r-5)^4, r < 5],[0, otherwise])

>    plot([IC1, IC2], 2..6 );

[Maple Plot]

Finite Fuzzy Sets

The FiniteDomain  procedure takes as its argument a either a set which is taken to be the universal set for a system of fuzzy sets or it takes two arguments which, when passed to the procedure seq , return a list of elements..

On this set, fuzzy sets may be defined using the
FuzzySet  constructor.  Real values r  in [0, 1] are interpreted as the fuzzy set with membership r  for each element in the universal set.

Nonnumeric Universal Sets

The universal set need not be a set of numeric values.  For example, the universal set may be a set of names, a set of places, or a set of things.
We will use, in this case, the symbols
x , y , and z .

>    restart;

>    FzSet := FuzzySets[FiniteDomain]( {x, y, z} ):

>    with( FzSet );

Warning, these protected names have been redefined and unprotected: implies, intersect, minus, plot, subset, union

[Complement, Concentrate, Controller, Core, Cut, Defuzzify, Dilate, Equals, FuzzySet, Height, IntensifyContrast, Normalize, Random, Support, `implies`, `in`, `intersect`, `minus`, mu, plot, `subset`, `...
[Complement, Concentrate, Controller, Core, Cut, Defuzzify, Dilate, Equals, FuzzySet, Height, IntensifyContrast, Normalize, Random, Support, `implies`, `in`, `intersect`, `minus`, mu, plot, `subset`, `...

>   

Constructors

FuzzySet

The constructor FuzzySet  takes a sequence of the form x = y  where `in`(x,U)  and y  is a fuzzy value.

>    S := FuzzySet( x = 0.3 );

S := PIECEWISE([r = x, .3])

>    T := FuzzySet( x = 0.2, y = 1 );

T := PIECEWISE([r = x, .2],[r = y, 1])

>    V := FuzzySet( u = 0.3 ); # Error

Error, (in FuzzySet) u is not in the universal set {x, y, z}

>    W := FuzzySet( x = 1.2 ); # Error

Error, (in FuzzySet) the value 1.2 is not a fuzzy value

>    X := FuzzySet( x = 0.3, y = 0.5, z = 0.7 );

X := PIECEWISE([r = x, .3],[r = y, .5],[r = z, .7])

Random

The constructor Random  returns a random fuzzy of the universal set.

>    R := Random();

R := PIECEWISE([r = x, .4274196691],[r = y, .3211106933],[r = z, .3436330737])

The constructor Random takes a procedure which returns fuzzy values as a first argument.

>    R2 := Random( () -> rand(1..2)()/2 );

R2 := PIECEWISE([r = x, 1],[r = y, 1/2],[r = z, 1/2])

Plotting

>    plot( S );

[Maple Plot]

>    plot( R );

[Maple Plot]

Operators on Fuzzy Sets with a Finite Nonnumeric Domain

The properites of the operators are identical to the descriptions given in the section Operators on Fuzzy Sets with a Real Domain .

>    S := FuzzySet( x = 0.3 );

S := PIECEWISE([r = x, .3])

>    T := FuzzySet( x = 0.2, y = 1 );

T := PIECEWISE([r = x, .2],[r = y, 1])

Union (union)

>    S union T;

PIECEWISE([r = x, .3],[r = y, 1])

>    S union 0.2;

PIECEWISE([r = x, .3],[r = y, .2],[r = z, .2])

Intersection (intersect)

>    S intersect T;

PIECEWISE([r = x, .2])

>    T intersect 0.2;

PIECEWISE([r = x, .2],[r = y, .2])

Implication (implies)

>    S implies T;

PIECEWISE([r = x, .7],[r = y, 1],[r = z, 1])

>    T implies S;

PIECEWISE([r = x, .8],[r = z, 1])

Membership (in)

>    x in S;

.3

>    y in S;

0

>    a in S;

`in`(a,PIECEWISE([r = x, .3]))

Set Minus (minus)

>    S minus T;

PIECEWISE([r = x, .1])

>    T minus S;

PIECEWISE([r = y, 1])

>    (0.9) minus T;

PIECEWISE([r = x, .7],[r = z, .9])

>    S minus (0.2);

PIECEWISE([r = x, .1])

Subset (subset)

>    T subset S;

false

>    S subset T;

false

>    (S minus T) subset T;

true

>    T subset 1;

true

>    0 subset S;

true

Functions on Fuzzy Sets with a Finite Nonnumeric Domain

Unless stated otherwise, the properites of these functions are identical to the descriptions given in the section Operators on Fuzzy Sets with a Real Domain .

>    S := FuzzySet( x = 0.3 );

S := PIECEWISE([r = x, .3])

>    T := FuzzySet( x = 0.2, y = 1 );

T := PIECEWISE([r = x, .2],[r = y, 1])

Complement

The complement of a fuzzy set is the set whose membership function is mu[Complement(S)](x) = (not mu[S](x)) .

>    Complement( S );

PIECEWISE([r = x, .7],[r = y, 1],[r = z, 1])

>    Complement( T );

PIECEWISE([r = x, .8],[r = z, 1])

>    Complement( 1/3 );

2/3

Converting Fuzzy Sets to Table of Fuzzy Values ( mu )

As discrete values cannot easily be turned into an expression, this procedure returns a table indexed by the elements of the universal set with entries equal to their fuzzy values.

>    mu[S]();

TABLE([x = .3, y = 0, z = 0])

>    mu[1/2]();

TABLE([x = 1/2, y = 1/2, z = 1/2])

Defuzzify

The two methods to defuzzify a fuzzy set on a finite non-numeric domain are to find all the elements with maximum membership and to randomly select one of these.
These two methods are identified by
method  = maximum(set)  and method  = maximum(random) , respectively.  The first is the default for nonnumeric domains.

>    Defuzzify( S );

x

>    Defuzzify( T );

y

>    R := FuzzySet( x = 1/2, y = 1/2 );

R := PIECEWISE([r = x, 1/2],[r = y, 1/2])

>    Defuzzify( R );

y

The option method  = maximum(set)  returns all maximum values.

>    Defuzzify( S, method = maximum(set) );

{x}

>    Defuzzify( R, method = maximum(set) );

{x, y}

The option method  = maximum(random)  is the default.

>    Defuzzify( S, method = maximum(random) );

x

Cut

>    Cut( S, 1/2 );

0

>    Cut( S, 0.1 );

PIECEWISE([r = x, .3])

>    Cut( S, 0.1, crisp );

PIECEWISE([r = x, 1])

>    Cut( T, 0.2, strong );

PIECEWISE([r = y, 1])

>    Cut( T, 0.2 );

PIECEWISE([r = x, .2],[r = y, 1])

>    Cut( T, 0.2, crisp );

PIECEWISE([r = x, 1],[r = y, 1])

Core

For fuzzy sets with a finite domain, the core is returned as a set of all elements which have a membership of 1.

>    Core( S );

{}

>    Core( Cut( T, 0.2, crisp ) );

{x, y}

Support

For fuzzy sets with a finite domain, the support is returned as a set of all elements which have nonzero membersip.

>    Support( S );

{x}

>    Support( T );

{x, y}

Height

>    Height( S );

.3

>    Height( T );

1

>    Height( 1/2 );

1/2

Normalize

>    Normalize( S );

PIECEWISE([r = x, .9999999999])

>    Normalize( T );

PIECEWISE([r = x, .2],[r = y, 1])

>    Normalize( Random() );

PIECEWISE([r = x, .9696800955],[r = y, .8105174276],[r = z, 1.000000000])

>    Normalize( 1/2 );

1

>    Normalize( 0 );

0

Concentrate

>    Concentrate( S );

PIECEWISE([r = x, .5477225575])

>    Concentrate( T );

PIECEWISE([r = x, .4472135955],[r = y, 1])

>    Concentrate( 1/2 );

1/2*2^(1/2)

Dilate

>    Dilate( S );

PIECEWISE([r = x, .5477225575])

>    Dilate( T );

PIECEWISE([r = x, .4472135955],[r = y, 1])

>    Dilate( 1/2 );

1/2*2^(1/2)

Intensify Contrast

>    IntensifyContrast( S );

PIECEWISE([r = x, .18])

>    IntensifyContrast( T );

PIECEWISE([r = x, .8e-1],[r = y, 1])

>    IntensifyContrast( FuzzySet( x = 0.3, y = 0.5, z = 0.7 ) );

PIECEWISE([r = x, .18],[r = y, .50],[r = z, .82])

Numeric Universal Sets

>    restart;

>    FzSet := FuzzySets[FiniteDomain]( 0.5*i, i=0..20 ):

>    with( FzSet ):

Warning, these protected names have been redefined and unprotected: implies, intersect, minus, plot, subset, union

>   

Constructors

FuzzySet Constructor

The constructor FuzzySet  takes a sequence of the form x = y  where `in`(x,U)  and y  is a fuzzy value.

>    S := FuzzySet( 0.5 = 0.3 );

S := PIECEWISE([r = .5, .3])

>    T := FuzzySet( 1.0 = 0.5, 2.0 = 0.5 );

T := PIECEWISE([r = 1.0, .5],[r = 2.0, .5])

>    V := FuzzySet( 1/3 = 0.3 ); # Error

V := PIECEWISE([r = .5, .3])

>    W := FuzzySet( 1/2 = 1.2 ); # Error

Error, (in FuzzySet) the value 1.2 is not a fuzzy value

Random

The constructor Random  returns a random fuzzy of the universal set.

>    R := Random():

The constructor Random takes a procedure which returns fuzzy values as a first argument.

>    R2 := Random( () -> rand(0..2)()/2 ):

>    plot( [R, R2] );

[Maple Plot]

Gamma

>    F1 := Gamma( 5, 9 ):

>    F2 := Gamma( 3, model=arctan ):

>    plot( [F1, F2] );

[Maple Plot]

L

>    F1 := L( 2, 5 ):

>    F2 := L( 7, model=arctan ):

>    plot( [F1, F2] );

[Maple Plot]

Lambda

With finite fuzzy sets, it is not guaranteed that one of the elements will reach maximum unless the appropriate argument is an element in the universal set.

>    F1 := Lambda( 1, 3.2, 6.7 ):

>    F2 := Lambda( 6, model=exp[0.2] ):

>    plot( [F1, F2] );

[Maple Plot]

PI

>    F1 := PI( 2, 4, 6, 12 ):

>    F2 := PI( 7, 8, model=exp ):

>    plot( [F1, F2] );

[Maple Plot]

Plotting

>    plot( T );

[Maple Plot]

>    plot( R );

[Maple Plot]

Operators on Fuzzy Sets with a Finite Numeric Domain

The properites of the operators are identical to the descriptions given in the section Operators on Fuzzy Sets with a Real Domain .

>    S := Lambda( 3, 5, 7 ):

>    T := Lambda( 2, 6, 10 ):

>    plot( [S, T] );

[Maple Plot]

Union (union)

>    plot( S union T );

[Maple Plot]

>    plot( S union 0.2 );

[Maple Plot]

Intersection (intersect)

>    plot( [S intersect T, T intersect 0.2] );

[Maple Plot]

Implication (implies)

>    plot( [S implies T, T implies S] );

[Maple Plot]

Membership (in)

>    0.5 in S;

0.

>    2.0 in S;

0.

>    1.7 in S;

0.

>    -10 in S;

`in`(-10,PIECEWISE([r = 3.5, .250000000],[r = 4.0, .500000000],[r = 4.5, .750000000],[r = 5.0, 1.000000000],[r = 5.5, .750000000],[r = 6.0, .500000000],[r = 6.5, .250000000]))

Set Minus (minus)

>    plot( [S minus T, T minus S] );

[Maple Plot]

>    plot( 0.9 minus T );

[Maple Plot]

Subset (subset)

>    T subset S;

false

>    S subset T;

false

>    (S minus T) subset T;

true

>    T subset 1;

true

>    0 subset S;

true

Functions on Fuzzy Sets with a Finite Numeric Domain

Unless stated otherwise, the properites of these functions are identical to the descriptions given in the section Operators on Fuzzy Sets with a Real Domain .

>    S := Lambda( 3, 5, 7 ):

>    T := Lambda( 2, 6, 10 ):

Complement

The complement of a fuzzy set is the set whose membership function is mu[Complement(S)](x) = (not mu[S](x)) .

>    plot( Complement( S ) );

[Maple Plot]

>    plot( Complement( T ) );

[Maple Plot]

>    Complement( 1/3 );

2/3

Converting Fuzzy Sets to Table of Fuzzy Values ( mu )

As discrete values cannot easily be turned into an expression, this procedure returns a table indexed by the elements of the universal set with entries equal to their fuzzy values.

>    mu[S]();

TABLE([3.0 = 0., 6.0 = .500000000, 3.5 = .250000000, 6.5 = .250000000, 4.0 = .500000000, 7.0 = 0., 4.5 = .750000000, 7.5 = 0., 0. = 0., 5.0 = 1.000000000, 8.0 = 0., 5.5 = .750000000, 8.5 = 0., 1.0 = 0....
TABLE([3.0 = 0., 6.0 = .500000000, 3.5 = .250000000, 6.5 = .250000000, 4.0 = .500000000, 7.0 = 0., 4.5 = .750000000, 7.5 = 0., 0. = 0., 5.0 = 1.000000000, 8.0 = 0., 5.5 = .750000000, 8.5 = 0., 1.0 = 0....
TABLE([3.0 = 0., 6.0 = .500000000, 3.5 = .250000000, 6.5 = .250000000, 4.0 = .500000000, 7.0 = 0., 4.5 = .750000000, 7.5 = 0., 0. = 0., 5.0 = 1.000000000, 8.0 = 0., 5.5 = .750000000, 8.5 = 0., 1.0 = 0....
TABLE([3.0 = 0., 6.0 = .500000000, 3.5 = .250000000, 6.5 = .250000000, 4.0 = .500000000, 7.0 = 0., 4.5 = .750000000, 7.5 = 0., 0. = 0., 5.0 = 1.000000000, 8.0 = 0., 5.5 = .750000000, 8.5 = 0., 1.0 = 0....

>    mu[1/2]();

TABLE([3.0 = 1/2, 6.0 = 1/2, 3.5 = 1/2, 6.5 = 1/2, 4.0 = 1/2, 7.0 = 1/2, 4.5 = 1/2, 7.5 = 1/2, 0. = 1/2, 5.0 = 1/2, 8.0 = 1/2, 5.5 = 1/2, 8.5 = 1/2, 1.0 = 1/2, .5 = 1/2, 9.0 = 1/2, 1.5 = 1/2, 9.5 = 1/2...
TABLE([3.0 = 1/2, 6.0 = 1/2, 3.5 = 1/2, 6.5 = 1/2, 4.0 = 1/2, 7.0 = 1/2, 4.5 = 1/2, 7.5 = 1/2, 0. = 1/2, 5.0 = 1/2, 8.0 = 1/2, 5.5 = 1/2, 8.5 = 1/2, 1.0 = 1/2, .5 = 1/2, 9.0 = 1/2, 1.5 = 1/2, 9.5 = 1/2...
TABLE([3.0 = 1/2, 6.0 = 1/2, 3.5 = 1/2, 6.5 = 1/2, 4.0 = 1/2, 7.0 = 1/2, 4.5 = 1/2, 7.5 = 1/2, 0. = 1/2, 5.0 = 1/2, 8.0 = 1/2, 5.5 = 1/2, 8.5 = 1/2, 1.0 = 1/2, .5 = 1/2, 9.0 = 1/2, 1.5 = 1/2, 9.5 = 1/2...
TABLE([3.0 = 1/2, 6.0 = 1/2, 3.5 = 1/2, 6.5 = 1/2, 4.0 = 1/2, 7.0 = 1/2, 4.5 = 1/2, 7.5 = 1/2, 0. = 1/2, 5.0 = 1/2, 8.0 = 1/2, 5.5 = 1/2, 8.5 = 1/2, 1.0 = 1/2, .5 = 1/2, 9.0 = 1/2, 1.5 = 1/2, 9.5 = 1/2...

Defuzzify

There are three methods to defuzzify a fuzzy set on a finite non-numeric domain: center of gravity, center of area, and maximum.
For the first two, the option
nearest  = true  selects the closest element in the Universal set.  If there is more than one such element, the average of the two closest is returned.
For the third method has five modifiers:  
maximum(smallest) , maximum(largest) , maximum(mean) , maximum(random) , and maximum(set) .  These methods return

    the smallest of all maxima,

    the mean of all maxima,
    the largest of all maxima,

    a random selection of the maxima, and

    a set of all maxima,

respectively.

>    V := PI( 3, 5, 8.5, 12 ):

>    plot( V );

[Maple Plot]

>    Defuzzify( S, method = gravity );

5.000000000

>    Defuzzify( S, method = area );

4.750000000

>    Defuzzify( S, method = maximum(random) );

5.0

>    Defuzzify( T, method = maximum(set) );

{6.0}

>    Defuzzify( T, method = area );

5.750000000

Return all maxima in a set.

>    Defuzzify( V, method = maximum(set) );

{6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 5.0, 5.5}

If there is more than one maxima, chose one randomly.

>    Defuzzify( V, method = maximum(random) );

7.0

Return the smallest of the maxima.

>    Defuzzify( V, method = maximum(smallest) );

5.0

Return the largest of the maxima.

>    Defuzzify( V, method = maximum(largest) );

8.5

Return the mean of the maxima.

>    Defuzzify( V, method = maximum(mean) );

8.5

>    Defuzzify( V, method = gravity );

6.911042945

Cut

>    plot( Cut( S, 1/2 ) );

[Maple Plot]

>    plot( Cut( S, 0.7 ) );

[Maple Plot]

>    plot( Cut( S, 0.1, crisp ) );

[Maple Plot]

>    plot( Cut( T, 0.5, strong ) ); # does not include 0.5

[Maple Plot]

>    plot( Cut( T, 0.45 ) );

[Maple Plot]

>    plot( Cut( T, 0.2, crisp ) );

[Maple Plot]

Core

For fuzzy sets with a finite domain, the core is returned as a set of all elements which have a membership of 1.

>    Core( S );

{4.5}

>    Core( Cut( T, 0.2, crisp ) );

{6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 2.5}

Support

For fuzzy sets with a finite domain, the support is returned as a set of all elements which have nonzero membersip.

>    Support( S );

{6.0, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5}

>    Support( T );

{9.0, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 2.0, 2.5}

Height

>    Height( S );

1.000000000

>    Height( T );

1.000000000

>    Height( 1/2 );

1/2

Normalize

>    Normalize( S );

PIECEWISE([r = 3.5, .2500000000],[r = 4.0, .5000000000],[r = 4.5, .7500000000],[r = 5.0, 1.000000000],[r = 5.5, .7500000000],[r = 6.0, .5000000000],[r = 6.5, .2500000000])

>    R := Random():

>    plot( [R, Normalize(R)] );

[Maple Plot]

>    Normalize( 1/2 );

1

>    Normalize( 0 );

0

Concentrate

>    plot( [S, Concentrate( S )] );

[Maple Plot]

>    plot( [T, Concentrate( T )] );

[Maple Plot]

>    Concentrate( 1/2 );

1/2*2^(1/2)

Dilate

>    plot( [S, Dilate( S )] );

[Maple Plot]

>    plot( [T, Dilate( T )] );

[Maple Plot]

>    Dilate( 1/2 );

1/2*2^(1/2)

Intensify Contrast

>    plot( [S, IntensifyContrast( S )] );

[Maple Plot]

>    plot( [T, IntensifyContrast( T )] );

[Maple Plot]

>    IntensifyContrast( FuzzySet( 0.5 = 0.7, 1.0 = 0.9, 1.5 = 0.3 ) );

PIECEWISE([r = .5, .82],[r = 1.0, .98],[r = 1.5, .18])

Tools Package

The Tools  package deals with those features relevant to all types of fuzzy sets.  Thus, it deals with t-  and s-norms , negations , and implications , which are used by the Logic  and RealDomain  packages and the packages returned by the FiniteDomain  routine.

>    restart;

>    with( FuzzySets[Tools] );

[AddClass, AddComplement, AddGammaModel, AddImplication, AddInference, AddLModel, AddLambdaModel, AddPIModel, AddSNorm, AddTNorm, GetClass, GetClasses, GetComplement, GetComplements, GetImplication, Ge...
[AddClass, AddComplement, AddGammaModel, AddImplication, AddInference, AddLModel, AddLambdaModel, AddPIModel, AddSNorm, AddTNorm, GetClass, GetClasses, GetComplement, GetComplements, GetImplication, Ge...
[AddClass, AddComplement, AddGammaModel, AddImplication, AddInference, AddLModel, AddLambdaModel, AddPIModel, AddSNorm, AddTNorm, GetClass, GetClasses, GetComplement, GetComplements, GetImplication, Ge...

>    with( FuzzySets[Logic] );

Warning, these protected names have been redefined and unprotected: and, evalb, implies, not, or

[`and`, booleanum, evalb, evalfz, `implies`, `not`, `or`]

>   

T-Norms and S-Norms

An Introduction To T-Norms and S-Norms

Up until now, we've used min  and max  to calculate operations on two fuzzy numbers.

In general, we may use
triangular-norms  ( t-norms ) and s-norms  (or t-conorms ) to define or  and and , respectively.

An s-norm s :[0,1] x  ( or ) must satisfy:
  1.  Symmetry:  s(x, y) = s(y, x)
  2.  Associativity:  s(x, s(y, z)) = s(s(x, y), z)
  3.  Boundary conditions:  
s(x, 0) = x  and s(x, 1) = 1
  4.  Monotonicity:  if
x <= v  and y <= w  then s(x,y) <= s(v,w)

A t-norm (
and ) must satisfy:
  1.  Symmetry:  
t(x,y) = t(y,x)
  2.  Associativity:  
t(x,t(y,z)) = t(t(x,y),z)
  3.  Boundary conditions:  
t(x,1) = x  and t(x,0) = 0
  4.  Monotonicity:  if
x <= v  and y <= w  then t(x,y) <= t(v,w)  

The default
s-  and t-norms  are s[default](x,y) = max(x,y)  and t[default](x,y) = min(x,y) , respectively.
The drastic sum
s-  and t-norms  are defined as s[drastic](x,y) = PIECEWISE([x, y = 0],[y, x = 0],[1, otherwise])  and t[drastic] = PIECEWISE([x, y = 1],[y, x = 1],[0, otherwise]) .


Theorem
For any s-norm
s  and t-norm t , the following inequalities holds:
    
s[default](x,y) <= s(x,y) `` <= s[drastic](x,y)  
    
s[drastic](x,y) <= s(x,y) `` <= s[default](x,y)

The Dombi s-  and t-norms  with parameter `in`(k,``) (0, infinity ) are s[Dombi,k](x,y) = 1/((1+(1/x-1)^(-k)+(1/y-1)^(-k))^(-1/k))  and t[Dombi,k](x,y) = 1/((1+(1/x-1)^k+(1/y-1)^k)^(1/k)) .


Theorem
The Dombi s- and t-norms have the properties that:
    
limit(s[Dombi,k](x,y),k = 0) = s[drastic](x,y) ,
    
limit(s[Dombi,k](x,y),k = infinity) = max(x,y) .
    
limit(t[Dombi,k](x,y),k = 0) = t[drastic](x,y) , and
    
limit(t[Dombi,k](x,y),k = infinity) = min(x,y) .


The available norms are given here:

default
    
min(x,y), max(x,y)
Hamacher
    
x*y/(x+y-x*y), (x+y-2*x*y)/(1-x*y)
algebraic
    
x*y, x+y-x*y

Einstein
    
x*y/(1+(1-x)*(1-y)), (x+y)/(1+x*y)
bounded
    
max(0,x+y-1), min(1,x+y)

To use any of these alternate norms, use the UseNorm function with the argument being the norm you wish to use.

Warning:  some norms are more complicated and others and may not result in objects which Maple can work with.

>    with( FuzzySets[RealDomain] ):

Warning, the name implies has been rebound

Warning, these protected names have been redefined and unprotected: intersect, minus, plot, subset, union

>    S := Gamma( 3, 5 );

S := PIECEWISE([0, r <= 3],[1/2*r-3/2, r < 5],[1, otherwise])

>    T := L( 3, 5 );

T := PIECEWISE([1, r <= 3],[-1/2*r+5/2, r < 5],[0, otherwise])

>    plot( [S, T, S minus T, S union T, S intersect T], 0..10 );

[Maple Plot]

>    FuzzySets:-Tools:-UseSNorm( algebraic );
FuzzySets:-Tools:-UseTNorm( algebraic );

default

default

>    plot( [S, T, S minus T, S union T, S intersect T], 0..10, numpoints=1000 );

[Maple Plot]

>    FuzzySets:-Tools:-UseSNorm( default );
FuzzySets:-Tools:-UseTNorm( default );

algebraic

algebraic

Use Norms

The routine UseNorm  can be used to change the default norm being used.  Available norms are listed by the GetNorms  routine.

For simple norms (t- and s-norms) not taking any parameters, the calling sequence is:

>    FuzzySets:-Tools:-UseSNorm( bounded );
FuzzySets:-Tools:-UseTNorm( bounded );

default

default

The return value is the previously used norm.

>    FuzzySets:-Tools:-UseSNorm( default );
FuzzySets:-Tools:-UseTNorm( default );

bounded

bounded

Norms may be parameterized, in which case, the parameters are passed by indexing the name of the norm with the parameters.
For an example of this, see the
AddNorm  section.

Programming with UseNorm

If you are programming and using fuzzy sets as part of a procedure, if you are changing the norm, it is good programming practice not to change the user's environment behind his or her back.  For example, most users would be annoyed if calling your procedure assigned the global variable x := 3; .  In the same way, if you change norm being used, change it back before your procedure exits.  The following code gives some examples:

>    MyProc := proc()
    local oldnorm;

    # some code

    try
        oldnorm := FuzzySets:-Tools:-UseNorm( newnorm );

        use FuzzySets:-Logic, FuzzySets:-RealDomain in
            # some more code using Fuzzy Sets
        end use;
    finally:
        FuzzySets:-Tools:-UseNorm( oldnorm );
    end try;

    # some more code
end proc:

In almost all cases, the finally statement is executed, even if an exception was thrown.  
And please, never, never, never use
with  inside of a procedure; use use .

Get S- and T-Norms

The routines GetSNorms  and GetTNorms  return an expression sequence of all available s- and t-norms, respectively.

>    GetSNorms();

algebraic, bounded, default, Dombi, drastic, DuboisPrade, Einstein, Hamacher, Weber, Yager, Yu

>    GetTNorms();

algebraic, bounded, default, Dombi, drastic, DuboisPrade, Einstein, Hamacher, Weber, Yager, Yu

Plotting S- and T-Norms

>    with( FuzzySets:-Tools );

[AddClass, AddComplement, AddGammaModel, AddImplication, AddInference, AddLModel, AddLambdaModel, AddPIModel, AddSNorm, AddTNorm, GetClass, GetClasses, GetComplement, GetComplements, GetImplication, Ge...
[AddClass, AddComplement, AddGammaModel, AddImplication, AddInference, AddLModel, AddLambdaModel, AddPIModel, AddSNorm, AddTNorm, GetClass, GetClasses, GetComplement, GetComplements, GetImplication, Ge...
[AddClass, AddComplement, AddGammaModel, AddImplication, AddInference, AddLModel, AddLambdaModel, AddPIModel, AddSNorm, AddTNorm, GetClass, GetClasses, GetComplement, GetComplements, GetImplication, Ge...
[AddClass, AddComplement, AddGammaModel, AddImplication, AddInference, AddLModel, AddLambdaModel, AddPIModel, AddSNorm, AddTNorm, GetClass, GetClasses, GetComplement, GetComplements, GetImplication, Ge...

>    PlotSNorm( algebraic, axes = box );

[Maple Plot]

>    PlotTNorm( algebraic, axes = box );

[Maple Plot]

Add Norm

The procedure AddNorm allows you to add new t- and s-norms (t-conorms).

>    AddSNorm( mynorm, (x, y) -> max( 0, -1 + x + y ) );
AddTNorm( mynorm, (x, y) -> min( x + y, 1 ) );

>    UseSNorm( mynorm );
UseTNorm( mynorm );

default

default

>    with( FuzzySets[Logic] );

Warning, the name implies has been rebound

[`and`, booleanum, evalb, evalfz, `implies`, `not`, `or`]

>    1 and 0;

1

>    0 or 0.5;

0.

>    PlotTNorm( mynorm );

[Maple Plot]

>    PlotSNorm( mynorm );

[Maple Plot]

Implications

Use Implication

>   

Add Implication

>   

Get Implications

This procedure takes no arguments and returns an expression sequence of all available implications.

>    GetImplications();

algebraic, bounded, default, Dombi, DuboisPrade, Einstein, Goedelian, Gougen, Hamacher, Larson, Lukasiewicz, Mamdani, sequence, Weber, Yager, Yu, Zadeh
algebraic, bounded, default, Dombi, DuboisPrade, Einstein, Goedelian, Gougen, Hamacher, Larson, Lukasiewicz, Mamdani, sequence, Weber, Yager, Yu, Zadeh

Many of these negations are more general than their

Plot Implication

>    PlotImplication( default );

[Maple Plot]

Complement

The negation of a fuzzy value is the amount to which that value is not true.

A negation
n :[0,1] -> [0, 1] ( not ) must satisfy:
  1.  Boundary conditions:  
n(0) = 1  and n(1) = 0  
  2.  Monotonicity:  if
x <= y  then n(y) <= n(x) .

Theorem
Each negation
n  has a unique equilibrium point `in`(x,[0, 1])  such that n(x) = x .

By default, the negation of a fuzzy value
r  is 1-r .

Use Complement

The UseComplement routine takes one argument that defines a negation to be used.
The return value is the negation that was previously being used.

>    UseComplement( cos );

default

>    not 0.3;

.7938926261

>    not %;

.1012044945

Note that it is not always true that (not not x) = x , as is demonstrated above.

Some negations may use parameters, which are specified by giving the name of the negation an index:

>    UseComplement( Yager[1.3] );

cos

>    not 0.3;

.8349329178

>    not %;

.3000000000

Get Complements

The GetComplements  routine takes no arguments and returns an expression sequence of all available negations.

>    GetComplements();

cos, default, Sugeno, Yager

Plotting Complements

The PlotComplement  routine plots one or more negations from [0, 1] to [0, 1].

>    PlotComplement( [default, cos, Yager[1.2], Yager[1.4]], color = [red, blue, grey, black], legend = ["Default", "Cosine", "Yager 1.2", "Yager 1.4"] );

[Maple Plot]

Add Complement

You can add new negations by using the AddComplement  routine.  It takes two arguments:  a symbol denoting the negation and an operator.
By definition, a negation should be a function that decreases monotonically from 1 to 0 on the interval
[0, 1] .
If the negation uses parameters, the parameters must be the 2nd, 3rd, and subsequent arguments of the parameter.
This example adds a negation called
step  that takes one parameter a  that should be in the interval ``(0,1) .

>    AddComplement( mystep, (x, a) -> piecewise( x < a, 1, 0 ), properties = [RealRange( Open(0), Open(1) )] );

>    UseComplement( mystep[0.3] );

Yager[1.3]

>    not 0.2;

1.

>    not 0.3;

0.

>    not 0.9;

0.

>    UseComplement( mystep[1.3] ); # Error

Error, (in FuzzySets:-Tools:-UseComplement) the parameter 1.3 should have the property RealRange(Open(0),Open(1))

Associated Classes

A triplet s-norm s, t-norm t and negation n form an associated class  if
      
n(s(x,y)) = t(n(x),n(y)) ,
that is, DeMorgan's law
    
(not (x or y)) = (not x) and not y
holds.

Models

The tools package also has routines for adding different models for the various constructors.
We will demonstrate this with the
FuzzySets[RealDomain]  package.

>    restart;

>    with( FuzzySets[Tools] ):

>    with( FuzzySets[RealDomain] ):

Warning, these protected names have been redefined and unprotected: implies, intersect, minus, plot, subset, union

Adding Gamma Models

The Gamma  constructor will recognize the first argument as a model for a fuzzy set where membership approaches 0  as the element approaches -infinity  and 1  as the element approaches infinity .

>    AddGammaModel( cos, (r, a, b) -> ( r < a, 0, r < b, 1/2 + cos( -Pi*(r-b)/(a-b) )/2, 1 ) );  

>    Gamma( 1, 2, model = cos );

PIECEWISE([0, r < 1],[1/2+1/2*cos(Pi*(r-2)), r < 2],[1, otherwise])

>    plot( %, 0..3 );

[Maple Plot]

Adding L Models

The L  constructor will recognize the first argument as a model for a fuzzy set where membership approaches 1  as the element approaches -infinity  and 0  as the element approaches infinity .

>    AddLModel( cos, (r, a, b) -> ( r < a, 1, r < b, 1/2 - cos( -Pi*(r-b)/(a-b) )/2, 0 ) );  

>    L( 1, 2, model = cos );

PIECEWISE([1, r < 1],[1/2-1/2*cos(Pi*(r-2)), r < 2],[0, otherwise])

>    plot( %, 0..3 );

[Maple Plot]

Adding Lambda Models

The Lambda  constructor will recognize the first argument as a model for a fuzzy set where membership equals 1  for a specific element and approaches and 0  as the elements approach infinity  or -infinity .

>    AddLambdaModel( cos, (r, a, b, c) -> (
    r < a, 0, r < b, 1/2 + cos( -Pi*(r-b)/(a-b) )/2, r < c, 1/2 - cos( -Pi*(r-c)/(b-c) )/2, 0
) );  

>    Lambda( 1, 2, 3, model = cos );

PIECEWISE([0, r < 1],[1/2+1/2*cos(Pi*(r-2)), r < 2],[1/2-1/2*cos(Pi*(r-3)), r < 3],[0, otherwise])

>    plot( %, 0..4 );

[Maple Plot]

Adding PI Models

The PI  constructor will recognize the first argument as a model for a fuzzy set where membership equals 1  for a specific element and approaches and 0  as the elements approach infinity  or -infinity .

>    AddPIModel( cos, (r, a, b, c, d) -> (
    r < a, 0, r < b, 1/2 + cos( -Pi*(r-b)/(a-b) )/2, r < c, 1, r < d, 1/2 - cos( -Pi*(r-d)/(c-d) )/2, 0
) );  

>    PI( 1, 2, 3, 4, model = cos );

PIECEWISE([0, r < 1],[1/2+1/2*cos(Pi*(r-2)), r < 2],[1, r < 3],[1/2-1/2*cos(Pi*(r-4)), r < 4],[0, otherwise])

>    plot( %, 0..5 );

[Maple Plot]

Example of a Fuzzy Controller for an Inverted Pendulum

The classic example for demonstrating fuzzy sets is the control of an inverted pendulum mounted on a carriage.
We have control of the velocity of the carriage and the object is to control the system to keep the inverted pendulum from falling down.

                [Maple OLE 2.0 Object]

Let the angle theta  be represented by the fuzzy sets angleXY , the derivatives of theta  by the fuzzy sets derivXY  and the resulting velocities by the fuzzy sets velocityXY  where XY  may be one of:

     NL       negative large
    
NM       negative medium
    
NS       negative small
    
AZ       approximately zero
    
PS       positive small
    
PM       positive medium
    
PL       positive large

>    restart;

>    with( FuzzySets[RealDomain] ):

Warning, these protected names have been redefined and unprotected: implies, intersect, minus, plot, subset, union

We define the following fuzzy sets describing the angles in degrees:

>    (
  angleNL,
  angleNM, angleNS, angleAZ, anglePS, anglePM,
  anglePL
) := (
  L( -30, -20 ),
  Partition( -30, -20, -10, 0, 10, 20, 30 ),
  Gamma( 20, 30 )
):

>    plot( [
  angleNL, angleNM, angleNS, angleAZ, anglePS, anglePM, anglePL
], -40..40 );

[Maple Plot]

Next, we define the following sets which describe the rate of change of the angle in degrees per second:

>    (
  derivNL,
  derivNM, derivNS, derivAZ, derivPS, derivPM,
  derivPL
) := (
  L( -30, -20 ),
  Partition( -30, -20, -10, 0, 10, 20, 30 ),
  Gamma( 20, 30 )
):

>    plot( [
  derivNL, derivNM, derivNS, derivAZ, derivPS, derivPM, derivPL
], -45..45 );

[Maple Plot]

Finally, we define the velocity of the carriage carrying the pendulum in metres per second:

>    (
  accelerationNL,
  accelerationNM, accelerationNS, accelerationAZ, accelerationPS, accelerationPM,
  accelerationPL
) := Partition( -16, -12, -8, -4, 0, 4, 8, 12, 16 ):

>    plot( [
  accelerationNL, accelerationNM, accelerationNS, accelerationAZ,
  accelerationPS, accelerationPM, accelerationPL
], -17..17 );

[Maple Plot]

We need a set of rules.
For example, the first rule says:
     If the angle is negative and small and the rate of change of angle is negative and large, then move the carriage in the positive direction slowly.

>    Rules := Controller(
  (angleNM, derivAZ) = accelerationNM,
  (angleNS, derivAZ) = accelerationNS,
  (angleAZ, derivAZ) = accelerationAZ,
  (anglePS, derivAZ) = accelerationPS,
  (anglePM, derivAZ) = accelerationPM,

  (angleNM, derivPS) = accelerationNS,
  (angleNS, derivPS) = accelerationAZ,
  (angleAZ, derivPS) = accelerationPS,
  (anglePS, derivPS) = accelerationPM,

  (angleNS, derivNS) = accelerationNM,
  (angleAZ, derivNS) = accelerationNS,
  (anglePS, derivNS) = accelerationAZ,
  (anglePM, derivNS) = accelerationPS,
  inference = minimum
):

Suppose we have an angle of -13^o  and the rate of change of the angle is -2.1^o/s .

>    soln := Rules( -13, -2.1 );

soln := PIECEWISE([0., r <= -12],[.2500000000*r+3., r <= -10.80000000],[.3000000000, r <= -6.800000000],[.2500000000*r+2., r <= -5.200000000],[.7000000000, r < -2.800000000],[-.2500000000*r, r < 0],[0....

We set the solution fuzzy set to be 0 and then check the degree membership of this pair for each pair of fuzzy sets we have defined in the set of rules.
We intersect the minimum of the two memberships of the the rule and union this result with our solution.

The result is the nonzero fuzzy set:

>    plot( soln, -17..1, view=[DEFAULT, 0..1], numpoints = 1000 );

[Maple Plot]

We can convert this fuzzy set into a real value using the Defuzzify  function:

>    Defuzzify( soln );

-5.338842975

Thus, we should move the carriage backward at a speed of 1.8 m/s.

>    InvertedPendulum := proc( initial_angle, initial_angular_velocity, controller, iterations )
  local position, velocity, angle, angular_velocity, dt, plotvehicle, plotlist, i, acceleration, angular_acceleration;

  position := 0;
  velocity := 0;
  angle := evalf( Pi*initial_angle/180 );
  angular_velocity := evalf( Pi*initial_angular_velocity/180 );

  dt := 60.0/1000.0;  # animations run at approximately 1000 frames per minute

  plotvehicle := proc( posn, a, angular_velocity )
    local x, y;

    x := sin(a);
    y := cos(a);
    plots[display](
      plots[pointplot]( [[posn, 0], [posn + x, y]], symbol = circle, symbolsize = 20 ),
      plots[pointplot]( [[-1, 0], [1, 0]] ),
      plottools[line]( [posn, 0], [posn + x, y] ),
      plots[textplot]( [0.5, 1.2, sprintf( "% 3d deg, % 3d deg/s", round( evalf( a*180/Pi ) ), round( evalf( angular_velocity*180/Pi ) ) )] ),
      scaling = constrained
    );
  end proc;

  plotlist := Vector( 1..iterations + 1 );
  plotlist[1] := plotvehicle( position, angle, angular_velocity );

  for i from 2 to iterations + 1 do
    try
      acceleration := 1.5*Defuzzify( controller( angle*180/3.14, angular_velocity*180/3.14 ), -100..100, evalf );
    catch:
      acceleration := 0;
    end try;

    angular_acceleration := 9.8 * sin( angle ) - acceleration * cos( angle );
    angular_velocity := angular_velocity + angular_acceleration * dt - 0.02 * angular_velocity;
    angle := angle + angular_velocity * dt;
    if i mod 100 = 0 then print( i ); end if;
    velocity := velocity + acceleration * dt;
    position := position + velocity * dt;
    plotlist[i] := plotvehicle( position, angle, angular_velocity );
  end do;

  plots[display]( seq( plotlist[i], i = 1..(i - 1) ), insequence = true, scaling = constrained );
end proc:

>    InvertedPendulum( -10, 40, Rules, 100 );

100

[Maple Plot]

>    ProductRules := Controller(
  (angleNM, derivAZ) = accelerationNL,
  (angleNS, derivAZ) = accelerationNS,
  (angleAZ, derivAZ) = accelerationAZ,
  (anglePS, derivAZ) = accelerationPS,
  (anglePM, derivAZ) = accelerationPL,

  (angleNM, derivPS) = accelerationNS,
  (angleNS, derivPS) = accelerationAZ,
  (angleAZ, derivPS) = accelerationPS,
  (anglePS, derivPS) = accelerationPL,

  (angleNS, derivNS) = accelerationNL,
  (angleAZ, derivNS) = accelerationNS,
  (anglePS, derivNS) = accelerationAZ,
  (anglePM, derivNS) = accelerationPS,
  inference = product
):

>    InvertedPendulum( -10, 40, ProductRules, 100 );

100

[Maple Plot]

>    solnP := ProductRules( -13, -2.1 );

solnP := PIECEWISE([0., r <= -16],[.5925000000e-1*r+.9480000000, r < -12],[-.5925000000e-1*r-.4740000000, r <= -8],[.1382500000*r+1.106000000, r < -4],[-.1382500000*r, r < 0],[0., otherwise])

>    plot( solnP, -20..10, 0..1 );

[Maple Plot]

A Faster Fuzzy Controller for an Inverted Pendulum

The RealDomain  package is designed to use symbolic algebra, and therefore will be relatively slow.  Generating a package which works with fuzzy subsets of a finite domain is significantly faster:  

>    restart;

>    FzS := FuzzySets[FiniteDomain]( i, i = -45..45 ):

>    with( FzS ):

Warning, these protected names have been redefined and unprotected: implies, intersect, minus, plot, subset, union

>    (
  angleNL,
  angleNM, angleNS, angleAZ, anglePS, anglePM,
  anglePL
) := (
  L( -30, -20 ),
  Partition( -30, -20, -10, 0, 10, 20, 30 ),
  Gamma( 20, 30 )
):

>    (
  derivNL,
  derivNM, derivNS, derivAZ, derivPS, derivPM,
  derivPL
) := (
  L( -30, -20 ),
  Partition( -30, -20, -10, 0, 10, 20, 30 ),
  Gamma( 20, 30 )
):

>    (
  accelerationNL,
  accelerationNM, accelerationNS, accelerationAZ, accelerationPS, accelerationPM,
  accelerationPL
) := Partition( -16, -12, -8, -4, 0, 4, 8, 12, 16 ):

>    Rules := Controller(
  (angleNM, derivAZ) = accelerationNM,
  (angleNS, derivAZ) = accelerationNS,
  (angleAZ, derivAZ) = accelerationAZ,
  (anglePS, derivAZ) = accelerationPS,
  (anglePM, derivAZ) = accelerationPM,

  (angleNM, derivPS) = accelerationNS,
  (angleNS, derivPS) = accelerationAZ,
  (angleAZ, derivPS) = accelerationPS,
  (anglePS, derivPS) = accelerationPM,

  (angleNS, derivNS) = accelerationNM,
  (angleAZ, derivNS) = accelerationNS,
  (anglePS, derivNS) = accelerationAZ,
  (anglePM, derivNS) = accelerationPS,
  inference = minimum
):

>    soln := Rules( -13, -2.1 ):

>    plot( soln, -17..1 );

[Maple Plot]

>    Defuzzify( soln );

-16/3

The defuzzified value is very close to the value found using fuzzy sets on the real domain:   -5.338842975 .

>    evalf(%);

-5.333333333

>    InvertedPendulum := proc( initial_angle, initial_angular_velocity, controller, iterations )
  local position, velocity, angle, angular_velocity, dt, plotvehicle, plotlist, i, acceleration, angular_acceleration;

  position := 0;
  velocity := 0;
  angle := evalf( Pi*initial_angle/180 );
  angular_velocity := evalf( Pi*initial_angular_velocity/180 );

  dt := 60.0/1000.0;  # animations run at approximately 1000 frames per minute

  plotvehicle := proc( posn, a, angular_velocity )
    local x, y;

    x := sin(a);
    y := cos(a);
    plots[display](
      plots[pointplot]( [[posn, 0], [posn + x, y]], symbol = circle, symbolsize = 20 ),
      plots[pointplot]( [[-1, 0], [1, 0]] ),
      plottools[line]( [posn, 0], [posn + x, y] ),
      plots[textplot]( [0.5, 1.2, sprintf( "% 3d deg, % 3d deg/s", round( evalf( a*180/Pi ) ), round( evalf( angular_velocity*180/Pi ) ) )] ),
      scaling = constrained
    );
  end proc;

  plotlist := Vector( 1..iterations + 1 );
  plotlist[1] := plotvehicle( position, angle, angular_velocity );

  for i from 2 to iterations + 1 do
    try
      acceleration := 1.5*Defuzzify( controller( angle*180/3.14, angular_velocity*180/3.14 ) );
    catch:
      acceleration := 0;
    end try;

    angular_acceleration := 9.8 * sin( angle ) - acceleration * cos( angle );
    angular_velocity := angular_velocity + angular_acceleration * dt - 0.02 * angular_velocity;
    angle := angle + angular_velocity * dt;
    if i mod 100 = 0 then print( i ); end if;
    velocity := velocity + acceleration * dt;
    position := position + velocity * dt;
    plotlist[i] := plotvehicle( position, angle, angular_velocity );
  end do;

  plots[display]( seq( plotlist[i], i = 1..(i - 1) ), insequence = true, scaling = constrained );
end proc:

This command takes 25% the time of the RealDomain  version to run.

>    InvertedPendulum( -10, 40, Rules, 100 );

100

[Maple Plot]