Inside The Code
This page explains some of the details of the FFLL code.
Membership Functions
Fuzzy variables contain sets, and each set has a membership function associated with it. The membership function defines the set's shape and is used to "fuzzify" the x values of the variable by associating a
Degree of Membership (DOM) with an x value. While the most common membership function used in fuzzy systems is a triangle, FFLL provides support for Triangles, Trapezoids, S-Curves, and Singletons as shown
below.
It is worth noting that the S-Curve membership function is not limited to bell shaped curves, and can represent fairly complex curves as shown
below.
Making FFLL Fast...
FFLL was designed to be fast, therefore lookup tables are used wherever possible sacrificing some memory for the sake of speed.
Each set's membership function contains a lookup table used to speed the "fuzzification" process. This lookup table is the values array in the
MemberFuncBase
class, which contains FuzzyVariableBase::x_array_count elements. Each array element holds a DOM value which is between zero and FuzzyVariableBase::dom_array_max_idx. Values of 100 or 200 for x_array_count provide good results, the larger the value of x_array_count the larger the memory footprint of the model.
The variable's X-axis values must be mapped into to the values array. The value of x_array_count determines how many X-axis values are represented by each element in to the values array. For example, if a variable's X-axis had a range of 0 to 50 (as in Figure 1) and x_array_count was 100, each index in the values array would represent 0.5 x values (50/100). If x_array_count is changed to 50, each "step" would be 1 x value
(50/50). Think of the value of x_array_count as the "sample frequency"
of the membership function, the more samples the smoother the curve.
To determine the DOM of a variable's x value, it is converted to an index into the values array by the FuzzyVariableBase::convert_value_to_idx() function. Each set in a variable has its values array checked at that index to get the set's DOM.
One-Dimensional Rules Array
FFLL stores rules in a one-dimensional array. This avoids the complexities of dynamically allocating a multi-dimensional array in C/C++ when the number of dimensions is not known before hand.
To speed access to the array elements and avoid potentially costly multiplications typical during array accesses, the offsets into the array are pre-calculated and stored in the rule_index variable of the
FuzzySetBase
class. These values are added together to get the final array index.
For example, in a 3x3x3 system (three input variables, each with three sets) there would be 27 total rules. The rule_index values would be:
Variable 0 |
Variable 1 |
Variable 2 |
set 0: 0 |
set 0: 0 |
set 0: 0 |
set 1: 9 |
set 1: 3 |
set 1: 1 |
set 2: 18 |
set 2: 6 |
set 2: 2 |
To get the rule index corresponding to rules[2][1][1], the offset for the third element in the set array for Variable 0 is found, which is 18. This process continues for each dimension in the array, adding each value to end up with the equation: 18 + 3 + 1 = 22. Which is the 22nd element in the one-dimensional rules array. This means that only (N-1) additions are required every time the rule index for an N dimensional array is calculated.
Defuzzification
To eliminate extra calculations, FFLL does not calculate the defuzzified output value until it is requested. For example, if a model has four input variables and the output value is calculated every time an input value changed, three output calculations would occur that were unnecessary.
The Center of Gravity defuzzification method makes heavy use of lookup tables while the Mean of Maximum method simply stores a single value per output set. See
COGDefuzzVarObj and
MOMDefuzzVarObj respectively for each method's details.
|