//+------------------------------------------------------------------+ //| membershipfunction.mqh | //| Copyright 2000-2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ //| 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 //+------------------------------------------------------------------+ //| Purpose: creating membership functions. | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Types of membership functions composition | //+------------------------------------------------------------------+ enum MfCompositionType { MinMF, // Minumum of functions MaxMF, // Maximum of functions ProdMF, // Production of functions SumMF // Sum of functions }; //+------------------------------------------------------------------+ //| The base class of all classes of membership functions | //+------------------------------------------------------------------+ class IMembershipFunction : public CObject { public: //--- method evaluate value of the membership function virtual double GetValue(const double x)=NULL; }; //+------------------------------------------------------------------+ //| Gaussian combination membership function | //+------------------------------------------------------------------+ class CNormalCombinationMembershipFunction : public IMembershipFunction { private: double m_b1; // Parametr b1: coordinate of the minimum membership function double m_sigma1; // Parametr sigma1: concentration factor of the left path of function double m_b2; // Parametr b2: coordinate of the maximum membership function double m_sigma2; // Parametr sigma2: concentration factor of the rigth path of function public: CNormalCombinationMembershipFunction(void); CNormalCombinationMembershipFunction(const double b1,const double sigma1,const double b2,const double sigma2); ~CNormalCombinationMembershipFunction(void); //--- methods gets or sets the parametrs void B1(const double b1) { m_b1=b1; } double B1(void) { return(m_b1); } void Sigma1(const double sigma1) { m_sigma1=sigma1; } double Sigma1(void) { return(m_sigma1); } void B2(const double b2) { m_b2=b2; } double B2(void) { return(m_b2); } void Sigma2(const double sigma2) { m_sigma2=sigma2; } double Sigma2(void) { return(m_sigma2); } //--- method gets the argument (x axis value) double GetValue(const double x); }; //+------------------------------------------------------------------+ //| Constructor without parameters | //+------------------------------------------------------------------+ CNormalCombinationMembershipFunction::CNormalCombinationMembershipFunction(void) { } //+------------------------------------------------------------------+ //| Constructor with parameters | //+------------------------------------------------------------------+ CNormalCombinationMembershipFunction::CNormalCombinationMembershipFunction(const double b1,const double sigma1,const double b2,const double sigma2) { m_b1=b1; m_sigma1=sigma1; m_b2=b2; m_sigma2=sigma2; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CNormalCombinationMembershipFunction::~CNormalCombinationMembershipFunction(void) { } //+------------------------------------------------------------------+ //| Get argument (x axis value) | //+------------------------------------------------------------------+ double CNormalCombinationMembershipFunction::GetValue(const double x) { if(m_b1<=m_b2) { if(xm_b2) { //--- return result return (exp((x - m_b2) * (x - m_b2) / ( -2.0 * m_sigma2 * m_sigma2))); } else { //--- m_b1 <= x && x <= m_b2 //--- return result return (1); } } if(m_b1>m_b2) { if(xm_b1) { //--- return result return (exp((x - m_b2) * (x - m_b2) / ( -2.0 * m_sigma2 * m_sigma2))); } else { //--- m_b1 <= x && x <= m_b2 //--- return result return ( exp((x - m_b1) * (x - m_b1) / ( -2.0 * m_sigma1 * m_sigma1)) * exp((x - m_b2) * (x - m_b2) / ( -2.0 * m_sigma2 * m_sigma2)) ); } } //--- m_b1 == m_b2 //--- return result return (m_b1); } //+------------------------------------------------------------------+ //| Generalized bell-shaped membership function | //+------------------------------------------------------------------+ class CGeneralizedBellShapedMembershipFunction : public IMembershipFunction { private: double m_a; // Parametr a: the concentration factor of the membership function double m_b; // Parametr b: coefficients slope of the membership function double m_c; // Parametr c: the maximum coordinate of the membership function public: CGeneralizedBellShapedMembershipFunction(void); CGeneralizedBellShapedMembershipFunction(const double a,const double b,const double c); ~CGeneralizedBellShapedMembershipFunction(void); //--- methods gets or sets the parametrs void A(const double a) { m_a=a; } double A(void) { return(m_a); } void B(const double b) { m_b=b; } double B(void) { return(m_b); } void C(const double c) { m_c=c; } double C(void) { return(m_c); } //--- method gets the argument (x axis value) double GetValue(const double x); }; //+------------------------------------------------------------------+ //| Constructor without parameters | //+------------------------------------------------------------------+ CGeneralizedBellShapedMembershipFunction::CGeneralizedBellShapedMembershipFunction(void) { } //+------------------------------------------------------------------+ //| Constructor with parameters | //+------------------------------------------------------------------+ CGeneralizedBellShapedMembershipFunction::CGeneralizedBellShapedMembershipFunction(const double a,const double b,const double c) { m_a=a; m_b=b; m_c=c; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CGeneralizedBellShapedMembershipFunction::~CGeneralizedBellShapedMembershipFunction(void) { } //+------------------------------------------------------------------+ //| Get argument (x axis value) | //+------------------------------------------------------------------+ double CGeneralizedBellShapedMembershipFunction::GetValue(const double x) { //--- return result return (1 / (1 + pow( fabs((x - m_a) / m_c) , 2 * m_b ))); } //+------------------------------------------------------------------+ //| S-shaped membership function | //+------------------------------------------------------------------+ class CS_ShapedMembershipFunction : public IMembershipFunction { private: double m_a; // Parametr a: beginning of the interval increases double m_b; // Parametr b: end of the interval increases public: CS_ShapedMembershipFunction(void); CS_ShapedMembershipFunction(const double a,const double b); ~CS_ShapedMembershipFunction(void); //--- methods gets or sets the parametrs void A(const double a) { m_a=a; } double A(void) { return(m_a); } void B(const double b) { m_b=b; } double B(void) { return(m_b); } //--- method gets the argument (x axis value) double GetValue(const double x); }; //+------------------------------------------------------------------+ //| Constructor without parameters | //+------------------------------------------------------------------+ CS_ShapedMembershipFunction::CS_ShapedMembershipFunction(void) { } //+------------------------------------------------------------------+ //| Constructor with parameters | //+------------------------------------------------------------------+ CS_ShapedMembershipFunction::CS_ShapedMembershipFunction(const double a,const double b) { m_a=a; m_b=b; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CS_ShapedMembershipFunction::~CS_ShapedMembershipFunction(void) { } //+------------------------------------------------------------------+ //| Get argument (x axis value) | //+------------------------------------------------------------------+ double CS_ShapedMembershipFunction::GetValue(const double x) { if(x<=m_a) { //--- return result return (0.0); } else if(m_a= m_b //--- return result return (1.0); } } //+------------------------------------------------------------------+ //| Z-shaped membership function | //+------------------------------------------------------------------+ class CZ_ShapedMembershipFunction : public IMembershipFunction { private: double m_a; // Parametr a: beginning of the interval decreasing double m_b; // Parametr b: end of the interval decreasing public: CZ_ShapedMembershipFunction(void); CZ_ShapedMembershipFunction(const double a,const double b); ~CZ_ShapedMembershipFunction(void); //--- methods gets or sets the parametrs void A(const double a) { m_a=a; } double A(void) { return(m_a); } void B(const double b) { m_b=b; } double B(void) { return(m_b); } //--- method gets the argument (x axis value) double GetValue(const double x); }; //+------------------------------------------------------------------+ //| Constructor without parameters | //+------------------------------------------------------------------+ CZ_ShapedMembershipFunction::CZ_ShapedMembershipFunction(void) { } //+------------------------------------------------------------------+ //| Constructor with parameters | //+------------------------------------------------------------------+ CZ_ShapedMembershipFunction::CZ_ShapedMembershipFunction(const double a,const double b) { m_a=a; m_b=b; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CZ_ShapedMembershipFunction::~CZ_ShapedMembershipFunction(void) { } //+------------------------------------------------------------------+ //| Get argument (x axis value) | //+------------------------------------------------------------------+ double CZ_ShapedMembershipFunction::GetValue(const double x) { if(x<=m_a) { //--- return result return (1.0); } else if(m_a= m_b //--- return result return (0.0); } } //+------------------------------------------------------------------+ //| P-shaped membership function | //+------------------------------------------------------------------+ class CP_ShapedMembershipFunction : public IMembershipFunction { private: double m_a; // Parametr a: carrier fuzzy set double m_d; // Parametr d: carrier fuzzy set double m_b; // Parametr b: the core of a fuzzy set double m_c; // Parametr c: the core of a fuzzy set public: CP_ShapedMembershipFunction(void); CP_ShapedMembershipFunction(const double a,const double b,const double c,const double d); ~CP_ShapedMembershipFunction(void); //--- methods gets or sets the parametrs void A(const double a) { m_a=a; } double A(void) { return(m_a); } void D(const double d) { m_d=d; } double D(void) { return(m_d); } void B(const double b) { m_b=b; } double B(void) { return(m_b); } void C(const double c) { m_c=c; } double C(void) { return(m_c); } //--- method gets the argument (x axis value) double GetValue(const double x); }; //+------------------------------------------------------------------+ //| Constructor without parameters | //+------------------------------------------------------------------+ CP_ShapedMembershipFunction::CP_ShapedMembershipFunction(void) { } //+------------------------------------------------------------------+ //| Constructor with parameters | //+------------------------------------------------------------------+ CP_ShapedMembershipFunction::CP_ShapedMembershipFunction(const double a,const double b,const double c,const double d) { m_a=a; m_d=d; m_b=b; m_c=c; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CP_ShapedMembershipFunction::~CP_ShapedMembershipFunction(void) { } //+------------------------------------------------------------------+ //| Get argument (x axis value) | //+------------------------------------------------------------------+ double CP_ShapedMembershipFunction::GetValue(const double x) { if(x<=m_a) { return(0.0); } else if(m_a=m_x4) { result=0; } else if((x>=m_x2) && (x<=m_x3)) { result=1; } else if((x>m_x1) && (x=m_x3) { result=0; } else if(x==m_x2) { result=1; } else if((x>m_x1) && (x1.0) { Print("Incorrect parameter! It is necessary to re-initialize them."); } m_constValue=constValue; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CConstantMembershipFunction::~CConstantMembershipFunction(void) { } //+--------------------------------------------------------------------------------------+ //| Composition of several membership functions represened as single membership function | //+--------------------------------------------------------------------------------------+ class CCompositeMembershipFunction : public IMembershipFunction { private: CList *m_mfs; // List of membership functions MfCompositionType m_composType; // Composite Type public: CCompositeMembershipFunction(MfCompositionType composType); CCompositeMembershipFunction(MfCompositionType composType,IMembershipFunction *mf1,IMembershipFunction *mf2); CCompositeMembershipFunction(MfCompositionType composType,CList *mfs); ~CCompositeMembershipFunction(void); //--- methods gets or sets the parametrs CList *MembershipFunctions(void) { return(m_mfs); } MfCompositionType CompositionType(void) { return(m_composType); } void CompositionType(MfCompositionType value) { m_composType=value; } //--- method gets the argument (x axis value) //+------------------------------------------------------------------+ //| Get argument (x axis value) | //+------------------------------------------------------------------+ double GetValue(double const x); private: //--- composition of the membership functions double Compose(const double val1,const double val2); }; //+------------------------------------------------------------------+ //| First constructor with parameters | //+------------------------------------------------------------------+ CCompositeMembershipFunction::CCompositeMembershipFunction(MfCompositionType composType) { m_mfs=new CList; m_composType=composType; } //+------------------------------------------------------------------+ //| Second constructor with parameters | //+------------------------------------------------------------------+ CCompositeMembershipFunction::CCompositeMembershipFunction(MfCompositionType composType,IMembershipFunction *mf1,IMembershipFunction *mf2) { m_mfs=new CList; m_mfs.Add(mf1); m_mfs.Add(mf2); m_composType=composType; } //+------------------------------------------------------------------+ //| Third constructor with parameters | //+------------------------------------------------------------------+ CCompositeMembershipFunction::CCompositeMembershipFunction(MfCompositionType composType,CList *mfs) { m_mfs=mfs; m_composType=composType; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CCompositeMembershipFunction::~CCompositeMembershipFunction() { m_mfs.FreeMode(false); delete m_mfs; } //+------------------------------------------------------------------+ //| Get argument (x axis value) | //+------------------------------------------------------------------+ double CCompositeMembershipFunction::GetValue(double const x) { if(m_mfs.Total()==0) { //--- return result return 0.0; } else if(m_mfs.Total()==1) { IMembershipFunction *fun=m_mfs.GetNodeAtIndex(0); //--- return result return fun.GetValue(x); } else { IMembershipFunction *fun=m_mfs.GetNodeAtIndex(0); double result=fun.GetValue(x); for(int i=1; i