Page 1 of 1

Fuzzy Logic function set

Posted: Sun May 10, 2009 6:11 pm
by Guimauve
Hello everyone,

This is a set of Fuzzy Logic function for use in developpement, but not limited to, AI systems.

Best Regards

Guimauve

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : FuzzyLogic function
; File Mame : Lib_FuzzyLogic.pb
; File Version : 1.0.0
; Programmation : OK
; Programmed by : Guimauve
; Date : 11-09-2007
; Last Update : 10-05-2009
; Coded for PureBasic V4.30
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Procedure.d FuzzyGrade(Value.d, x0.d, x1.d) 
  
  If Value <= x0 
    FuzzyResult.d = 0.0 
  ElseIf Value >= x1
    FuzzyResult = 1.0
  Else 
    FuzzyResult = (Value - x0) / (x1 - x0)
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

Procedure.d FuzzyReverseGrade(Value.d, x0.d, x1.d) 

  If Value <= x0 
    FuzzyResult.d = 1.0 
  ElseIf Value >= x1
    FuzzyResult = 0.0
  Else 
    FuzzyResult = (x1 - Value) / (x1 - x0)
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

Procedure.d FuzzyTriangle(Value.d, x0.d, x1.d, x2.d) 

  If Value <= x0 
    FuzzyResult.d = 0.0 
  ElseIf Value = x1
    FuzzyResult = 1.0
  ElseIf (Value > x0) And (Value < x1)
    FuzzyResult = (Value - x0) / (x1 - x0)
  ElseIf (Value > x1) And (Value < x2)
    FuzzyResult = (x2 - Value) / (x2 - x1)
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

Procedure.d FuzzyTrapezoid(Value.d, x0.d, x1.d, x2.d, x3.d) 
   
  If Value <= x0 
    FuzzyResult.d = 0.0 
  ElseIf (Value >= x1) And (Value <= x2)
    FuzzyResult = 1.0
  ElseIf (Value > x0) And (Value < x1) 
    FuzzyResult = (Value-x0) - / (x1 - x0)
  ElseIf (Value > x2) And (Value < x3) 
    FuzzyResult = (x3 - Value) / (x3 - x2)
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

Procedure.d FuzzyAND(A.d, B.d) 
  
  If A > B
    FuzzyResult.d = B
  ElseIf A <= B
    FuzzyResult = A
  Else 
    FuzzyResult = A
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

Procedure.d FuzzyOR(A.d, B.d) 
  
  If A < B
    FuzzyResult.d = B
  ElseIf A >= B
    FuzzyResult = A
  Else 
    FuzzyResult = A
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

Procedure.d FuzzyNOT(A.d) 
   
  ProcedureReturn 1.0 - A
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<

Posted: Sun May 10, 2009 8:14 pm
by Demivec
Just a note, you can get a 10% speed increase just by changing equations of the form:

Code: Select all

FuzzyResult = (Value/(x1 - x0)) - (x0/(x1 - x0))
;and
FuzzyResult = (-Value/(x3 - x2)) + (x3/(x3 - x2))
to:

Code: Select all

FuzzyResult = (Value - x0)/(x1 - x0)
;or
FuzzyResult = (x3 - Value)/(x3 - x2)

Posted: Sun May 10, 2009 9:44 pm
by idle
That could useful thanks.

Posted: Mon May 11, 2009 1:21 am
by Guimauve
Demivec wrote:Just a note, you can get a 10% speed increase just by changing equations of the form:

Code: Select all

FuzzyResult = (Value/(x1 - x0)) - (x0/(x1 - x0))
;and
FuzzyResult = (-Value/(x3 - x2)) + (x3/(x3 - x2))
to:

Code: Select all

FuzzyResult = (Value - x0)/(x1 - x0)
;or
FuzzyResult = (x3 - Value)/(x3 - x2)
It's done, see previous post.

Thanks

Best Regards

Guimauve

Posted: Mon May 11, 2009 1:40 pm
by Demivec
The procedures FuzzyTriangle() and FuzzyTrapezoid() seem to have some errors in their logic. This means they don't function properly. Here's one way that they can be rewritten:

Code: Select all

ProcedureDLL.d FuzzyTriangle(Value.d, x0.d, x1.d, x2.d)
  Protected FuzzyResult.d

  If Value = x1
    FuzzyResult = 1.0
  ElseIf Value <= x0 Or Value >= x2
    FuzzyResult = 0.0
  ElseIf (Value > x0) And (Value < x1)
    FuzzyResult = (Value - x0) / (x1 - x0)
  ElseIf (Value > x1) And (Value < x2)
    FuzzyResult = (x2 - Value) / (x2 - x1)
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

ProcedureDLL.d FuzzyTrapezoid(Value.d, x0.d, x1.d, x2.d, x3.d)
  Protected FuzzyResult.d
  
  If (Value >= x1) And (Value <= x2)
    FuzzyResult = 1.0
  ElseIf Value <= x0 Or Value >= x3 
    FuzzyResult = 0.0
  ElseIf (Value > x0) And (Value < x1)
    FuzzyResult = (Value - x0) / (x1 - x0)
  ElseIf (Value > x2) And (Value < x3)
    FuzzyResult = (x3 - Value) / (x3 - x2)
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure
This allows a value to be evaluated correctly where the peak of the triangle is over one of the ends (a right triangle). It also returns a value of 0.0 if the value is greater than the maximum range (outside the shape).

I've rewritten both of these functions with new variable names and supplied an optional height value (i.e. instead of a default value of 1.0, the optional height value would be returned instead) . I've also replaced the intermediate variable "FuzzyResult" and return the values directly. You may find some of these changes helpful

Code: Select all

ProcedureDLL.d FuzzyTriangle(Value.d, min.d, peak.d, max.d, height.d = 1.0)
  
  If Value = peak
    ProcedureReturn height
  ElseIf Value <= min Or Value >= max
    ProcedureReturn 0.0
  ElseIf (Value > min) And (Value < peak)
    ProcedureReturn ((Value - min) / (peak - min)) * height
  ElseIf (Value > peak) And (Value < max)
    ProcedureReturn ((max - Value) / (max - peak)) * height
  EndIf
  
EndProcedure

ProcedureDLL.d FuzzyTrapezoid(Value.d, lbMin.d, ubMin.d, ubMax.d, lbMax.d, height.d = 1.0)
  
  If (Value >= ubMin) And (Value <= ubMax)
    ProcedureReturn height
  ElseIf Value <= lbMin Or Value >= lbMax
    ProcedureReturn 0.0
  ElseIf (Value > lbMin) And (Value < ubMin)
    ProcedureReturn ((Value - lbMin) / (ubMin - lbMin)) * height
  ElseIf (Value > ubMax) And (Value < lbMax)
    ProcedureReturn ((lbMax - Value) / (lbMax - ubMax)) * height
  EndIf
  
EndProcedure
Were you thinking of implementing anything else? I thought about adding at least a few more functions such as FuzzyBell(), FuzzySigmoid(), and/or FuzzyGaussian().

Posted: Mon May 11, 2009 10:11 pm
by Guimauve
Demivec wrote:The procedures FuzzyTriangle() and FuzzyTrapezoid() seem to have some errors in their logic. This means they don't function properly.
The original function C source code came from "AI for Game Developers" book (www.oreilly.com). I have forget to include this information, sorry.
Demivec wrote:Were you thinking of implementing anything else? I thought about adding at least a few more functions such as FuzzyBell(), FuzzySigmoid(), and/or FuzzyGaussian().
Why not, but I'm very buzzy right now. You can add them if you wish.

Best Regards.

Guimauve

Posted: Fri May 15, 2009 3:03 am
by Guimauve
Hello everyone,

There is the FuzzyBell(), FuzzySigmoid(), FuzzyGaussian(), FuzzySmoothGrade() and FuzzySmoothReverseGrade() function.

Best Regards
Guimauve

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : More Fuzzy Logic Function
; File Name : More Fuzzy Logic Function.pb
; File Version : 1.0.0
; Programmation : OK
; Programmed by : Guimauve
; Date : 14-05-2009
; Last Update : 14-05-2009
; Coded for PureBasic V4.30
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Procedure.d FuzzyBell(Value.d, Va.d, Vb.d, Vc.d, ChopValue.d = 0.0001)
  
  FuzzyResult.d = 1/(1+Pow(Abs((Value-Vc)/Va),2*Vb))
  
  If FuzzyResult <= ChopValue
    FuzzyResult = 0.0
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

Procedure.d FuzzySigmoid(Value.d, Va01.d, Vc01.d, Va02.d, Vc02.d, ChopValue.d = 0.0001)
  
  FuzzyResult.d = (1.0/(1+Pow(2.71828182846, -Va01*(Value-Vc01)))) * (1.0/(1+Pow(2.71828182846, -Va02*(Value-Vc02))))
  
  If FuzzyResult <= ChopValue
    FuzzyResult = 0.0
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

Procedure.d FuzzyGaussian(Value.d, Mu01.d, Sigma01.d, ChopValue.d = 0.0001)
  
  FuzzyResult.d = Pow(2.71828182846, -((Value - Mu01)*(Value - Mu01))/(2*Sigma01*Sigma01))
  
  If FuzzyResult <= ChopValue
    FuzzyResult = 0.0
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

Procedure.d FuzzySmoothGrade(Value.d, Va.d, Vb.d) 
  
  If Value <= Va 
    FuzzyResult.d = 0.0 
  ElseIf Value >= Vb
    FuzzyResult = 1.0
  ElseIf (Value >= Va And Value <= (Va+Vb)/2) 
    FuzzyResult = 2*((Value - Va)/(Vb-Va))*((Value - Va)/(Vb-Va))
  ElseIf (Value >= (Va+Vb)/2 And Value <= Vb)
    FuzzyResult = 1 - 2*((Value - Vb)/(Vb-Va))*((Value - Vb)/(Vb-Va))
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

Procedure.d FuzzySmoothReverseGrade(Value.d, Va.d, Vb.d) 
  
  If Value <= Va 
    FuzzyResult.d = 1.0 
  ElseIf Value >= Vb
    FuzzyResult = 0.0
  ElseIf Value >= Va And Value <= (Va+Vb)/2 
    FuzzyResult = 1 - 2 * ((Value - Va) / (Vb - Va)) * ((Value - Va) / (Vb - Va))
  ElseIf Value >= (Va + Vb)/2 And Value <= Vb
    FuzzyResult = 2*((Value - Vb)/(Vb - Va)) * ((Value - Vb)/(Vb - Va))
  EndIf
  
  ProcedureReturn FuzzyResult
EndProcedure

;/ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;/ <<<<< !!! WARNING - YOU ARE NOW IN A TESTING ZONE - WARNING !!! <<<<<
;/ <<<<< !!! WARNING - THIS CODE SHOULD BE COMMENTED - WARNING !!! <<<<<
;/ <<<<< !!! WARNING - BEFORE THE FINAL COMPILATION. - WARNING !!! <<<<<
;/ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

For Index = 0 To 100 Step 5
  Debug "FuzzyBell = " + StrD(FuzzyBell(Index/10, 2.0,4.0,6.0), 4)
Next 

Debug ""

For Index = 1 To 100 Step 5
  Debug "FuzzySigmoid = " + StrD(FuzzySigmoid(Index/10, 2.0,3.0,-5.0, 8.0), 4)
Next 

Debug ""

For Index = 0 To 100 Step 5
  Debug "FuzzyGaussian = " + StrD(FuzzyGaussian(Index/10, 5.0, 2.0), 4)
Next 

Debug ""

For Weight = 170 To 200
  Debug "FuzzySmoothGrade = " + StrD(FuzzySmoothGrade(Weight, 175, 195), 4)
Next 

Debug ""

For Weight = 170 To 200
  Debug "FuzzySmoothReverseGrade = " + StrD(FuzzySmoothReverseGrade(Weight, 175, 195), 4)
Next 

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<

Posted: Fri May 15, 2009 6:41 pm
by Demivec
I'm glad you added the additional functions.

Here's a variation of FuzzySigmoid(), yours seems to be based on the difference between two sigmoid functions. This one uses less parameters and is just a single sigmoid function. Use a negative value for "s" to reverse the direction of the curve from left to right. I've also included a makeshift FuzzyPlot() routine for visualizing these functions. It works with the others as well.

Code: Select all

Procedure FuzzyPlot(x, Value.d, imageid, Color, opt = -1, scale = -1) ;x = x coordinate, scale = image height
  Static drawOpt = #False ;if drawOpt = #True points are connected
  Static drawScale = 1
  Static lastX = 0
  Static lastY = 0

  If opt <> -1
    drawOpt = opt
    lastX = 0
    lastY = 0
    If scale <> -1
      drawScale = scale
    EndIf
  EndIf
  
  If IsImage(imageid)
    StartDrawing(ImageOutput(imageid))
      If drawOpt
        LineXY(lastX, lastY, x, 100 - (Value * drawScale), Color)
        lastX = x
        lastY = 100 - (Value * drawScale)
      EndIf 
      Circle(x, 100 - (Value * drawScale), 2, Color)
    StopDrawing()
  EndIf 
EndProcedure

Procedure.d FuzzySigmoid(Value.d, crossover.d, s.d, ChopValue.d = 0.0001) ;s is the slope at the crossover point
  Protected FuzzyResult.d = 1.0 / (1.0 + Pow(2.71828182846, -s * (Value - crossover)))
    
  If FuzzyResult > ChopValue
    ProcedureReturn FuzzyResult
  Else
    ProcedureReturn 0.0
  EndIf 
EndProcedure


OpenWindow(0,0,0,300,300,"Test",#PB_Window_SystemMenu)
CreateImage(0,200,100)

FuzzyPlot(0, 0, 0, 0, 1, ImageHeight(0)) ;init plot values
For i = 0 To 500
  FuzzyPlot(i, FuzzySigmoid(i, 50, -0.2), 0, $FF00FF)
Next

StartDrawing(WindowOutput(0))
  DrawImage(ImageID(0),0,0)
StopDrawing()

Repeat:Until WaitWindowEvent(10) = #PB_Event_CloseWindow

Posted: Fri May 15, 2009 7:36 pm
by Kaeru Gaman
is there some literature about fuzzy locig, that could teach me short and descriptive how to use these functions?

atm those names are just african villages to me...

Posted: Fri May 15, 2009 9:05 pm
by Demivec
Kaeru Gaman wrote:is there some literature about fuzzy locig, that could teach me short and descriptive how to use these functions?

atm those names are just african villages to me...
In the future I'm going to try to work up some demonstration code that illustrates how they are used. You can find sources by searching for "Fuzzy Logic Tutorials".



Here is a basic outline:

Fuzzy Values are values that represent a degree of truth. So instead of #True (1) or #False (0) you would have #MostlyTrue (0.8 ), #Unclear (0.5), or #MostlyFalse (0.1). These values would be used in a rule evaluation process with comprisons to obtain a result (i.e. If Truth >= #MostlyTrue And Understanding <> #Cofused Then Action = #ContinueReading).

Fuzzy Logic generally involves three operations:

Fuzzyfication: Translation from real world values to Fuzzy values.

Rule evaluation: Computing rule strengths based on rules and inputs.

Defuzzyfication: Translate results back to the real world values.


The functions in the above code are used in the Fuzzyification process (i.e. FuzzyTriangle()) and in the Rule evalation process (i.e. FuzzyAnd()) . I don't believe there's been any code presented for Defuzzyification yet.

Fuzzy Logic is used to improve decision making when things aren't so clear (yes/no). It can be used in artificial intelligence in games, to controlling devices, or to make financial decisions and such.

:wink:

Posted: Fri May 15, 2009 9:59 pm
by Guimauve
The source is the MatLab website http://www.mathworks.com/access/helpdes ... ellmf.html.

Some explanation about how to use such functions are also available.

Best Regards

Guimauve

Posted: Fri May 15, 2009 10:48 pm
by utopiomania
I have some old source code in another language that resembles this. It accepts a number of
logic inputs, and the corresponding logic output, so that it can learn from the data.

After a while, it will begin to predict the correct output all on itself, based on the input
and its stored knowledge base.

A bit scary in my opinion, but very fascinating.

Posted: Fri May 15, 2009 10:58 pm
by Demivec
utopiomania wrote:I have some old source code in another language that resembles this. It accepts a number of
logic inputs, and the corresponding logic output, so that it can learn from the data.

After a while, it will begin to predict the correct output all on itself, based on the input
and its stored knowledge base.

A bit scary in my opinion, but very fascinating.
That seems to be more along the lines of a Neural Net, they have to be trained. Fuzzy Logic can be used in connection with a Neural Net.