2025-08-19 18:36:26 +01:00
//+------------------------------------------------------------------+
//| TestFuzzy.mq5 |
2026-01-31 12:29:07 +00:00
//| Copyright 2000-2026, MetaQuotes Ltd. |
//| www.mql5.com |
2025-08-19 18:36:26 +01:00
//+------------------------------------------------------------------+
//| Implementation of Fuzzy library in MetaQuotes Language 5 |
//| |
//| The features of the library include: |
//| - Create Mamdani fuzzy model |
//| - Create Sugeno fuzzy model |
//| - Normal membership function |
//| - Triangular membership function |
//| - Trapezoidal membership function |
//| - Constant membership function |
//| - Defuzzification method of center of gravity (COG) |
//| - Defuzzification method of bisector of area (BOA) |
//| - Defuzzification method of mean of maxima (MeOM) |
//| |
//| This file is free software; you can redistribute it and/or |
//| modify it under the terms of the GNU General Public License as |
//| published by the Free Software Foundation (www.fsf.org); either |
//| version 2 of the License, or (at your option) any later version. |
//| |
//| This program is distributed in the hope that it will be useful, |
//| but WITHOUT ANY WARRANTY; without even the implied warranty of |
//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
//| GNU General Public License for more details. |
//+------------------------------------------------------------------+
# include <Math\Fuzzy\MamdaniFuzzySystem.mqh>
# include <Math\Fuzzy\SugenoFuzzySystem.mqh>
//+------------------------------------------------------------------+
//| Test_NormalCombinationMembershipFunction() |
//+------------------------------------------------------------------+
bool Test_NormalCombinationMembershipFunction ( )
{
bool result = true ;
double delta = 1e-20 ;
double x [ ] = { -4.0 , 5.1 , 0.1 } ;
double b1 = 1.2 ;
double sigma1 = 0.45 ;
double b2 = 3.1 ;
double sigma2 = 0.9 ;
CNormalCombinationMembershipFunction function ( b1 , sigma1 , b2 , sigma2 ) ;
for ( int i = 0 ; i < ArraySize ( x ) ; i + + )
{
double actual = function . GetValue ( x [ i ] ) ;
double expected = 0.0 ;
if ( x [ i ] < 1.2 )
{
expected = MathExp ( MathPow ( x [ i ] - b1 , 2 ) / ( -2.0 * MathPow ( 0.45 , 2 ) ) ) ;
}
else if ( x [ i ] > 3.1 )
{
expected = MathExp ( MathPow ( x [ i ] - b2 , 2 ) / ( -2.0 * MathPow ( 0.9 , 2 ) ) ) ;
}
if ( MathAbs ( actual - expected ) > 1e-20 )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
}
return ( result ) ;
}
//+------------------------------------------------------------------+
//| Test_GeneralizedBellShapedMembershipFunction() |
//+------------------------------------------------------------------+
bool Test_GeneralizedBellShapedMembershipFunction ( )
{
bool result = true ;
double delta = 1e-20 ;
double x [ ] = { -4 , 5.1 , 0.1 } ;
double a = 2.4 ;
double b = 0.9 ;
double c = 1.33 ;
CGeneralizedBellShapedMembershipFunction function ( a , b , c ) ;
for ( int i = 0 ; i < ArraySize ( x ) ; i + + )
{
double actual = function . GetValue ( x [ i ] ) ;
double expected = 1 / ( 1 + MathPow ( MathAbs ( ( x [ i ] - a ) / c ) , 2 * b ) ) ;
if ( actual ! = expected )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
}
return ( result ) ;
}
//+------------------------------------------------------------------+
//| Test_SigmoidalMembershipFunction() |
//+------------------------------------------------------------------+
bool Test_SigmoidalMembershipFunction ( )
{
bool result = true ;
double delta = 1e-20 ;
double x [ ] = { -4 , 4.1 , 0.1 } ;
double a = 1.75 ;
double c = - M_PI / 2 ;
CSigmoidalMembershipFunction function ( a , c ) ;
for ( int i = 0 ; i < ArraySize ( x ) ; i + + )
{
double actual = function . GetValue ( x [ i ] ) ;
double expected = 1 / ( 1.0 + MathExp ( - a * ( x [ i ] - c ) ) ) ;
if ( actual ! = expected )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
}
return ( result ) ;
}
//+------------------------------------------------------------------+
//| Test_ProductTwoSigmoidalMembershipFunctions() |
//+------------------------------------------------------------------+
bool Test_ProductTwoSigmoidalMembershipFunctions ( )
{
bool result = true ;
double delta = 1e-20 ;
double x [ ] = { -4.0 , 4.1 , 0.1 } ;
double a1 = -1.75 ;
double c1 = - M_PI / 2.0 ;
double a2 = 0.972 ;
double c2 = 0.43 ;
CProductTwoSigmoidalMembershipFunctions function ( a1 , c1 , a2 , c2 ) ;
for ( int i = 0 ; i < ArraySize ( x ) ; i + + )
{
double actual = function . GetValue ( x [ i ] ) ;
double expected = ( ( 1.0 / ( 1.0 + MathExp ( - a1 * ( x [ i ] - c1 ) ) ) ) *
( 1.0 / ( 1.0 + MathExp ( - a2 * ( x [ i ] - c2 ) ) ) ) ) ;
if ( actual ! = expected )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
}
return ( result ) ;
}
//+------------------------------------------------------------------+
//| Test_TrapezoidMembershipFunction() |
//+------------------------------------------------------------------+
bool Test_TrapezoidMembershipFunction ( )
{
bool result = true ;
double delta = 1e-20 ;
double x [ ] = { -4 , 3.1 , 0.1 } ;
double x1 = -4 ;
double x2 = -4 ;
double x3 = 2 ;
double x4 = M_PI ;
CTrapezoidMembershipFunction function ( x1 , x2 , x3 , x4 ) ;
for ( int i = 0 ; i < ArraySize ( x ) ; i + + )
{
double actual = function . GetValue ( x [ i ] ) ;
double expected = 1.0 ;
if ( x [ i ] > 2 & & x [ i ] < M_PI )
{
expected = ( - x [ i ] / ( x4 - x3 ) ) + ( x4 / ( x4 - x3 ) ) ;
}
else if ( x [ i ] > M_PI )
{
expected = 0 ;
}
if ( actual ! = expected )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
}
return ( result ) ;
}
//+------------------------------------------------------------------+
//| Test_NormalMembershipFunction() |
//+------------------------------------------------------------------+
bool Test_NormalMembershipFunction ( )
{
bool result = true ;
double delta = 1e-20 ;
double x [ ] = { -4 , 5.1 , 0.1 } ;
double b = 1.33 ;
double sigma = 0.45 ;
CNormalMembershipFunction function ( b , sigma ) ;
for ( int i = 0 ; i < ArraySize ( x ) ; i + + )
{
double actual = function . GetValue ( x [ i ] ) ;
double expected = MathExp ( MathPow ( x [ i ] -1.33 , 2.0 ) / ( -2.0 * MathPow ( 0.45 , 2.0 ) ) ) ;
if ( actual ! = expected )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
}
return ( result ) ;
}
//+------------------------------------------------------------------+
//| Test_TriangularMembershipFunction() |
//+------------------------------------------------------------------+
bool Test_TriangularMembershipFunction ( )
{
bool result = true ;
double delta = 1e-20 ;
double x [ ] = { -4 , 4.1 , 0.1 } ;
double x1 = - M_PI ;
double x2 = - M_E / 2.0 ;
double x3 = M_PI / 5.0 ;
CTriangularMembershipFunction function ( x1 , x2 , x3 ) ;
for ( int i = 0 ; i < ArraySize ( x ) ; i + + )
{
double actual = function . GetValue ( x [ i ] ) ;
double expected = 0 ;
if ( x [ i ] = = x2 )
{
expected = 1 ;
}
else if ( x [ i ] > x1 & & x [ i ] < x2 )
{
expected = ( x [ i ] / ( x2 - x1 ) ) - ( x1 / ( x2 - x1 ) ) ;
}
else if ( x [ i ] > x2 & & x [ i ] < x3 )
{
expected = ( - x [ i ] / ( x3 - x2 ) ) + ( x3 / ( x3 - x2 ) ) ;
}
if ( actual ! = expected )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
}
return ( result ) ;
}
//+------------------------------------------------------------------+
//| Test_ConstantMembershipFunction() |
//+------------------------------------------------------------------+
bool Test_ConstantMembershipFunction ( )
{
bool result = true ;
double delta = 1e-20 ;
double x [ ] = { -4 , 4.1 , 0.1 } ;
double value = 1.0 ;
CConstantMembershipFunction function ( 1.0 ) ;
for ( int i = 0 ; i < ArraySize ( x ) ; i + + )
{
double actual = function . GetValue ( x [ i ] ) ;
double expected = value ;
if ( actual ! = expected )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
}
return ( result ) ;
}
//+------------------------------------------------------------------+
//| Test_P_S_Z_ShapedMembershipFunction() |
//+------------------------------------------------------------------+
bool Test_P_S_Z_ShapedMembershipFunction ( )
{
bool result = true ;
double delta = 1e-20 ;
double x [ ] = { -4.0 , 4.1 , 0.1 } ;
CS_ShapedMembershipFunction sfunction ( -1.0 / 137.0 , M_PI / 2.0 ) ;
CZ_ShapedMembershipFunction zfunction ( MathExp ( 1.0 ) , M_PI ) ;
CP_ShapedMembershipFunction pfunction ( -1.0 / 137.0 , M_PI / 2.0 , MathExp ( 1.0 ) , M_PI ) ;
for ( int i = 0 ; i < ArraySize ( x ) ; i + + )
{
double actual = pfunction . GetValue ( x [ i ] ) ;
double expected = sfunction . GetValue ( x [ i ] ) * zfunction . GetValue ( x [ i ] ) ;
if ( actual ! = expected )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
}
return ( result ) ;
}
//+------------------------------------------------------------------+
//| Test_Bisector() |
//+------------------------------------------------------------------+
bool Test_Bisector ( )
{
double delta = 1e-10 ;
CMamdaniFuzzySystem system ( ) ;
system . SetDefuzzificationMethod ( BisectorDef ) ;
CTriangularMembershipFunction * function = new CTriangularMembershipFunction ( 0 , 5 , 5 ) ;
double actual = system . Defuzzify ( function , 0 , 5 ) ;
double expected = 3.5 ;
if ( MathAbs ( actual - expected ) > = delta )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
return ( false ) ;
}
return ( true ) ;
}
//+------------------------------------------------------------------+
//| Test_Centroid() |
//+------------------------------------------------------------------+
bool Test_Centroid ( )
{
bool result = true ;
double delta = 1e-1 ;
CMamdaniFuzzySystem system ( ) ;
system . SetDefuzzificationMethod ( CentroidDef ) ;
double mean [ ] = { -5 , -3 , -1 , 1 , 3 , 5 } ;
double sigma [ ] = { 1 , 2 } ;
for ( int i = 0 ; i < ArraySize ( mean ) ; i + + )
{
for ( int j = 0 ; j < ArraySize ( sigma ) ; j + + )
{
CNormalMembershipFunction * function = new CNormalMembershipFunction ( mean [ i ] , sigma [ j ] ) ;
double actual = system . Defuzzify ( function , -10 , 10 ) ;
double expected = mean [ i ] ;
if ( MathAbs ( actual - expected ) > = delta )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
}
}
return ( result ) ;
}
//+------------------------------------------------------------------+
//| Test_Defuzzification() |
//+------------------------------------------------------------------+
bool Test_Defuzzification ( )
{
bool result = true ;
double delta = 1e-12 ;
CMamdaniFuzzySystem system ( ) ;
double actual = 0.0 ;
double expected = 0.0 ;
//---
system . SetDefuzzificationMethod ( CentroidDef ) ;
actual = system . Defuzzify ( new CNormalMembershipFunction ( 0 , 2 ) , -10 , 10 ) ;
if ( MathAbs ( actual - expected ) > = delta )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
//---
system . SetDefuzzificationMethod ( BisectorDef ) ;
actual = system . Defuzzify ( new CNormalMembershipFunction ( 0 , 2 ) , -10 , 10 ) ;
if ( MathAbs ( actual - expected ) > = delta )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
//---
system . SetDefuzzificationMethod ( AverageMaximumDef ) ;
actual = system . Defuzzify ( new CNormalMembershipFunction ( 0 , 2 ) , -10 , 10 ) ;
if ( MathAbs ( actual - expected ) > = delta )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
//---
system . SetDefuzzificationMethod ( SmallestMaximumDef ) ;
actual = system . Defuzzify ( new CNormalMembershipFunction ( 0 , 2 ) , -10 , 10 ) ;
if ( MathAbs ( actual - expected ) > = delta )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
//---
system . SetDefuzzificationMethod ( LargestMaximumDef ) ;
actual = system . Defuzzify ( new CNormalMembershipFunction ( 0 , 2 ) , -10 , 10 ) ;
if ( MathAbs ( actual - expected ) > = delta )
{
Print ( " Expected: " , expected , " +/- " , delta , " ; But was: " , actual ) ;
result = false ;
}
return ( result ) ;
}
//+------------------------------------------------------------------+
//| Test_TipingProblem() |
//+------------------------------------------------------------------+
bool Test_TipingProblem ( )
{
//--- Mamdani Fuzzy System
CMamdaniFuzzySystem * fsTips = new CMamdaniFuzzySystem ( ) ;
//--- Create first input variables for the system
CFuzzyVariable * fvService = new CFuzzyVariable ( " service " , 0.0 , 10.0 ) ;
fvService . Terms ( ) . Add ( new CFuzzyTerm ( " poor " , new CTriangularMembershipFunction ( -5.0 , 0.0 , 5.0 ) ) ) ;
fvService . Terms ( ) . Add ( new CFuzzyTerm ( " good " , new CTriangularMembershipFunction ( 0.0 , 5.0 , 10.0 ) ) ) ;
fvService . Terms ( ) . Add ( new CFuzzyTerm ( " excellent " , new CTriangularMembershipFunction ( 5.0 , 10.0 , 15.0 ) ) ) ;
fsTips . Input ( ) . Add ( fvService ) ;
//--- Create second input variables for the system
CFuzzyVariable * fvFood = new CFuzzyVariable ( " food " , 0.0 , 10.0 ) ;
fvFood . Terms ( ) . Add ( new CFuzzyTerm ( " rancid " , new CTrapezoidMembershipFunction ( 0.0 , 0.0 , 1.0 , 3.0 ) ) ) ;
fvFood . Terms ( ) . Add ( new CFuzzyTerm ( " delicious " , new CTrapezoidMembershipFunction ( 7.0 , 9.0 , 10.0 , 10.0 ) ) ) ;
fsTips . Input ( ) . Add ( fvFood ) ;
//--- Create Output
CFuzzyVariable * fvTips = new CFuzzyVariable ( " tips " , 0.0 , 30.0 ) ;
fvTips . Terms ( ) . Add ( new CFuzzyTerm ( " cheap " , new CTriangularMembershipFunction ( 0.0 , 5.0 , 10.0 ) ) ) ;
fvTips . Terms ( ) . Add ( new CFuzzyTerm ( " average " , new CTriangularMembershipFunction ( 10.0 , 15.0 , 20.0 ) ) ) ;
fvTips . Terms ( ) . Add ( new CFuzzyTerm ( " generous " , new CTriangularMembershipFunction ( 20.0 , 25.0 , 30.0 ) ) ) ;
fsTips . Output ( ) . Add ( fvTips ) ;
//--- Create three Mamdani fuzzy rule
CMamdaniFuzzyRule * rule1 = fsTips . ParseRule ( " if (service is poor ) or (food is rancid) then tips is cheap " ) ;
CMamdaniFuzzyRule * rule2 = fsTips . ParseRule ( " if ((service is good)) then tips is average " ) ;
CMamdaniFuzzyRule * rule3 = fsTips . ParseRule ( " if (service is excellent) or (food is delicious) then (tips is generous) " ) ;
//--- Add three Mamdani fuzzy rule in system
fsTips . Rules ( ) . Add ( rule1 ) ;
fsTips . Rules ( ) . Add ( rule2 ) ;
fsTips . Rules ( ) . Add ( rule3 ) ;
//--- Set input value
CList * in = new CList ;
CDictionary_Obj_Double * p_od_Service = new CDictionary_Obj_Double ;
CDictionary_Obj_Double * p_od_Food = new CDictionary_Obj_Double ;
//--- Testing values
double Food = 6.5 ;
double Service = 9.8 ;
double expected = 24.3 ;
p_od_Service . SetAll ( fvService , Service ) ;
p_od_Food . SetAll ( fvFood , Food ) ;
in . Add ( p_od_Service ) ;
in . Add ( p_od_Food ) ;
//--- Get result
CList * result ;
CDictionary_Obj_Double * p_od_Tips ;
result = fsTips . Calculate ( in ) ;
p_od_Tips = result . GetNodeAtIndex ( 0 ) ;
double actual = NormalizeDouble ( p_od_Tips . Value ( ) , 1 ) ;
delete in ;
delete result ;
delete fsTips ;
if ( expected ! = actual )
{
Print ( " Expected: " , expected , " ; But was: " , actual ) ;
//--- failed
return ( false ) ;
}
else
{
//--- success
return ( true ) ;
}
}
//+------------------------------------------------------------------+
//| Test_TypicalFuzzyControlSystem() |
//+------------------------------------------------------------------+
bool Test_TypicalFuzzyControlSystem ( )
{
//--- Sugeno Fuzzy System
CSugenoFuzzySystem * fsCruiseControl = new CSugenoFuzzySystem ( ) ;
//--- Create first input variables for the system
CFuzzyVariable * fvSpeedError = new CFuzzyVariable ( " SpeedError " , -20.0 , 20.0 ) ;
fvSpeedError . Terms ( ) . Add ( new CFuzzyTerm ( " slower " , new CTriangularMembershipFunction ( -35.0 , -20.0 , -5.0 ) ) ) ;
fvSpeedError . Terms ( ) . Add ( new CFuzzyTerm ( " zero " , new CTriangularMembershipFunction ( -15.0 , -0.0 , 15.0 ) ) ) ;
fvSpeedError . Terms ( ) . Add ( new CFuzzyTerm ( " faster " , new CTriangularMembershipFunction ( 5.0 , 20.0 , 35.0 ) ) ) ;
fsCruiseControl . Input ( ) . Add ( fvSpeedError ) ;
//--- Create second input variables for the system
CFuzzyVariable * fvSpeedErrorDot = new CFuzzyVariable ( " SpeedErrorDot " , -5.0 , 5.0 ) ;
fvSpeedErrorDot . Terms ( ) . Add ( new CFuzzyTerm ( " slower " , new CTriangularMembershipFunction ( -9.0 , -5.0 , -1.0 ) ) ) ;
fvSpeedErrorDot . Terms ( ) . Add ( new CFuzzyTerm ( " zero " , new CTriangularMembershipFunction ( -4.0 , -0.0 , 4.0 ) ) ) ;
fvSpeedErrorDot . Terms ( ) . Add ( new CFuzzyTerm ( " faster " , new CTriangularMembershipFunction ( 1.0 , 5.0 , 9.0 ) ) ) ;
fsCruiseControl . Input ( ) . Add ( fvSpeedErrorDot ) ;
//--- Create Output
CSugenoVariable * svAccelerate = new CSugenoVariable ( " Accelerate " ) ;
double coeff1 [ 3 ] = { 0.0 , 0.0 , 0.0 } ;
svAccelerate . Functions ( ) . Add ( fsCruiseControl . CreateSugenoFunction ( " zero " , coeff1 ) ) ;
double coeff2 [ 3 ] = { 0.0 , 0.0 , 1.0 } ;
svAccelerate . Functions ( ) . Add ( fsCruiseControl . CreateSugenoFunction ( " faster " , coeff2 ) ) ;
double coeff3 [ 3 ] = { 0.0 , 0.0 , -1.0 } ;
svAccelerate . Functions ( ) . Add ( fsCruiseControl . CreateSugenoFunction ( " slower " , coeff3 ) ) ;
double coeff4 [ 3 ] = { -0.04 , -0.1 , 0.0 } ;
svAccelerate . Functions ( ) . Add ( fsCruiseControl . CreateSugenoFunction ( " func " , coeff4 ) ) ;
fsCruiseControl . Output ( ) . Add ( svAccelerate ) ;
//--- Craete Sugeno fuzzy rules
AddSugenoFuzzyRule ( fsCruiseControl , fvSpeedError , fvSpeedErrorDot , svAccelerate , " slower " , " slower " , " faster " ) ;
AddSugenoFuzzyRule ( fsCruiseControl , fvSpeedError , fvSpeedErrorDot , svAccelerate , " slower " , " zero " , " faster " ) ;
AddSugenoFuzzyRule ( fsCruiseControl , fvSpeedError , fvSpeedErrorDot , svAccelerate , " slower " , " faster " , " zero " ) ;
AddSugenoFuzzyRule ( fsCruiseControl , fvSpeedError , fvSpeedErrorDot , svAccelerate , " zero " , " slower " , " faster " ) ;
AddSugenoFuzzyRule ( fsCruiseControl , fvSpeedError , fvSpeedErrorDot , svAccelerate , " zero " , " zero " , " func " ) ;
AddSugenoFuzzyRule ( fsCruiseControl , fvSpeedError , fvSpeedErrorDot , svAccelerate , " zero " , " faster " , " slower " ) ;
AddSugenoFuzzyRule ( fsCruiseControl , fvSpeedError , fvSpeedErrorDot , svAccelerate , " faster " , " slower " , " zero " ) ;
AddSugenoFuzzyRule ( fsCruiseControl , fvSpeedError , fvSpeedErrorDot , svAccelerate , " faster " , " zero " , " slower " ) ;
AddSugenoFuzzyRule ( fsCruiseControl , fvSpeedError , fvSpeedErrorDot , svAccelerate , " faster " , " faster " , " slower " ) ;
//--- Set input value and get result
CList * in = new CList ;
CDictionary_Obj_Double * p_od_Error = new CDictionary_Obj_Double ;
CDictionary_Obj_Double * p_od_ErrorDot = new CDictionary_Obj_Double ;
double Speed_Error = 18.3 ;
double Speed_ErrorDot = -3.5 ;
double expected = -16.7 ;
p_od_Error . SetAll ( fvSpeedError , Speed_Error ) ;
p_od_ErrorDot . SetAll ( fvSpeedErrorDot , Speed_ErrorDot ) ;
in . Add ( p_od_Error ) ;
in . Add ( p_od_ErrorDot ) ;
//--- Get result
CList * result ;
CDictionary_Obj_Double * p_od_Accelerate ;
result = fsCruiseControl . Calculate ( in ) ;
p_od_Accelerate = result . GetNodeAtIndex ( 0 ) ;
double actual = NormalizeDouble ( p_od_Accelerate . Value ( ) * 100 , 1 ) ;
delete in ;
delete result ;
delete fsCruiseControl ;
if ( expected ! = actual )
{
Print ( " Expected: " , expected , " ; But was: " , actual ) ;
//--- failed
return ( false ) ;
}
else
{
//--- success
return ( true ) ;
}
}
//+------------------------------------------------------------------+
//| AddSugenoFuzzyRule() |
//+------------------------------------------------------------------+
void AddSugenoFuzzyRule ( CSugenoFuzzySystem * fs , CFuzzyVariable * fv1 , CFuzzyVariable * fv2 , CSugenoVariable * sv ,
const string value1 , const string value2 , const string result )
{
CSugenoFuzzyRule * rule = fs . EmptyRule ( ) ;
rule . Conclusion ( new CSingleCondition ( ) ) ;
rule . Condition ( ) . Op ( OperatorType : : And ) ;
rule . Condition ( ) . ConditionsList ( ) . Add ( rule . CreateCondition ( fv1 , fv1 . GetTermByName ( value1 ) ) ) ;
rule . Condition ( ) . ConditionsList ( ) . Add ( rule . CreateCondition ( fv2 , fv2 . GetTermByName ( value2 ) ) ) ;
rule . Conclusion ( ) .Var ( sv ) ;
INamedValue * sf = sv . GetFuncByName ( result ) ;
rule . Conclusion ( ) . Term ( sf ) ;
fs . Rules ( ) . Add ( rule ) ;
}
//+------------------------------------------------------------------+
//| TestMembersipFunctions |
//+------------------------------------------------------------------+
bool TestMembersipFunctions ( const string test_name )
{
PrintFormat ( " %s started " , test_name ) ;
//--- test 1
PrintFormat ( " %s: Test 1: calculation of the values for combination two normal membership function " , test_name ) ;
if ( ! Test_NormalCombinationMembershipFunction ( ) )
return ( false ) ;
//--- test 2
PrintFormat ( " %s: Test 2: calculation of the values for generalized bell-shaped membership function " , test_name ) ;
if ( ! Test_GeneralizedBellShapedMembershipFunction ( ) )
return ( false ) ;
//--- test 3
PrintFormat ( " %s: Test 3: calculation of the values for sigmoidal membership function " , test_name ) ;
if ( ! Test_SigmoidalMembershipFunction ( ) )
return ( false ) ;
//--- test 4
PrintFormat ( " %s: Test 4: calculation of the values for product two sigmoidal membership function " , test_name ) ;
if ( ! Test_ProductTwoSigmoidalMembershipFunctions ( ) )
return ( false ) ;
//--- test 5
PrintFormat ( " %s: Test 5: calculation of the values for trapezoid membership function " , test_name ) ;
if ( ! Test_TrapezoidMembershipFunction ( ) )
return ( false ) ;
//--- test 6
PrintFormat ( " %s: Test 6: calculation of the values for normal membership function " , test_name ) ;
if ( ! Test_NormalMembershipFunction ( ) )
return ( false ) ;
//--- test 7
PrintFormat ( " %s: Test 7: calculation of the values for triangular membership function " , test_name ) ;
if ( ! Test_TriangularMembershipFunction ( ) )
return ( false ) ;
//--- test 8
PrintFormat ( " %s: Test 8: calculation of the values for constant membership function " , test_name ) ;
if ( ! Test_ConstantMembershipFunction ( ) )
return ( false ) ;
//--- test 9
PrintFormat ( " %s: Test 9: comparing the results of calculations 'P' shaped function and product 'S' and 'Z' shaped function " , test_name ) ;
if ( ! Test_P_S_Z_ShapedMembershipFunction ( ) )
return ( false ) ;
//--- successful
PrintFormat ( " %s passed " , test_name ) ;
return ( true ) ;
}
//+------------------------------------------------------------------+
//| TestDefuzzificationMethods |
//+------------------------------------------------------------------+
bool TestDefuzzificationMethods ( const string test_name )
{
PrintFormat ( " %s started " , test_name ) ;
//--- test 1
PrintFormat ( " %s: Test 1: application of the Bisector defuzzification for a triangular membership function " , test_name ) ;
if ( ! Test_Bisector ( ) )
return ( false ) ;
//--- test 2
PrintFormat ( " %s: Test 2: application of the Centroid defuzzification for a normal membership function " , test_name ) ;
if ( ! Test_Centroid ( ) )
return ( false ) ;
//--- test 3
PrintFormat ( " %s: Test 3: application of the Bisector, Centroid, Middle, Smallest, and Largest of Maximum defuzzification for a normal membership function " , test_name ) ;
if ( ! Test_Defuzzification ( ) )
return ( false ) ;
//--- successful
PrintFormat ( " %s passed " , test_name ) ;
return ( true ) ;
}
//+------------------------------------------------------------------+
//| TestFuzzySystems |
//+------------------------------------------------------------------+
bool TestFuzzySystems ( const string test_name )
{
PrintFormat ( " %s started " , test_name ) ;
//--- test 1
PrintFormat ( " %s: Test 1: calculate result for Mamdani fuzzy system " , test_name ) ;
if ( ! Test_TipingProblem ( ) )
return ( false ) ;
//--- test 2
PrintFormat ( " %s: Test 2: calculate result for Sugeno fuzzy system " , test_name ) ;
if ( ! Test_TypicalFuzzyControlSystem ( ) )
return ( false ) ;
//--- successful
PrintFormat ( " %s passed " , test_name ) ;
return ( true ) ;
}
//+------------------------------------------------------------------+
//| TestFuzzy |
//+------------------------------------------------------------------+
void TestFuzzy ( int & tests_performed , int & tests_passed )
{
//--- Membersip functions
tests_performed + + ;
string test_name = " Membersip functions test " ;
if ( TestMembersipFunctions ( test_name ) )
tests_passed + + ;
else
PrintFormat ( " %s failed " , test_name ) ;
//--- Defuzzification methods
tests_performed + + ;
test_name = " Defuzzification methods test " ;
if ( TestDefuzzificationMethods ( test_name ) )
tests_passed + + ;
else
PrintFormat ( " %s failed " , test_name ) ;
//--- Fuzzy systems
tests_performed + + ;
test_name = " Fuzzy systems test " ;
if ( TestFuzzySystems ( test_name ) )
tests_passed + + ;
else
PrintFormat ( " %s failed " , test_name ) ;
return ;
}
//+------------------------------------------------------------------+
//| UnitTests() |
//+------------------------------------------------------------------+
void UnitTests ( const string package_name )
{
PrintFormat ( " Unit tests for Package %s \n " , package_name ) ;
//--- initial values
int tests_performed = 0 ;
int tests_passed = 0 ;
//--- test distributions
TestFuzzy ( tests_performed , tests_passed ) ;
//--- print statistics
PrintFormat ( " \n %d of %d passed " , tests_passed , tests_performed ) ;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart ( )
{
UnitTests ( " Fuzzy " ) ;
}
//+------------------------------------------------------------------+