| //+------------------------------------------------------------------+
|
| //| sugenovariable.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 <Arrays\List.mqh>
|
| #include "FuzzyVariable.mqh"
|
| #include "Dictionary.mqh"
|
| //+------------------------------------------------------------------+
|
| //| Purpose: creating Sugeno variable. |
|
| //+------------------------------------------------------------------+
|
| //+------------------------------------------------------------------+
|
| //| The base class for Linear Sugeno Function |
|
| //+------------------------------------------------------------------+
|
| class ISugenoFunction : public CNamedValueImpl
|
| {
|
| public:
|
| //--- method to check type
|
| virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_ISugenoFunction); }
|
| };
|
| //+------------------------------------------------------------------+
|
| //| Lenear function for Sugeno Fuzzy System |
|
| //+------------------------------------------------------------------+
|
| class CLinearSugenoFunction : public ISugenoFunction
|
| {
|
| private:
|
| CList *m_input; // List of input variables
|
| CList *m_coeffs; // The dictionary which stores variables and their coefficients
|
| double m_const_value; // The constant term of the linear equation
|
|
|
| public:
|
| CLinearSugenoFunction(const string name,CList *in);
|
| CLinearSugenoFunction(const string name,CList *in,CList *coeffs,const double constValue);
|
| CLinearSugenoFunction(const string name,CList *in,const double &coeffs[]);
|
| ~CLinearSugenoFunction(void);
|
| //--- method to check type
|
| virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_LinearSugenoFunction); }
|
| //--- methods gets or sets constant coefficient
|
| double ConstValue() { return(m_const_value); }
|
| void ConstValue(const double value) { m_const_value=value; }
|
| //--- methods gets or sets coefficient by fuzzy variable
|
| double GetCoefficient(CFuzzyVariable *var);
|
| void SetCoefficient(CFuzzyVariable *var,const double coeff);
|
| //--- calculate
|
| double Evaluate(CList *inputValues);
|
| };
|
| //+------------------------------------------------------------------+
|
| //| First constructor with parameters |
|
| //+------------------------------------------------------------------+
|
| CLinearSugenoFunction::CLinearSugenoFunction(const string name,CList *in)
|
| {
|
| m_coeffs=new CList;
|
| CNamedValueImpl::Name(name);
|
| m_input=in;
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Second constructor with parameters |
|
| //+------------------------------------------------------------------+
|
| CLinearSugenoFunction::CLinearSugenoFunction(const string name,CList *in,CList *coeffs,const double constValue)
|
| {
|
| CNamedValueImpl::Name(name);
|
| m_input=in;
|
| //--- Check that all coeffecients are related to the variable from input
|
| for(int i=0; i<coeffs.Total(); i++)
|
| {
|
| CDictionary_Obj_Double *p_vd=coeffs.GetNodeAtIndex(i);
|
| if((m_input.IndexOf(p_vd.Key())==-1) && (in.Total()==coeffs.Total()))
|
| {
|
| Print("Input of the fuzzy system does not contain all variable.");
|
| }
|
| }
|
| m_coeffs=coeffs;
|
| m_const_value=constValue;
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Third constructor with parameters |
|
| //+------------------------------------------------------------------+
|
| CLinearSugenoFunction::CLinearSugenoFunction(const string name,CList *in,const double &coeffs[])
|
| {
|
| m_coeffs=new CList;
|
| m_input=in;
|
| CNamedValueImpl::Name(name);
|
| //--- Check input values
|
| if(ArraySize(coeffs)!=in.Total() && ArraySize(coeffs)!=(in.Total()+1))
|
| {
|
| Print("Wrong lenght of coefficients array");
|
| }
|
| //--- Fill list of coefficients
|
| for(int i=0; i<in.Total(); i++)
|
| {
|
| CDictionary_Obj_Double *p_vd=new CDictionary_Obj_Double;
|
| CFuzzyVariable *var=in.GetNodeAtIndex(i);
|
| p_vd.SetAll(var,coeffs[i]);
|
| m_coeffs.Add(p_vd);
|
| }
|
| if(ArraySize(coeffs)==(in.Total()+1))
|
| {
|
| m_const_value=coeffs[ArraySize(coeffs)-1];
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Destructor |
|
| //+------------------------------------------------------------------+
|
| CLinearSugenoFunction::~CLinearSugenoFunction(void)
|
| {
|
| if(CheckPointer(m_input)==POINTER_DYNAMIC)
|
| delete m_input;
|
| if(CheckPointer(m_coeffs)==POINTER_DYNAMIC)
|
| delete m_coeffs;
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Get coefficient by fuzzy variable |
|
| //+------------------------------------------------------------------+
|
| double CLinearSugenoFunction::GetCoefficient(CFuzzyVariable *var)
|
| {
|
| if(var==NULL)
|
| {
|
| //--- return const coefficient
|
| return (m_const_value);
|
| }
|
| else
|
| {
|
| for(int i=0; i<m_coeffs.Total(); i++)
|
| {
|
| CDictionary_Obj_Double *p_vd=m_coeffs.GetNodeAtIndex(i);
|
| if(p_vd.Key()==var)
|
| {
|
| //--- return coefficient
|
| return (p_vd.Value());
|
| }
|
| }
|
| }
|
| //--- return NULL
|
| return (NULL);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Set coefficient by fuzzy variable |
|
| //+------------------------------------------------------------------+
|
| void CLinearSugenoFunction::SetCoefficient(CFuzzyVariable *var,const double coeff)
|
| {
|
| if(var==NULL)
|
| {
|
| m_const_value=coeff;
|
| }
|
| else
|
| {
|
| for(int i=0; i<m_coeffs.Total(); i++)
|
| {
|
| CDictionary_Obj_Double *p_vd=m_coeffs.GetNodeAtIndex(i);
|
| if(p_vd.Key()==var)
|
| {
|
| p_vd.Value(coeff);
|
| }
|
| m_coeffs.Delete(i);
|
| m_coeffs.Insert(p_vd,i);
|
| }
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Calculate result of linear function |
|
| //+------------------------------------------------------------------+
|
| double CLinearSugenoFunction::Evaluate(CList *inputValues)
|
| {
|
| double result=0.0;
|
| for(int i=0; i<m_coeffs.Total(); i++)
|
| {
|
| CDictionary_Obj_Double *p_vd1=m_coeffs.GetNodeAtIndex(i);
|
| CDictionary_Obj_Double *p_vd2=inputValues.GetNodeAtIndex(i);
|
| result+=(p_vd1.Value())*(p_vd2.Value());
|
| }
|
| result+=m_const_value;
|
| //--- return result
|
| return (result);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Used as an output variable in Sugeno fuzzy inference system |
|
| //+------------------------------------------------------------------+
|
| class CSugenoVariable : public CNamedVariableImpl
|
| {
|
| private:
|
| CList *m_functions; // List of Sugeno functions
|
|
|
| public:
|
| CSugenoVariable(const string name);
|
| ~CSugenoVariable(void);
|
| //--- method to check type
|
| virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_SugenoVariable); }
|
| //--- method gets the list of functions that belongs to the variable
|
| CList *Functions() { return(m_functions); }
|
| //--- overload gets the list of functions that belongs to the variable
|
| CList *Values() { return(m_functions); }
|
| //--- find function by name
|
| ISugenoFunction *GetFuncByName(const string name);
|
| };
|
| //+------------------------------------------------------------------+
|
| //| Constructor with parameters |
|
| //+------------------------------------------------------------------+
|
| CSugenoVariable::CSugenoVariable(const string name)
|
| {
|
| m_functions=new CList;
|
| CNamedVariableImpl::Name(name);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Destructor |
|
| //+------------------------------------------------------------------+
|
| CSugenoVariable::~CSugenoVariable(void)
|
| {
|
| delete m_functions;
|
| }
|
| //+--------------------------------------------------------------------------------------+
|
| //| Find function by its name |
|
| //+--------------------------------------------------------------------------------------+
|
| ISugenoFunction *CSugenoVariable::GetFuncByName(const string name)
|
| {
|
| CList *values=CSugenoVariable::Values();
|
| values.Total();
|
| for(int i=0; i<values.Total(); i++)
|
| {
|
| CNamedValueImpl *func=values.GetNodeAtIndex(i);
|
| if(func.Name()==name)
|
| {
|
| ISugenoFunction *result=m_functions.GetNodeAtIndex(i);
|
| //--- return result
|
| return (result);
|
| }
|
| }
|
| Print("The function of the same name is not found");
|
| //--- return
|
| return (NULL);
|
| }
|
| //+------------------------------------------------------------------+
|