Section 3

Back Home Up Next

 

Home
Software
Prices
Download
Yahoo Charts


NEW:
ADVANCED
TRADESTATION TECHNIQUE

US Markets Daily
snapshots

Technical
Description


Forthcoming Releases:

Fuzzy Logic:
sFLC3
DLL & API


Neural Net:
Release of NXL3
DLL & API


 

Section 3

Creating Fuzzy Sets

The client application has a “Load FS” button which does it all.  Let’s have a quick look at what it actually does.

We indeed need as a 1st step consisting of initialising a number of Fuzzy Sets for our FLC. 

This call will be even more useful in the Genetic Algorithm version of the FLC as it will allow testing many different fuzzy sets concurrently. To generate[1] 3 empty fuzzy sets, the function call is as simple as:

      FLC->InitFuzzySets(3);

This function InitFuzzySets(int) returns a value:

            -3         if the number of fuzzy sets to create is negative

            -2         if fuzzy sets could not be created (memory allocation error)

            -1         if fuzzy sets have already been created for this fuzzy set

            0          OK

Click Here for more info on API return codes

 

if OK, one can then use a pointer to the Fuzzy Set array.  Array boundaries won’t always be checked in the client application, but the number of fuzzy sets can be retrieved with:

      int nfs = FLC->GetNumFuzzySets();

A pointer to the Fuzzy Set Array can be retrieved with:

      CFuzzySet* pFSet = FLC->FSArray();

 

Typically, we then initialise the newly created fuzzy sets:

for (int i = 0; i < nNumFuzzySets; i++)

      {

            pFSet[i].InitFuzzySet(nNumFuzzyStates,0);

            pFSet[i].DefineFuzzySet(m_nDefaultFuzzySetModel);

      }

Note1: InitFuzzySet( int , int ) returns a value (same convention):

            -3         if the number of states to be created is negative

            -2         if fuzzy states could not be created (memory allocation error)

            -1         if fuzzy states have already been created for this fuzzy set

            0          OK

Each Fuzzy Set above has been initialised with the same number of fuzzy states (membership functions) and we provide the default shapes for all fuzzy states according to a model. For simplicity, this is the same default model in this example, but any default model can be used here.  In the sample application, the “m_nDefaultFuzzySetModel” variable is set when selecting which default fuzzy set (see “Defining a Fuzzy Set Model” above)

In practice, the 1st parameter “nNumFuzzyStatesis the number of fuzzy states, often 3, 5 or 7. The 2nd parameter represents the tag[2] to be attached to each state.  Predefined tags will be loaded from the DLL: “Low”, “Med” and “High” in this instance.

What we’ve seen in this section is how easy it is to create and define any number of Fuzzy Sets in just a few function calls.

Defining Fuzzy States

We’ve just used “DefineFuzzySet” to load a default Fuzzy Set with all its membership functions etc.  Fuzzy states are nothing but a way to quantify the attributes that will be applied to a variable, in other words, how high is “high” for instance.  We’ll see later on that we will attach a Fuzzy Set to a Variable, so that we can easily assess the degree of membership in each fuzzy state.

To better understand how a Fuzzy State is defined, let’s have a look at our _MFshape class, part of the CFLMembershipFunction class where Fuzzy States are defined.  We have chosen to only code triangular shapes in this version, but we could easily add Gaussian shapes too.

class _MFshape

//    ShoulderRight (0) -\, Triangle (1) /-\, ShoulderLeft (2) /-

      int   nType;

//    The points do characterize the shape of the membership function

//    This set-up can also accommodate other shapes like Gaussian

//    More points can be added to identify more shapes

//    like trapezoids. dCenter is used for shoulder shapes

      double dPoint1;  

      double dPoint2;  

      double dPoint3;  

      double dPoint4;  

      double dCenter;

In current implementations (triangular shapes), only 3 shapes are used: 0 (ShoulderRight), 1 (Triangle) and 2 (ShoulderLeft).  These shapes only need dPoint1, dPoint2, and dCenter.  dPoint3 and dPoint4 are left for future use (possible other shapes). dCenter is required to avoid state saturation for shoulder shapes.

We now better understand the settings (bottom of page 5) for our predefined 3-state Fuzzy Sets.  The file header also gives shapes for 5-state Fuzzy Sets.

The first thing a FLC needs to do is to fuzzify the inputs, in other words, pre-process the input value for each variable, against the different Fuzzy States of the Fuzzy Set in question.  That’s what is called calculating the degree of membership for each state. Since we will generally use a default fuzzy model, we don’t need to delve into details, so such calculations have been moved to Annex 1.

Defining a Variable Set (VS)

The Variable Set is the 2nd main component of the FLC.  In the client application, this step is as simple as clicking on the “Load FS” button.  We assume a FS has been created and defined.

Of course, it is essential to first check whether such FS has been defined, and if VS has not already been defined:

      if (FLC->boolVS()) return;

      if (!FLC->boolFS()) return;

Like for Fuzzy Sets, a number of variables, here 3, are created in one call:

      FLC->InitVarSet(3);

InitVarSet(int) returns a value:

            -3         if the number of variables to be created is negative

            -2         if fuzzy variables could not be created (memory allocation error)

            -1         if fuzzy variables have already been created for this FLC

            0          OK

Click Here for more info on API return codes

If OK, we can then retrieve a pointer to the Variables array, the same way we did for the Fuzzy Sets array:

 

      CFLVariable* pVars = FLC->VarArray();

      CFuzzySet* pFSet = FLC->FSArray();

      int nv = FLC->GetNumVars();

pVars will now be used to initialise the different variables, with an individual Fuzzy Set: 

      pVars[0].LoadFuzzySet(pFSet[0],TRUE); // Input1 in the FLC

      pVars[1].LoadFuzzySet(pFSet[1],TRUE); // Input2

pVars[2].LoadFuzzySet(pFSet[2],FALSE);// Output

Technically, LoadFuzzySet does a little more than copying a Fuzzy Set into the Variable description. It also attributes a premise number to each (Variable <-> Fuzzy State).  It will be described in more details later in this document.

For the time being, that is it! Only one call to create variables and one call in a loop to load a Fuzzy Set for each variable!

Defining a Rule Set (RS)

The Rule Set is the 3rd and last important component in the FLC.  The format has changed very slightly from FLC v2. We need to check that a Variable Set (VS) has been loaded in the FLC, and that each variable has been associated to a Fuzzy Set.  At the same time, we calculate the number of rules for a complete rule set.  We also check a rule set has not been loaded yet.

 

      int ret = FLC->DetermineRuleSetSize();

      if (FLC->boolRS()) return;

 

Memory for the entire Rule Set is created using this call:

      FLC->InitRuleSet();

InitRuleSet() returns a value:

            -3         if the number of rules to be created is negative

            -2         if rules could not be created (memory allocation error)

            -1         if rules have already been created for this FLC

            0          OK

Click Here for more info on API return codes

We can also call:     FLC->InitRuleSet(NumRules)[3];

If OK, one can then retrieve a pointer to the Rule Set:

CFLRule * pFLR = FLC->RuleArray();

Each rule has to now be formatted.  In our example, all rules are made of 2 premises like:

IF Var_1 IS High AND Var_2 IS Low THEN Output IS Average

Please note that the current rule model is specifically MISO (Multi Input Single Output), i.e. a rule only has one consequent.  Allowing for MIMO rules should not be a problem to expand.  In order to cater for a future update, the rule allocation is therefore separated from the previous call:

FLC->AllocateRuleSpace();

Loading the default Rule Set

Typically, after the empty Rule Set is created, we need to fill each rule with a composition of premises associated to a consequent (1 output).  One could keep the rule set in the client application like it was defined in the previous version of our FLC.  For simplicity though, it is easier to just load a rule set as per the model first selected.

The previous implementation syntax is provided in Appendix 4.

Deleting FLC components

FS, VS and RS can be deleted at all times.  The FS is not even needed once the variables have a fuzzy set loaded.

Deleting a FS requires a single call to:

      FLC->ClearFuzzySets();

The same logic applies to VS, but deleting VS must be followed by deletion of the RS:

      FLC->ClearVarSet();

      FLC->ClearRuleSet();

The Rule Set can be deleted separately.

Modifying FLC Components

The dialog implementation relies on passing pointers to child dialogs where the appropriate object is modified.  For instance, in the case of modifying Fuzzy Sets:

 

      if (!FLC->boolFS())return;

      CFuzzySet *FS = FLC->FSArray();

      static CFuzzySetDesign s_FSdlg;

 

      s_FSdlg.nNumFS = FLC->GetNumFuzzySets();

      s_FSdlg.FS = FS;

      s_FSdlg.DoModal();

 

The same logic is used for VS and RS.  There is a small variation however with VS.  Building a RS should be prevented if the FS is removed from a variable it was attached to.  This can be done for instance as follows:

 

      for (int i=0; i<FLC->GetNumVars(); i++)

            if (!VS[i].HasFS())

            {

                  FLC->ClearVarSet();

                  return;

            }

ClearVarSet() will reset the boolVS flag which is used when a RS is created.

Note: the dialog implementation does not allow changing the number of fuzzy states. It is possible to manually drop the FS attached to the variable, and attach another FS with more (or less fuzzy states).  In practice, assuming GA optimisation techniques, the FLC individual and/or the FLC component (VS) would be killed (depending on the level or levels the GA is applied) and regenerated.

Implementation details

The UI could admittedly be more comprehensive, but the current implementation only serves as a container for the FLC classes.  This hierarchical model can easily be stored in a database. Save/restore functionalities have not been coded here for better readability.

Each FLC is uniquely identified by a number, which can be a database index.  It is easy to visualise database relationships between FLC and its components FS, VS, and RS.  One must however note that at a higher level (FuSM) the same Variables may have to be used in several locations. In other instances, Variables may have different Fuzzy Sets, hence only be semantically equivalent.  This will be detailed in a separate document


 

[1] Each Fuzzy Set is given a unique number. This will facilitate associations to variables later on.

[2] const string strStates3[3][3] =

       {"Low", "Med", "High", "Neg.", "Null", "Pos.", "Small", "Avg.", "High"};

[3] If the number of rules in the Rule Set is needed, an accessor member function is available, like for all private members of all FLC classes:       NumRules = FLC->GetRuleSetSize();

Home Up Best viewed with MS Internet Explorer 5 and above

Page last modified: May 08, 2008
Copyright © ForeTrade Technologies 21st century and thereafter