Consolidate Python ignore rules into root gitignore
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| dictionary.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| 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 <Object.mqh>
|
||||
#include <Arrays\List.mqh>
|
||||
#include "RuleParser.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Gets the value associated with the specified key in the CList |
|
||||
//| Where key - string, value - CObject |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TryGetValue(CList *list,string key,CObject *&value)
|
||||
{
|
||||
for(int i=0; i<list.Total(); i++)
|
||||
{
|
||||
CDictionary_String_Obj *pair=list.GetNodeAtIndex(i);
|
||||
if(pair.Key()==key)
|
||||
{
|
||||
value=pair.Value();
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Removes a range of elements from a list of CList |
|
||||
//+------------------------------------------------------------------+
|
||||
void RemoveRange(CArrayObj &list,const int index,const int count)
|
||||
{
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
list.Delete(index);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| It creates a shallow copy of a range of elements |
|
||||
//| from the original list of CList |
|
||||
//+------------------------------------------------------------------+
|
||||
CArrayObj *GetRange(CArrayObj *list,const int index,const int count)
|
||||
{
|
||||
CArrayObj *new_list=new CArrayObj;
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
new_list.Add(list.At(i+index));
|
||||
}
|
||||
return (new_list);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Dictionary: Object - Object |
|
||||
//+------------------------------------------------------------------+
|
||||
class CDictionary_Obj_Obj : public CObject
|
||||
{
|
||||
private:
|
||||
CObject *m_key;
|
||||
CObject *m_value;
|
||||
|
||||
public:
|
||||
CDictionary_Obj_Obj(void);
|
||||
~CDictionary_Obj_Obj(void);
|
||||
//--- methods gets or sets the value
|
||||
CObject *Key() { return(m_key); }
|
||||
void Key(CObject *key) { m_key=key; }
|
||||
//--- methods gets or sets the key
|
||||
CObject *Value() { return(m_value); }
|
||||
void Value(CObject *value) { m_value=value; }
|
||||
//--- method sets the value and key
|
||||
void SetAll(CObject *key,CObject *value);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor without parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CDictionary_Obj_Obj::CDictionary_Obj_Obj(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CDictionary_Obj_Obj::~CDictionary_Obj_Obj()
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Sets the value and key |
|
||||
//+------------------------------------------------------------------+
|
||||
void CDictionary_Obj_Obj::SetAll(CObject *key,CObject *value)
|
||||
{
|
||||
m_key=key;
|
||||
m_value=value;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Dictionary: String - Object |
|
||||
//+------------------------------------------------------------------+
|
||||
class CDictionary_String_Obj : public CObject
|
||||
{
|
||||
private:
|
||||
string m_key;
|
||||
CObject *m_value;
|
||||
|
||||
public:
|
||||
CDictionary_String_Obj(void);
|
||||
~CDictionary_String_Obj(void);
|
||||
//--- methods gets or sets the value
|
||||
string Key() { return(m_key); }
|
||||
void Key(const string key) { m_key=key; }
|
||||
//--- methods gets or sets the key
|
||||
CObject *Value() { return(m_value); }
|
||||
void Value(CObject *value) { m_value=value; }
|
||||
//--- method sets the value and key
|
||||
void SetAll(const string key,CObject *value);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor without parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CDictionary_String_Obj::CDictionary_String_Obj(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CDictionary_String_Obj::~CDictionary_String_Obj()
|
||||
{
|
||||
if(CheckPointer(m_value)==POINTER_DYNAMIC)
|
||||
delete m_value;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Sets the value and key |
|
||||
//+------------------------------------------------------------------+
|
||||
void CDictionary_String_Obj::SetAll(const string key,CObject *value)
|
||||
{
|
||||
m_key=key;
|
||||
m_value=value;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Dictionary: Object - Double |
|
||||
//+------------------------------------------------------------------+
|
||||
class CDictionary_Obj_Double : public CObject
|
||||
{
|
||||
private:
|
||||
CObject *m_key;
|
||||
double m_value;
|
||||
|
||||
public:
|
||||
CDictionary_Obj_Double(void);
|
||||
~CDictionary_Obj_Double(void);
|
||||
//--- methods gets or sets the value
|
||||
CObject *Key() { return(m_key); }
|
||||
void Key(CObject *key) { m_key=key; }
|
||||
//--- methods gets or sets the key
|
||||
double Value() { return(m_value); }
|
||||
void Value(const double value) { m_value=value; }
|
||||
//--- method sets the value and key
|
||||
void SetAll(CObject *key,const double value);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor without parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CDictionary_Obj_Double::CDictionary_Obj_Double(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CDictionary_Obj_Double::~CDictionary_Obj_Double()
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Sets the value and key |
|
||||
//+------------------------------------------------------------------+
|
||||
void CDictionary_Obj_Double::SetAll(CObject *key,const double value)
|
||||
{
|
||||
m_key=key;
|
||||
m_value=value;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,371 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| fuzzyrule.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| 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 "InferenceMethod.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Purpose: Creating fuzzy rules |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| And/Or operator type |
|
||||
//+------------------------------------------------------------------+
|
||||
enum OperatorType
|
||||
{
|
||||
And, // And operator
|
||||
Or // Or operator
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hedge modifiers |
|
||||
//+------------------------------------------------------------------+
|
||||
enum HedgeType
|
||||
{
|
||||
None, // None
|
||||
Slightly, // Cube root
|
||||
Somewhat, // Square root
|
||||
Very, // Square
|
||||
Extremely // Cube
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class of CConditions used in the 'if' expression |
|
||||
//+------------------------------------------------------------------+
|
||||
class ICondition : public CObject
|
||||
{
|
||||
public:
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnCondition type) { return(type==TYPE_CLASS_ICondition); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Single condition |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSingleCondition : public ICondition
|
||||
{
|
||||
private:
|
||||
INamedVariable *m_var; // Type of variable
|
||||
INamedValue *m_term; // Type of value
|
||||
bool m_not; // Is MF inverted
|
||||
|
||||
public:
|
||||
CSingleCondition(void);
|
||||
CSingleCondition(INamedVariable *var,INamedValue *term);
|
||||
CSingleCondition(INamedVariable *var,INamedValue *term,bool not);
|
||||
~CSingleCondition(void);
|
||||
//--- methods gets or sets the varriable
|
||||
INamedVariable *Var(void) { return(m_var); }
|
||||
void Var(INamedVariable *value) { m_var=value; }
|
||||
//--- methods gets or sets mark "Is MF inverted"
|
||||
bool Not(void) { return(m_not); }
|
||||
void Not(bool not) { m_not=not; }
|
||||
//--- methods gets or sets term in expression
|
||||
INamedValue *Term(void) { return(m_term); }
|
||||
void Term(INamedValue *value) { m_term=value; }
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnCondition type) { return(type==TYPE_CLASS_SingleCondition); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor without parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CSingleCondition::CSingleCondition(void)
|
||||
{
|
||||
m_var = NULL;
|
||||
m_not = false;
|
||||
m_term=NULL;
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| First constructor with parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CSingleCondition::CSingleCondition(INamedVariable *var,INamedValue *term)
|
||||
{
|
||||
m_var=var;
|
||||
m_term=term;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Second constructor with parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CSingleCondition::CSingleCondition(INamedVariable *var,INamedValue *term,bool not)
|
||||
{
|
||||
m_var=var;
|
||||
m_term=term;
|
||||
m_not=not;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSingleCondition::~CSingleCondition(void)
|
||||
{
|
||||
if(CheckPointer(m_var)==POINTER_DYNAMIC)
|
||||
delete m_var;
|
||||
if(CheckPointer(m_term)==POINTER_DYNAMIC)
|
||||
delete m_term;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Condition of fuzzy rule for the both Mamdani and Sugeno systems |
|
||||
//+------------------------------------------------------------------+
|
||||
class CFuzzyCondition : public CSingleCondition
|
||||
{
|
||||
private:
|
||||
HedgeType m_hedge; // hedge type
|
||||
|
||||
public:
|
||||
CFuzzyCondition(CFuzzyVariable *var,CFuzzyTerm *term,bool not);
|
||||
CFuzzyCondition(CFuzzyVariable *var,CFuzzyTerm *term,bool not,HedgeType hedge);
|
||||
CFuzzyCondition(CFuzzyVariable *var,CFuzzyTerm *term);
|
||||
~CFuzzyCondition(void);
|
||||
//--- methods gets or sets the hedge type
|
||||
HedgeType Hedge(void) { return (m_hedge); }
|
||||
void Hedge(HedgeType value) { m_hedge=value; }
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnCondition type) { return(type==TYPE_CLASS_FuzzyCondition); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| First constructor with parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyCondition::CFuzzyCondition(CFuzzyVariable *var,CFuzzyTerm *term,bool not)
|
||||
{
|
||||
CSingleCondition::Var(var);
|
||||
CSingleCondition::Term(term);
|
||||
CSingleCondition::Not(not);
|
||||
m_hedge=None;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Second constructor with parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyCondition::CFuzzyCondition(CFuzzyVariable *var,CFuzzyTerm *term,bool not,HedgeType hedge)
|
||||
{
|
||||
CSingleCondition::Var(var);
|
||||
CSingleCondition::Term(term);
|
||||
CSingleCondition::Not(not);
|
||||
m_hedge=hedge;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Thrid constructor with parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyCondition::CFuzzyCondition(CFuzzyVariable *var,CFuzzyTerm *term)
|
||||
|
||||
{
|
||||
CSingleCondition::Var(var);
|
||||
CSingleCondition::Term(term);
|
||||
CSingleCondition::Not(false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyCondition::~CFuzzyCondition(void)
|
||||
{
|
||||
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Several CConditions linked by or/and operators |
|
||||
//+------------------------------------------------------------------+
|
||||
class CConditions : public ICondition
|
||||
{
|
||||
private:
|
||||
bool m_not; // Default : false
|
||||
OperatorType m_op; // Type of operator. Default : And
|
||||
CList *m_conditions; // List of CConditions
|
||||
|
||||
public:
|
||||
CConditions(void);
|
||||
~CConditions(void);
|
||||
//--- methods gets or sets the mark "Is MF inverted"
|
||||
bool Not(void) { return(m_not); }
|
||||
void Not(bool value) { m_not=value; }
|
||||
//--- methods gets or sets operator that links expressions (and/or)
|
||||
OperatorType Op(void) { return (m_op); }
|
||||
void Op(OperatorType value) { m_op=value; }
|
||||
//--- method gets the list of CConditions (single or multiples)
|
||||
CList *ConditionsList(void) { return(m_conditions); }
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnCondition type) { return(type==TYPE_CLASS_Conditions); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor without parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CConditions::CConditions(void)
|
||||
{
|
||||
m_not=false;
|
||||
m_op = And;
|
||||
m_conditions=new CList;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CConditions::~CConditions(void)
|
||||
{
|
||||
delete m_conditions;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class used by rule parser |
|
||||
//+------------------------------------------------------------------+
|
||||
class IParsableRule : public CObject
|
||||
{
|
||||
public:
|
||||
//--- methods gets or sets the condition (IF) part of the rule
|
||||
virtual CConditions *Condition(void) { return(NULL); }
|
||||
virtual void Condition(CConditions *value) { }
|
||||
//--- methods gets or sets the conclusion (THEN) part of the rule
|
||||
virtual CSingleCondition *Conclusion(void) { return(NULL); }
|
||||
virtual void Conclusion(CSingleCondition *value) { }
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnRule type) { return(type==TYPE_CLASS_IParsableRule); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Implements common functionality of fuzzy rules |
|
||||
//+------------------------------------------------------------------+
|
||||
class CGenericFuzzyRule : public IParsableRule
|
||||
{
|
||||
private:
|
||||
CConditions *m_generic_condition; // Generic path of condition
|
||||
|
||||
public:
|
||||
CGenericFuzzyRule(void);
|
||||
~CGenericFuzzyRule(void);
|
||||
//--- methods gets or sets the condition (IF) part of the rule
|
||||
CConditions *Condition(void) { return(m_generic_condition); }
|
||||
void Condition(CConditions *value) { m_generic_condition=value; }
|
||||
//--- methods create a single condition
|
||||
CFuzzyCondition *CreateCondition(CFuzzyVariable *var,CFuzzyTerm *term);
|
||||
CFuzzyCondition *CreateCondition(CFuzzyVariable *var,CFuzzyTerm *term,bool not);
|
||||
CFuzzyCondition *CreateCondition(CFuzzyVariable *var,CFuzzyTerm *term,bool not,HedgeType hedge);
|
||||
//--- methods gets or sets the conclusion (THEN) part of the rule
|
||||
virtual CSingleCondition *Conclusion(void) { return(NULL); }
|
||||
virtual void Conclusion(CSingleCondition *value) { }
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnRule type) { return(type==TYPE_CLASS_GenericFuzzyRule); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor without parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CGenericFuzzyRule::CGenericFuzzyRule(void)
|
||||
{
|
||||
m_generic_condition=new CConditions();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CGenericFuzzyRule::~CGenericFuzzyRule(void)
|
||||
{
|
||||
delete m_generic_condition;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a single condition(1) |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyCondition *CGenericFuzzyRule::CreateCondition(CFuzzyVariable *var,CFuzzyTerm *term)
|
||||
{
|
||||
//--- return fuzzy condition
|
||||
return new CFuzzyCondition(var, term);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a single condition(2) |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyCondition *CGenericFuzzyRule::CreateCondition(CFuzzyVariable *var,CFuzzyTerm *term,bool not)
|
||||
{
|
||||
//--- return fuzzy condition
|
||||
return new CFuzzyCondition(var, term, not);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a single condition(3) |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyCondition *CGenericFuzzyRule::CreateCondition(CFuzzyVariable *var,CFuzzyTerm *term,bool not,HedgeType hedge)
|
||||
{
|
||||
//--- return fuzzy condition
|
||||
return new CFuzzyCondition(var, term, not, hedge);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fuzzy rule for Mamdani fuzzy system. |
|
||||
//| NOTE: a rule cannot be created directly, only via |
|
||||
//| MamdaniFuzzySystem::EmptyRule or MamdaniFuzzySystem::ParseRule |
|
||||
//+------------------------------------------------------------------+
|
||||
class CMamdaniFuzzyRule : public CGenericFuzzyRule
|
||||
{
|
||||
private:
|
||||
CSingleCondition *m_mamdani_conclusion; // Mamdani conclusion
|
||||
double m_weight; // Weight of Mamdani rule
|
||||
|
||||
public:
|
||||
CMamdaniFuzzyRule(void);
|
||||
~CMamdaniFuzzyRule(void);
|
||||
//--- methods gets or sets the conclusion (THEN) part of the rule
|
||||
CSingleCondition *Conclusion(void) { return(m_mamdani_conclusion); }
|
||||
void Conclusion(CSingleCondition *value) { m_mamdani_conclusion=value; }
|
||||
//--- methods gets or sets the rule weight
|
||||
double Weight(void) { return(m_weight); }
|
||||
void Weight(const double value) { m_weight=value; }
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnRule type) { return(type==TYPE_CLASS_MamdaniFuzzyRule); }
|
||||
};
|
||||
//+---------------------------------------------------------------+
|
||||
//| Constructor without parameters |
|
||||
//+---------------------------------------------------------------+
|
||||
CMamdaniFuzzyRule::CMamdaniFuzzyRule(void)
|
||||
{
|
||||
m_weight=1.0;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CMamdaniFuzzyRule::~CMamdaniFuzzyRule(void)
|
||||
{
|
||||
if(CheckPointer(m_mamdani_conclusion)==POINTER_DYNAMIC)
|
||||
delete m_mamdani_conclusion;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fuzzy rule for Sugeno fuzzy system |
|
||||
//| NOTE: a rule cannot be created directly, only via |
|
||||
//| SugenoFuzzySystem::EmptyRule or SugenoFuzzySystem::ParseRule |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSugenoFuzzyRule : public CGenericFuzzyRule
|
||||
{
|
||||
private:
|
||||
CSingleCondition *m_sugeno_conclusion; // Sugeno conclusion
|
||||
|
||||
public:
|
||||
CSugenoFuzzyRule(void);
|
||||
~CSugenoFuzzyRule(void);
|
||||
//--- methods gets or sets the conclusion (THEN) part of the rule
|
||||
CSingleCondition *Conclusion(void) { return(m_sugeno_conclusion); }
|
||||
void Conclusion(CSingleCondition *value) { m_sugeno_conclusion=value; }
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnRule type) { return(type==TYPE_CLASS_SugenoFuzzyRule); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor without parameters |
|
||||
//+-------------------------- ---------------------------------------+
|
||||
CSugenoFuzzyRule::CSugenoFuzzyRule(void)
|
||||
{
|
||||
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSugenoFuzzyRule::~CSugenoFuzzyRule(void)
|
||||
{
|
||||
if(CheckPointer(m_sugeno_conclusion)==POINTER_DYNAMIC)
|
||||
delete m_sugeno_conclusion;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,69 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| fuzzyterm.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| 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 "MembershipFunction.mqh"
|
||||
#include "Helper.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Purpose: creating fuzzy term. |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fuzzy or linguistic term. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CFuzzyTerm : public CNamedValueImpl
|
||||
{
|
||||
private:
|
||||
IMembershipFunction *m_mf; // The membership function of the term
|
||||
|
||||
public:
|
||||
CFuzzyTerm(const string name,IMembershipFunction *mf);
|
||||
~CFuzzyTerm(void);
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_FuzzyTerm); }
|
||||
//--- method gets the membership function initially associated with the term
|
||||
IMembershipFunction *MembershipFunction() { return(m_mf); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor with parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyTerm::CFuzzyTerm(const string name,IMembershipFunction *mf)
|
||||
{
|
||||
CNamedValueImpl::Name(name);
|
||||
m_mf=mf;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyTerm::~CFuzzyTerm(void)
|
||||
{
|
||||
if(CheckPointer(m_mf)==POINTER_DYNAMIC)
|
||||
{
|
||||
delete m_mf;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,113 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| fuzzyvariable.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| 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 "FuzzyTerm.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Purpose: creating fuzzy variable |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fuzzy or linguistic variable. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CFuzzyVariable : public CNamedVariableImpl
|
||||
{
|
||||
private:
|
||||
double m_min; // Minimum value of the variable
|
||||
double m_max; // Maximum value of the variable
|
||||
CList *m_terms; // List of terms in a variable
|
||||
|
||||
public :
|
||||
CFuzzyVariable(const string name,const double min,const double max);
|
||||
~CFuzzyVariable(void);
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_FuzzyVariable); }
|
||||
//--- methods gets or sets parameters of varriable
|
||||
void Max(const double max) { m_max=max; }
|
||||
double Max(void) { return (m_max); }
|
||||
void Min(const double min) { m_min=min; }
|
||||
double Min(void) { return (m_min); }
|
||||
//--- methods gets or sets the terms
|
||||
CList *Terms() { return(m_terms); }
|
||||
void Terms(CList *terms) { m_terms=terms; }
|
||||
//--- add fuzzy term
|
||||
void AddTerm(CFuzzyTerm *term);
|
||||
//--- get membership function by name
|
||||
CFuzzyTerm *GetTermByName(const string name);
|
||||
//--- overload
|
||||
CList *Values() { return(m_terms); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor with parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyVariable::CFuzzyVariable(const string name,const double min,const double max)
|
||||
{
|
||||
CNamedVariableImpl::Name(name);
|
||||
m_terms=new CList();
|
||||
if(min>max)
|
||||
{
|
||||
Print("Incorrect parameters! Maximum value must be greater than minimum one.");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_min = min;
|
||||
m_max = max;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyVariable::~CFuzzyVariable(void)
|
||||
{
|
||||
delete m_terms;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Add fuzzy term to list terms in a variable |
|
||||
//+------------------------------------------------------------------+
|
||||
void CFuzzyVariable::AddTerm(CFuzzyTerm *term)
|
||||
{
|
||||
m_terms.Add(term);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get membership function (term) by name |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyTerm *CFuzzyVariable::GetTermByName(const string name)
|
||||
{
|
||||
for(int i=0; i<m_terms.Total(); i++)
|
||||
{
|
||||
CFuzzyTerm *term=m_terms.GetNodeAtIndex(i);
|
||||
if(term.Name()==name)
|
||||
{
|
||||
//--- return fuzzy term
|
||||
return (term);
|
||||
}
|
||||
}
|
||||
Print("Term with the same name can not be found!");
|
||||
//--- return
|
||||
return (NULL);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,333 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| genericfuzzysystem.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| 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 <Arrays\ArrayObj.mqh>
|
||||
#include "FuzzyRule.mqh"
|
||||
#include "InferenceMethod.mqh"
|
||||
#include "Dictionary.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Purpose: Creating generic fuzzy system |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common functionality of Mamdani and Sugeno fuzzy systems |
|
||||
//+------------------------------------------------------------------+
|
||||
class CGenericFuzzySystem
|
||||
{
|
||||
private:
|
||||
CList *m_input; // List of input fuzzy variables
|
||||
EnAndMethod m_and_method; // And method from InferenceMethod
|
||||
EnOrMethod m_or_method; // Or method from InferenceMethod
|
||||
|
||||
protected:
|
||||
CGenericFuzzySystem(void);
|
||||
~CGenericFuzzySystem(void);
|
||||
public:
|
||||
//--- method gets the input linguistic variables
|
||||
CList *Input(void) { return(m_input); }
|
||||
//--- method gets or sets the type of "And method"
|
||||
void AndMethod(EnAndMethod value) { m_and_method=value; }
|
||||
EnAndMethod AndMethod(void) const { return (m_and_method); }
|
||||
//--- method gets or sets the type of "Or method"
|
||||
void OrMethod(EnOrMethod value) { m_or_method=value; }
|
||||
EnOrMethod OrMethod(void) const { return (m_or_method); }
|
||||
//--- method gets the varriable by name
|
||||
CFuzzyVariable *InputByName(const string name);
|
||||
//--- common steps of calculating
|
||||
CList *Fuzzify(CList *inputValues);
|
||||
protected:
|
||||
double EvaluateCondition(ICondition *condition,CList *fuzzifiedInput);
|
||||
double EvaluateConditionPair(const double cond1,const double cond2,OperatorType op);
|
||||
private:
|
||||
bool ValidateInputValues(CList *inputValues,string &msg);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor without parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CGenericFuzzySystem::CGenericFuzzySystem(void)
|
||||
{
|
||||
m_input=new CList;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CGenericFuzzySystem::~CGenericFuzzySystem(void)
|
||||
{
|
||||
if(CheckPointer(m_input)==POINTER_DYNAMIC)
|
||||
{
|
||||
delete m_input;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get input linguistic variable by its name |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyVariable *CGenericFuzzySystem::InputByName(const string name)
|
||||
{
|
||||
CList *result=CGenericFuzzySystem::Input();
|
||||
for(int i=0; i<result.Total(); i++)
|
||||
{
|
||||
CFuzzyVariable *var=result.GetNodeAtIndex(i);
|
||||
if(var.Name()==name)
|
||||
{
|
||||
//--- return fuzzy variable
|
||||
return (var);
|
||||
}
|
||||
}
|
||||
Print("The variable with that name is not found");
|
||||
//--- return
|
||||
return (NULL);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fuzzify input |
|
||||
//+------------------------------------------------------------------+
|
||||
CList *CGenericFuzzySystem::Fuzzify(CList *inputValues)
|
||||
{
|
||||
//--- Validate input
|
||||
string msg;
|
||||
if(!ValidateInputValues(inputValues,msg))
|
||||
{
|
||||
Print(msg);
|
||||
//--- return
|
||||
return (NULL);
|
||||
}
|
||||
//--- Fill results list
|
||||
CList *result=new CList;
|
||||
for(int i=0; i<Input().Total(); i++)
|
||||
{
|
||||
CFuzzyVariable *var=Input().GetNodeAtIndex(i);
|
||||
double value=NULL;
|
||||
for(int k=0; k<inputValues.Total(); k++)
|
||||
{
|
||||
CDictionary_Obj_Double *p_vd=inputValues.GetNodeAtIndex(i);
|
||||
CFuzzyVariable *v=p_vd.Key();
|
||||
if(p_vd.Key()==var)
|
||||
{
|
||||
value=p_vd.Value();
|
||||
break;
|
||||
}
|
||||
}
|
||||
CList *resultForVar=new CList;
|
||||
for(int j=0; j<var.Terms().Total(); j++)
|
||||
{
|
||||
CDictionary_Obj_Double *p_vd=new CDictionary_Obj_Double;
|
||||
CFuzzyTerm *term=var.Terms().GetNodeAtIndex(j);
|
||||
p_vd.SetAll(term,term.MembershipFunction().GetValue(value));
|
||||
resultForVar.Add(p_vd);
|
||||
}
|
||||
CDictionary_Obj_Obj *p_vl=new CDictionary_Obj_Obj;
|
||||
p_vl.SetAll(var,resultForVar);
|
||||
result.Add(p_vl);
|
||||
}
|
||||
//--- return result
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Evaluate fuzzy condition (or conditions) |
|
||||
//+------------------------------------------------------------------+
|
||||
double CGenericFuzzySystem::EvaluateCondition(ICondition *condition,CList *fuzzifiedInput)
|
||||
{
|
||||
double result=0.0;
|
||||
ICondition *IC;
|
||||
if(condition.IsTypeOf(TYPE_CLASS_Conditions))
|
||||
{
|
||||
CConditions *conds=condition;
|
||||
if(conds.ConditionsList().Total()==0)
|
||||
{
|
||||
Print("Inner exception.");
|
||||
}
|
||||
else if(conds.ConditionsList().Total()==1)
|
||||
{
|
||||
IC=conds.ConditionsList().GetNodeAtIndex(0);
|
||||
result=EvaluateCondition(IC,fuzzifiedInput);
|
||||
}
|
||||
else
|
||||
{
|
||||
IC=conds.ConditionsList().GetNodeAtIndex(0);
|
||||
result=EvaluateCondition(IC,fuzzifiedInput);
|
||||
for(int i=1; i<conds.ConditionsList().Total(); i++)
|
||||
{
|
||||
IC=conds.ConditionsList().GetNodeAtIndex(i);
|
||||
double cond2=EvaluateCondition(IC,fuzzifiedInput);;
|
||||
result=EvaluateConditionPair(result,cond2,conds.Op());
|
||||
}
|
||||
}
|
||||
if(conds.Not())
|
||||
{
|
||||
result=1.0-result;
|
||||
}
|
||||
//--- return result
|
||||
return (result);
|
||||
}
|
||||
else if(condition.IsTypeOf(TYPE_CLASS_FuzzyCondition))
|
||||
{
|
||||
CFuzzyCondition *cond=condition;
|
||||
CDictionary_Obj_Obj *p_vl;
|
||||
CDictionary_Obj_Double *p_td;
|
||||
for(int i=0; i<fuzzifiedInput.Total(); i++)
|
||||
{
|
||||
p_vl=fuzzifiedInput.GetNodeAtIndex(i);
|
||||
if(p_vl.Key()==cond.Var())
|
||||
{
|
||||
CList *list=p_vl.Value();
|
||||
for(int j=0; j<list.Total(); j++)
|
||||
{
|
||||
p_td=list.GetNodeAtIndex(j);
|
||||
if(p_td.Key()==cond.Term())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
result=p_td.Value();
|
||||
switch(cond.Hedge())
|
||||
{
|
||||
case Slightly:
|
||||
//--- Cube root
|
||||
result=pow(result,1.0/3.0);
|
||||
break;
|
||||
case Somewhat:
|
||||
result=sqrt(result);
|
||||
break;
|
||||
case Very:
|
||||
result=result*result;
|
||||
break;
|
||||
case Extremely:
|
||||
result=result*result*result;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(cond.Not())
|
||||
{
|
||||
result=1.0-result;
|
||||
}
|
||||
//--- return result
|
||||
return (result);
|
||||
}
|
||||
else
|
||||
{
|
||||
Print("Internal error.");
|
||||
//--- return
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Evaluate fuzzy condition (or conditions) |
|
||||
//+------------------------------------------------------------------+
|
||||
double CGenericFuzzySystem::EvaluateConditionPair(const double cond1,const double cond2,OperatorType op)
|
||||
{
|
||||
if(op==And)
|
||||
{
|
||||
if(CGenericFuzzySystem::AndMethod()==MinAnd)
|
||||
{
|
||||
//--- return evaluate condition
|
||||
return fmin(cond1, cond2);
|
||||
}
|
||||
else if(CGenericFuzzySystem::AndMethod()==ProductionAnd)
|
||||
{
|
||||
//--- return evaluate condition
|
||||
return (cond1 * cond2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Print("Internal error.");
|
||||
//--- return
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
else if(op==Or)
|
||||
{
|
||||
if(CGenericFuzzySystem::OrMethod()==MaxOr)
|
||||
{
|
||||
//--- return evaluate condition
|
||||
return fmax(cond1, cond2);
|
||||
}
|
||||
else if(CGenericFuzzySystem::OrMethod()==ProbabilisticOr)
|
||||
{
|
||||
//--- return evaluate condition
|
||||
return (cond1 + cond2 - cond1 * cond2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Print("Internal error.");
|
||||
//--- return
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Print("Internal error.");
|
||||
//--- return
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validate input values |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CGenericFuzzySystem::ValidateInputValues(CList *inputValues,string &msg)
|
||||
{
|
||||
msg=NULL;
|
||||
if(inputValues.Total()!=Input().Total())
|
||||
{
|
||||
msg="Input values count is incorrect.";
|
||||
//--- return false
|
||||
return (false);
|
||||
}
|
||||
bool contain;
|
||||
for(int i=0; i<Input().Total(); i++)
|
||||
{
|
||||
CFuzzyVariable *var=Input().GetNodeAtIndex(i);
|
||||
contain=false;
|
||||
for(int j=0; j<inputValues.Total();j++)
|
||||
{
|
||||
CDictionary_Obj_Double *p_vd=inputValues.GetNodeAtIndex(j);
|
||||
if(p_vd.Key()==var)
|
||||
{
|
||||
contain=true;
|
||||
double val=p_vd.Value();
|
||||
if(val<var.Min() || val>var.Max())
|
||||
{
|
||||
msg=StringFormat("Value for the %s variable is out of range.",var.Name());
|
||||
//--- return false
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(contain==false)
|
||||
{
|
||||
msg=StringFormat("Value for the %s variable does not present.",var.Name());
|
||||
//--- return false
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
//--- return true
|
||||
return (true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,158 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| helper.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| 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 "InferenceMethod.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Purpose: Analysis of the fuzzy rules |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| This class must be implemented by values in parsable rules |
|
||||
//+------------------------------------------------------------------+
|
||||
class INamedValue : public CObject
|
||||
{
|
||||
public:
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_INamedValue); }
|
||||
//--- methods gets or sets the name
|
||||
virtual string Name(void) { return(""); }
|
||||
virtual void Name(const string name) { }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| This class must be implemented by values in parsable rules |
|
||||
//+------------------------------------------------------------------+
|
||||
class INamedVariable : public INamedValue
|
||||
{
|
||||
public:
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_INamedValue); }
|
||||
//--- get list of values that belongs to the variable
|
||||
virtual CList *Values(void) { return(NULL); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Named variable |
|
||||
//+------------------------------------------------------------------+
|
||||
class CNamedVariableImpl : public INamedVariable
|
||||
{
|
||||
private:
|
||||
string m_name; // Name of the variable
|
||||
|
||||
public:
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_NamedVariableImpl); }
|
||||
//--- methods gets or sets varriable name
|
||||
virtual void Name(const string name);
|
||||
virtual string Name(void) { return(m_name); }
|
||||
//--- get list of values that belongs to the variable
|
||||
virtual CList *Values(void) { return(NULL); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set variable name |
|
||||
//+------------------------------------------------------------------+
|
||||
void CNamedVariableImpl::Name(const string name)
|
||||
{
|
||||
if(!CNameHelper::IsValidName(name))
|
||||
{
|
||||
Print("Invalid variable name.");
|
||||
}
|
||||
m_name=name;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Named value of variable |
|
||||
//+------------------------------------------------------------------+
|
||||
class CNamedValueImpl : public INamedValue
|
||||
{
|
||||
private:
|
||||
string m_name; // Name of the value
|
||||
|
||||
public:
|
||||
//--- method to check type
|
||||
virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_NamedVariableImpl); }
|
||||
//--- methods gets or sets varriable name
|
||||
virtual void Name(const string name);
|
||||
virtual string Name(void) { return(m_name); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set variable name |
|
||||
//+------------------------------------------------------------------+
|
||||
void CNamedValueImpl::Name(const string name)
|
||||
{
|
||||
if(!CNameHelper::IsValidName(name))
|
||||
{
|
||||
Print("Invalid term name.");
|
||||
}
|
||||
m_name=name;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Keywords: |
|
||||
//+------------------------------------------------------------------+
|
||||
static string KEYWORDS[]={ "if","then","is","and","or","not","(",")","slightly","somewhat","very","extremely" }; // Keywords in rules
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class NameHelper checks the availability of names |
|
||||
//+------------------------------------------------------------------+
|
||||
class CNameHelper
|
||||
{
|
||||
public:
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check the name of variable/term |
|
||||
//+------------------------------------------------------------------+
|
||||
static bool IsValidName(const string name)
|
||||
{
|
||||
//--- Empty names are not allowed
|
||||
if(StringLen(name)==0)
|
||||
{
|
||||
//--- return false
|
||||
return (false);
|
||||
}
|
||||
|
||||
for(int i=0; i<StringLen(name); i++)
|
||||
{
|
||||
//--- Only letters, numbers or '_' are allowed
|
||||
char s=(char) StringGetCharacter(name,i);
|
||||
if(s!='_' && !(s>=48 && s<=57) // Not numbers and symbol '_'
|
||||
&& !( s >= 65 && s <= 90 ) // Not capital letters
|
||||
&& !( s >= 97 && s <= 122 )) // Not letters
|
||||
{
|
||||
//--- return false
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
//--- Identifier cannot be a keword
|
||||
for(int i=0; i<ArraySize(KEYWORDS); i++)
|
||||
{
|
||||
if(name==KEYWORDS[i])
|
||||
{
|
||||
//--- return false
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
//--- return true
|
||||
return (true);
|
||||
}
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,125 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| inferencemethod.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| 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>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Purpose: Contains a number of enumerations, |
|
||||
//| for the convenience of working with other files |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| And evaluating method |
|
||||
//+------------------------------------------------------------------+
|
||||
enum EnAndMethod
|
||||
{
|
||||
MinAnd, // Minimum: min(a, b)
|
||||
ProductionAnd // Production: a * b
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Or evaluating method |
|
||||
//+------------------------------------------------------------------+
|
||||
enum EnOrMethod
|
||||
{
|
||||
MaxOr, // Maximum: max(a, b)
|
||||
ProbabilisticOr // Probabilistic OR: a + b - a * b
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fuzzy implication method |
|
||||
//+------------------------------------------------------------------+
|
||||
enum ImplicationMethod
|
||||
{
|
||||
MinIpm, // Truncation of output fuzzy set
|
||||
ProductionImp // Scaling of output fuzzy set
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Aggregation method for membership functions |
|
||||
//+------------------------------------------------------------------+
|
||||
enum AggregationMethod
|
||||
{
|
||||
MaxAgg, // Maximum of rule outpus
|
||||
SumAgg // Sum of rule output
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Defuzzification method |
|
||||
//+------------------------------------------------------------------+
|
||||
enum DefuzzificationMethod
|
||||
{
|
||||
CentroidDef, // Center of area of fuzzy result MF
|
||||
BisectorDef, // The point divides the area under the MF into two equal
|
||||
AverageMaximumDef, // Arithmetic mean of all the maxima of the MF
|
||||
LargestMaximumDef, // The largest of the maxima of the membership function
|
||||
SmallestMaximumDef // The smallest of the maxima of the membership function
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Type of varriable and term |
|
||||
//+------------------------------------------------------------------+
|
||||
enum EnType
|
||||
{
|
||||
TYPE_CLASS_INamedValue, // Base class
|
||||
TYPE_CLASS_INamedVariable, // INamedVariable : INamedValue
|
||||
TYPE_CLASS_NamedVariableImpl, // NamedVariableImpl : INamedVariable
|
||||
TYPE_CLASS_NamedValueImpl, // NamedValueImpl : INamedValue
|
||||
TYPE_CLASS_FuzzyTerm, // FuzzyTerm : NamedValueImpl
|
||||
TYPE_CLASS_FuzzyVariable, // FuzzyVariable : NamedVariableImpl
|
||||
TYPE_CLASS_SugenoVariable, // SugenoVariable : NamedVariableImpl
|
||||
TYPE_CLASS_ISugenoFunction, // ISugenoFunction : NamedValueImpl
|
||||
TYPE_CLASS_LinearSugenoFunction // LinearSugenoFunction : ISugenoFunction
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Type of expression |
|
||||
//+------------------------------------------------------------------+
|
||||
enum EnLexem
|
||||
{
|
||||
TYPE_CLASS_IExpression, // Base class
|
||||
TYPE_CLASS_Lexem, // Lexem : IExpression
|
||||
TYPE_CLASS_ConditionExpression, // ConditionExpression : IExpression
|
||||
TYPE_CLASS_VarLexem, // VarLexem : Lexem
|
||||
TYPE_CLASS_KeywordLexem, // KeywordLexem : Lexem
|
||||
TYPE_CLASS_AltLexem, // AltLexem : Lexem
|
||||
TYPE_CLASS_TermLexem // TermLexem : AltLexem
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Type of condition |
|
||||
//+------------------------------------------------------------------+
|
||||
enum EnCondition
|
||||
{
|
||||
TYPE_CLASS_ICondition, // Base class
|
||||
TYPE_CLASS_Conditions, // Conditions : ICondition
|
||||
TYPE_CLASS_SingleCondition, // SingleCondition : ICondition
|
||||
TYPE_CLASS_FuzzyCondition // FuzzyCondition : SingleCondition
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Type of rule |
|
||||
//+------------------------------------------------------------------+
|
||||
enum EnRule
|
||||
{
|
||||
TYPE_CLASS_IParsableRule, // Base class
|
||||
TYPE_CLASS_GenericFuzzyRule, // GenericFuzzyRule : IParsableRule
|
||||
TYPE_CLASS_MamdaniFuzzyRule, // MamdaniFuzzyRule : GenericFuzzyRule
|
||||
TYPE_CLASS_SugenoFuzzyRule // SugenoFuzzyRule : GenericFuzzyRule
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,556 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| mandanifuzzysystem.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| 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 <Arrays\ArrayDouble.mqh>
|
||||
#include "GenericFuzzySystem.mqh"
|
||||
#include "InferenceMethod.mqh"
|
||||
#include "RuleParser.mqh"
|
||||
#include "FuzzyRule.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Purpose: Creating Mamdani fuzzy system |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| Mamdani fuzzy inference system |
|
||||
//+------------------------------------------------------------------+
|
||||
class CMamdaniFuzzySystem : public CGenericFuzzySystem
|
||||
{
|
||||
private:
|
||||
CList* m_output; // List of fuzzy variable
|
||||
CList* m_rules; // List of Mamdani fuzzy rule
|
||||
ImplicationMethod m_impl_method; // Implication method
|
||||
AggregationMethod m_aggr_method; // Aggregation method
|
||||
DefuzzificationMethod m_defuzz_method; // Defuzzification method
|
||||
|
||||
public:
|
||||
CMamdaniFuzzySystem(void);
|
||||
~CMamdaniFuzzySystem(void);
|
||||
//--- method gets the output linguistic variables
|
||||
CList* Output(void) { return(m_output); }
|
||||
//--- method gets the fuzzy rule
|
||||
CList* Rules(void) { return(m_rules); }
|
||||
//--- methods gets or sets the implication method
|
||||
ImplicationMethod GetImplicationMethod(void) const { return (m_impl_method); }
|
||||
void SetImplicationMethod(ImplicationMethod value) { m_impl_method=value; }
|
||||
//--- methods gets or sets the aggregation method
|
||||
AggregationMethod GetAggregationMethod(void) const { return (m_aggr_method); }
|
||||
void SetAggregationMethod(AggregationMethod value) { m_aggr_method=value; }
|
||||
//--- methods gets or sets the defuzzification method
|
||||
DefuzzificationMethod GetDefuzzificationMethod(void) const { return (m_defuzz_method); }
|
||||
void SetDefuzzificationMethod(DefuzzificationMethod value) { m_defuzz_method=value; }
|
||||
//--- maethod gets the variable by name
|
||||
CFuzzyVariable* OutputByName(const string name);
|
||||
//--- create a new rule
|
||||
CMamdaniFuzzyRule* EmptyRule(void);
|
||||
//--- parse rule
|
||||
CMamdaniFuzzyRule* ParseRule(const string rule);
|
||||
//--- method for calculate result
|
||||
CList* Calculate(CList *inputValues);
|
||||
CList* EvaluateConditions(CList *fuzzifiedInput);
|
||||
CList* Implicate(CList *conditions);
|
||||
CList* Aggregate(CList *conclusions);
|
||||
CList* Defuzzify(CList *fuzzyResult);
|
||||
double Defuzzify(IMembershipFunction *mf,const double min,const double max);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor without parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CMamdaniFuzzySystem::CMamdaniFuzzySystem(void)
|
||||
{
|
||||
m_output = new CList;
|
||||
m_rules = new CList;
|
||||
m_impl_method = MinIpm; // Implication method default is Min
|
||||
m_aggr_method = MaxAgg; // Aggregation method default is Max
|
||||
m_defuzz_method = CentroidDef; // Defuzzification method default is Centroid
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CMamdaniFuzzySystem::~CMamdaniFuzzySystem(void)
|
||||
{
|
||||
delete m_output;
|
||||
delete m_rules;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get output linguistic variable by its name |
|
||||
//+------------------------------------------------------------------+
|
||||
CFuzzyVariable *CMamdaniFuzzySystem::OutputByName(const string name)
|
||||
{
|
||||
for(int i=0; i<m_output.Total(); i++)
|
||||
{
|
||||
CFuzzyVariable *var=m_output.GetNodeAtIndex(i);
|
||||
if(var.Name()==name)
|
||||
{
|
||||
//--- return varriable
|
||||
return (var);
|
||||
}
|
||||
}
|
||||
Print("Variable with that name is not found");
|
||||
//--- return
|
||||
return (NULL);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create new empty rule |
|
||||
//+------------------------------------------------------------------+
|
||||
CMamdaniFuzzyRule *CMamdaniFuzzySystem::EmptyRule()
|
||||
{
|
||||
//--- return empty rule
|
||||
return new CMamdaniFuzzyRule();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Parse rule from the string |
|
||||
//+------------------------------------------------------------------+
|
||||
CMamdaniFuzzyRule *CMamdaniFuzzySystem::ParseRule(const string rule)
|
||||
{
|
||||
//--- return Mamdani fuzzy rule
|
||||
return CRuleParser::Parse(rule, EmptyRule(), Input(), Output());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate output values |
|
||||
//+------------------------------------------------------------------+
|
||||
CList *CMamdaniFuzzySystem::Calculate(CList *inputValues)
|
||||
{
|
||||
//--- There should be one rule as minimum
|
||||
if(m_rules.Total()==0)
|
||||
{
|
||||
Print("There should be one rule as minimum.");
|
||||
//--- return
|
||||
return (NULL);
|
||||
}
|
||||
//--- Fuzzification step
|
||||
CList *fuzzifiedInput=Fuzzify(inputValues);
|
||||
//--- Evaluate the conditions
|
||||
CList *evaluatedConditions=EvaluateConditions(fuzzifiedInput);
|
||||
//--- Do implication for each rule
|
||||
CList *implicatedConclusions=Implicate(evaluatedConditions);
|
||||
//--- Aggrerate the results
|
||||
CList *fuzzyResult=Aggregate(implicatedConclusions);
|
||||
//--- Defuzzify the result
|
||||
CList *result=Defuzzify(fuzzyResult);
|
||||
//---
|
||||
delete fuzzyResult;
|
||||
for(int i=0; i<implicatedConclusions.Total(); i++)
|
||||
{
|
||||
CDictionary_Obj_Obj *pair=implicatedConclusions.GetNodeAtIndex(i);
|
||||
CCompositeMembershipFunction *composite=pair.Value();
|
||||
delete composite.MembershipFunctions().GetNodeAtIndex(0);
|
||||
delete composite;
|
||||
}
|
||||
delete implicatedConclusions;
|
||||
delete evaluatedConditions;
|
||||
for(int i=0; i<fuzzifiedInput.Total(); i++)
|
||||
{
|
||||
CDictionary_Obj_Obj *pair=fuzzifiedInput.GetNodeAtIndex(i);
|
||||
delete pair.Value();
|
||||
}
|
||||
delete fuzzifiedInput;
|
||||
//--- return result
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Evaluate conditions |
|
||||
//+------------------------------------------------------------------+
|
||||
CList *CMamdaniFuzzySystem::EvaluateConditions(CList *fuzzifiedInput)
|
||||
{
|
||||
CList *result=new CList;
|
||||
for(int i=0; i<Rules().Total(); i++)
|
||||
{
|
||||
CDictionary_Obj_Double *p_rd=new CDictionary_Obj_Double;
|
||||
CMamdaniFuzzyRule *rule=Rules().GetNodeAtIndex(i);
|
||||
p_rd.SetAll(rule,EvaluateCondition(rule.Condition(),fuzzifiedInput));
|
||||
result.Add(p_rd);
|
||||
}
|
||||
//--- return result
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Implicate rule results |
|
||||
//+------------------------------------------------------------------+
|
||||
CList *CMamdaniFuzzySystem::Implicate(CList *conditions)
|
||||
{
|
||||
CList *conclusions=new CList;
|
||||
for(int i=0; i<conditions.Total(); i++)
|
||||
{
|
||||
CDictionary_Obj_Double *p_rd=conditions.GetNodeAtIndex(i);
|
||||
CMamdaniFuzzyRule *rule=p_rd.Key();
|
||||
MfCompositionType compType;
|
||||
switch(m_impl_method)
|
||||
{
|
||||
case MinIpm :
|
||||
{
|
||||
compType=MinMF;
|
||||
break;
|
||||
}
|
||||
case ProductionImp :
|
||||
{
|
||||
compType=ProdMF;
|
||||
break;
|
||||
}
|
||||
default :
|
||||
{
|
||||
Print("Internal error.");
|
||||
//---
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
CFuzzyTerm *val=rule.Conclusion().Term();
|
||||
IMembershipFunction *first_fun=new CConstantMembershipFunction(p_rd.Value());
|
||||
IMembershipFunction *second_fun=val.MembershipFunction();
|
||||
CCompositeMembershipFunction *resultMF=new CCompositeMembershipFunction(compType,first_fun,second_fun);
|
||||
CDictionary_Obj_Obj *p_rf=new CDictionary_Obj_Obj;
|
||||
p_rf.SetAll(rule,resultMF);
|
||||
conclusions.Add(p_rf);
|
||||
}
|
||||
//--- return conclusions
|
||||
return (conclusions);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Aggregate results |
|
||||
//+------------------------------------------------------------------+
|
||||
CList *CMamdaniFuzzySystem::Aggregate(CList *conclusions)
|
||||
{
|
||||
CList *fuzzyResult=new CList;
|
||||
for(int i=0; i<Output().Total(); i++)
|
||||
{
|
||||
CFuzzyVariable *var=Output().GetNodeAtIndex(i);
|
||||
CList *mfList=new CList;
|
||||
for(int j=0; j<conclusions.Total(); j++)
|
||||
{
|
||||
CDictionary_Obj_Obj *p_rf=conclusions.GetNodeAtIndex(j);
|
||||
CMamdaniFuzzyRule *rule=p_rf.Key();
|
||||
if(rule.Conclusion().Var()==var)
|
||||
{
|
||||
mfList.Add(p_rf.Value());
|
||||
}
|
||||
}
|
||||
MfCompositionType composType;
|
||||
switch(m_aggr_method)
|
||||
{
|
||||
case MaxAgg:
|
||||
composType=MaxMF;
|
||||
break;
|
||||
case SumAgg:
|
||||
composType=SumMF;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
Print("Internal exception.");
|
||||
//--- return
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
CDictionary_Obj_Obj *p_vf=new CDictionary_Obj_Obj;
|
||||
CCompositeMembershipFunction *func=new CCompositeMembershipFunction(composType,mfList);
|
||||
p_vf.SetAll(var,func);
|
||||
fuzzyResult.Add(p_vf);
|
||||
}
|
||||
//--- return result
|
||||
return (fuzzyResult);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate crisp result for each rule |
|
||||
//+------------------------------------------------------------------+
|
||||
CList *CMamdaniFuzzySystem::Defuzzify(CList *fuzzyResult)
|
||||
{
|
||||
CList *crispResult=new CList;
|
||||
for(int i=0; i<fuzzyResult.Total(); i++)
|
||||
{
|
||||
CDictionary_Obj_Double *p_vd=new CDictionary_Obj_Double;
|
||||
CDictionary_Obj_Obj *p_vf=fuzzyResult.GetNodeAtIndex(i);
|
||||
CFuzzyVariable *var=p_vf.Key();
|
||||
p_vd.SetAll(var,Defuzzify(p_vf.Value(),var.Min(),var.Max()));
|
||||
crispResult.Add(p_vd);
|
||||
}
|
||||
//--- return result
|
||||
return (crispResult);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Helpers |
|
||||
//+------------------------------------------------------------------+
|
||||
double CMamdaniFuzzySystem::Defuzzify(IMembershipFunction *mf,const double min,const double max)
|
||||
{
|
||||
if(m_defuzz_method==CentroidDef)
|
||||
{
|
||||
int k=50; // The function is divided into "k" steps
|
||||
double step=(max-min)/k; // Calculate the step function
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate a center of gravity as integral |
|
||||
//+------------------------------------------------------------------+
|
||||
double ptLeft=0.0;
|
||||
double ptCenter= 0.0;
|
||||
double ptRight = 0.0;
|
||||
double valLeft=0.0;
|
||||
double valCenter= 0.0;
|
||||
double valRight = 0.0;
|
||||
double val2Left=0.0;
|
||||
double val2Center= 0.0;
|
||||
double val2Right = 0.0;
|
||||
double numerator=0.0;
|
||||
double denominator=0.0;
|
||||
for(int i=0; i<k; i++)
|
||||
{
|
||||
if(i==0)
|
||||
{
|
||||
ptRight=min;
|
||||
valRight=mf.GetValue(ptRight);
|
||||
val2Right=ptRight*valRight;
|
||||
}
|
||||
ptLeft=ptRight;
|
||||
ptCenter= min+step *((double)i+0.5);
|
||||
ptRight = min+step *(i+1);
|
||||
valLeft=valRight;
|
||||
valCenter= mf.GetValue(ptCenter);
|
||||
valRight = mf.GetValue(ptRight);
|
||||
val2Left=val2Right;
|
||||
val2Center= ptCenter * valCenter;
|
||||
val2Right = ptRight * valRight;
|
||||
numerator+=step *(val2Left+4*val2Center+val2Right)/3.0;
|
||||
denominator+=step *(valLeft+4*valCenter+valRight)/3.0;
|
||||
}
|
||||
delete mf;
|
||||
if(denominator!=0)
|
||||
{
|
||||
//--- return result
|
||||
return (numerator / denominator);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- return NAN
|
||||
return (MathLog(-1));
|
||||
}
|
||||
}
|
||||
else
|
||||
if(m_defuzz_method==BisectorDef)
|
||||
{
|
||||
//+-------------------------------------------------------------------------------------+
|
||||
//| The method Bisector consists in finding the point on the abscissa, |
|
||||
//| which divides the area under the curve of the membership function in two equal parts|
|
||||
//+-------------------------------------------------------------------------------------+
|
||||
double Area=0.0; // The area under the function
|
||||
int k=50; // The function is divided into "k" steps
|
||||
double now=min; // The current position
|
||||
for(int i=0; i<k; i++)
|
||||
{
|
||||
Area+=mf.GetValue(now);
|
||||
now=now+(max-min)/k;
|
||||
}
|
||||
now=min;
|
||||
double halfArea=fabs(Area/2-mf.GetValue(min));
|
||||
Area=0.0;
|
||||
while(true)
|
||||
{
|
||||
Area+=mf.GetValue(now);
|
||||
if(Area>=halfArea)
|
||||
{
|
||||
break;
|
||||
}
|
||||
now=now+(max-min)/k;
|
||||
}
|
||||
delete mf;
|
||||
//--- return result
|
||||
return (now);
|
||||
}
|
||||
else
|
||||
if(m_defuzz_method==AverageMaximumDef)
|
||||
{
|
||||
//+------------------------------------------------------------------------------------------+
|
||||
//| AverageMaximum method is the arithmetic mean of all the maxima of the membership function|
|
||||
//+------------------------------------------------------------------------------------------+
|
||||
double sum_max=0; // Sum of local maxima
|
||||
double count_max=0; // Count of local maxima
|
||||
int k=50; // The function is divided into "k" steps
|
||||
double now=min; // The current position
|
||||
double step=(max-min)/k; // Calculate the step function
|
||||
for(int i=1; i<k; i++)
|
||||
{
|
||||
double point_1 = mf.GetValue(now);
|
||||
double point_0 = mf.GetValue(now - step);
|
||||
double point_2 = mf.GetValue(now + step);
|
||||
//--- check the first element
|
||||
if(i==1)
|
||||
{
|
||||
if(mf.GetValue(min)>mf.GetValue(min+step))
|
||||
{
|
||||
sum_max+=mf.GetValue(min);
|
||||
count_max++;
|
||||
}
|
||||
}
|
||||
//--- check the second element
|
||||
if(i==k-1)
|
||||
{
|
||||
if(mf.GetValue(max)>mf.GetValue(max-step))
|
||||
{
|
||||
sum_max+=mf.GetValue(max);
|
||||
count_max++;
|
||||
}
|
||||
}
|
||||
//--- check all the other elements
|
||||
if((point_1>point_0) && (point_1>point_2))
|
||||
{
|
||||
sum_max+=point_1;
|
||||
count_max++;
|
||||
}
|
||||
}
|
||||
if(count_max==0)
|
||||
{
|
||||
delete mf;
|
||||
//--- return result
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete mf;
|
||||
//--- return result
|
||||
return (sum_max/count_max);
|
||||
}
|
||||
}
|
||||
else
|
||||
if(m_defuzz_method==LargestMaximumDef)
|
||||
{
|
||||
CArrayDouble *local_max=new CArrayDouble; // Array of all local maximum
|
||||
double result; // Result of defuzzification method
|
||||
int k=50; // The function is divided into "k" steps
|
||||
double now=min; // The current position
|
||||
double step=(max-min)/k; // Calculate the step function
|
||||
for(int i=1; i<k; i++)
|
||||
{
|
||||
double point_1 = mf.GetValue(now);
|
||||
double point_0 = mf.GetValue(now - step);
|
||||
double point_2 = mf.GetValue(now + step);
|
||||
//--- check the first element
|
||||
if(i==1)
|
||||
{
|
||||
if(mf.GetValue(min)>mf.GetValue(min+step))
|
||||
{
|
||||
local_max.Add(mf.GetValue(min));
|
||||
}
|
||||
}
|
||||
//--- check the second element
|
||||
if(i==k-1)
|
||||
{
|
||||
if(mf.GetValue(max)>mf.GetValue(max-step))
|
||||
{
|
||||
local_max.Add(mf.GetValue(max));
|
||||
}
|
||||
}
|
||||
//--- check all the other elements
|
||||
if((point_1>point_0) && (point_1>point_2))
|
||||
{
|
||||
local_max.Add(point_1);
|
||||
}
|
||||
now+=step;
|
||||
}
|
||||
result=local_max.At(0);
|
||||
for(int i=0; i<local_max.Total(); i++)
|
||||
{
|
||||
if(result<=local_max.At(i))
|
||||
{
|
||||
result=local_max.At(i);
|
||||
}
|
||||
}
|
||||
now=min;
|
||||
while(true)
|
||||
{
|
||||
if(mf.GetValue(now)==result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
now+=step;
|
||||
}
|
||||
delete local_max;
|
||||
delete mf;
|
||||
//--- return result
|
||||
return (now);
|
||||
}
|
||||
else
|
||||
if(m_defuzz_method==SmallestMaximumDef)
|
||||
{
|
||||
CArrayDouble *local_max=new CArrayDouble; // Array of all local maximum
|
||||
double result; // Result of defuzzification method
|
||||
int k=50; // The function is divided into "k" steps
|
||||
double now=min; // The current position
|
||||
double step=(max-min)/k; // Calculate the step function
|
||||
for(int i=1; i<k; i++)
|
||||
{
|
||||
double point_1 = mf.GetValue(now);
|
||||
double point_0 = mf.GetValue(now - step);
|
||||
double point_2 = mf.GetValue(now + step);
|
||||
//--- check the first element
|
||||
if(i==1)
|
||||
{
|
||||
if(mf.GetValue(min)>mf.GetValue(min+step))
|
||||
{
|
||||
local_max.Add(mf.GetValue(min));
|
||||
}
|
||||
}
|
||||
//--- check the second element
|
||||
if(i==k-1)
|
||||
{
|
||||
if(mf.GetValue(max)>mf.GetValue(max-step))
|
||||
{
|
||||
local_max.Add(mf.GetValue(max));
|
||||
}
|
||||
}
|
||||
//--- check all the other elements
|
||||
if((point_1>point_0) && (point_1>point_2))
|
||||
{
|
||||
local_max.Add(point_1);
|
||||
}
|
||||
now+=step;
|
||||
}
|
||||
result=local_max.At(0);
|
||||
for(int i=0; i<local_max.Total(); i++)
|
||||
{
|
||||
if(result>=local_max.At(i))
|
||||
{
|
||||
result=local_max.At(i);
|
||||
}
|
||||
}
|
||||
now=min;
|
||||
while(true)
|
||||
{
|
||||
if(mf.GetValue(now)==result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
now+=step;
|
||||
}
|
||||
delete local_max;
|
||||
delete mf;
|
||||
//--- return result
|
||||
return (now);
|
||||
}
|
||||
else
|
||||
{
|
||||
Print("Internal exception.");
|
||||
delete mf;
|
||||
//--- return
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,327 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| sugenofuzzysystem.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| 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 "GenericFuzzySystem.mqh"
|
||||
#include "InferenceMethod.mqh"
|
||||
#include "RuleParser.mqh"
|
||||
#include "FuzzyRule.mqh"
|
||||
#include "SugenoVariable.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Purpose: Creating Sugeno fuzzy system |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| Sugeno fuzzy inference system |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSugenoFuzzySystem : public CGenericFuzzySystem
|
||||
{
|
||||
private:
|
||||
CList *m_output; // List of Sugeno variable
|
||||
CList *m_rules; // List of Sugeno fuzzy rule
|
||||
|
||||
public:
|
||||
CSugenoFuzzySystem(void);
|
||||
~CSugenoFuzzySystem(void);
|
||||
//--- method gets the output linguistic variables
|
||||
CList* Output(void) { return(m_output); }
|
||||
//--- method gets the fuzzy rule
|
||||
CList* Rules(void) { return(m_rules); }
|
||||
//--- maethod gets the variable by name
|
||||
CSugenoVariable* OutputByName(const string name);
|
||||
//--- method create new linear function
|
||||
CLinearSugenoFunction* CreateSugenoFunction(const string name,CList *coeffs,const double constValue);
|
||||
CLinearSugenoFunction* CreateSugenoFunction(const string name,const double &coeffs[]);
|
||||
//--- method create a new rule
|
||||
CSugenoFuzzyRule* EmptyRule(void);
|
||||
//--- method for calculate result
|
||||
CSugenoFuzzyRule* ParseRule(const string rule);
|
||||
CList* EvaluateConditions(CList *fuzzifiedInput);
|
||||
CList* EvaluateFunctions(CList *inputValues);
|
||||
CList* CombineResult(CList *ruleWeights,CList *functionResults);
|
||||
CList* Calculate(CList *inputValues);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor without parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
CSugenoFuzzySystem::CSugenoFuzzySystem(void)
|
||||
{
|
||||
m_output=new CList;
|
||||
m_rules=new CList;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSugenoFuzzySystem::~CSugenoFuzzySystem(void)
|
||||
{
|
||||
delete m_output;
|
||||
delete m_rules;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get the output variable of the system by name |
|
||||
//+------------------------------------------------------------------+
|
||||
CSugenoVariable *CSugenoFuzzySystem::OutputByName(const string name)
|
||||
{
|
||||
for(int i=0; i<m_output.Total(); i++)
|
||||
{
|
||||
CSugenoVariable *var=m_output.GetNodeAtIndex(i);
|
||||
if(var.Name()==name)
|
||||
{
|
||||
//--- return Sugeno variable
|
||||
return (var);
|
||||
}
|
||||
}
|
||||
Print("Variable with that name is not found");
|
||||
//--- return
|
||||
return (NULL);
|
||||
}
|
||||
//+------------------------------------------------------------------------+
|
||||
//| Use this method to create a linear function for the Sugeno fuzzy system|
|
||||
//+------------------------------------------------------------------------+
|
||||
CLinearSugenoFunction *CSugenoFuzzySystem::CreateSugenoFunction(const string name,CList *coeffs,const double constValue)
|
||||
{
|
||||
//--- return linear Sugeno function
|
||||
return new CLinearSugenoFunction(name, CGenericFuzzySystem::Input(), coeffs, constValue);
|
||||
}
|
||||
//+------------------------------------------------------------------------+
|
||||
//| Use this method to create a linear function for the Sugeno fuzzy system|
|
||||
//+------------------------------------------------------------------------+
|
||||
CLinearSugenoFunction *CSugenoFuzzySystem::CreateSugenoFunction(const string name,const double &coeffs[])
|
||||
{
|
||||
//--- return linear Sugeno function
|
||||
return new CLinearSugenoFunction(name, Input(), coeffs);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Use this method to create an empty rule for the system |
|
||||
//+------------------------------------------------------------------+
|
||||
CSugenoFuzzyRule *CSugenoFuzzySystem::EmptyRule()
|
||||
{
|
||||
//--- return Sugeno fuzzy rule
|
||||
return new CSugenoFuzzyRule();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Use this method to create rule by its textual representation |
|
||||
//+------------------------------------------------------------------+
|
||||
CSugenoFuzzyRule *CSugenoFuzzySystem::ParseRule(const string rule)
|
||||
{
|
||||
//--- return Sugeno fuzzy rule
|
||||
return CRuleParser::Parse(rule, EmptyRule(), Input(), Output());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Evaluate conditions |
|
||||
//+------------------------------------------------------------------+
|
||||
CList *CSugenoFuzzySystem::EvaluateConditions(CList *fuzzifiedInput)
|
||||
{
|
||||
CList *result=new CList;
|
||||
for(int i=0; i<Rules().Total(); i++)
|
||||
{
|
||||
CDictionary_Obj_Double *p_rd=new CDictionary_Obj_Double;
|
||||
CSugenoFuzzyRule *rule=Rules().GetNodeAtIndex(i);
|
||||
p_rd.SetAll(rule,EvaluateCondition(rule.Condition(),fuzzifiedInput));
|
||||
result.Add(p_rd);
|
||||
}
|
||||
//--- return result
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate functions results |
|
||||
//+------------------------------------------------------------------+
|
||||
CList *CSugenoFuzzySystem::EvaluateFunctions(CList *inputValues)
|
||||
{
|
||||
CList *result=new CList;
|
||||
for(int i=0; i<Output().Total(); i++)
|
||||
{
|
||||
CSugenoVariable *var=Output().GetNodeAtIndex(i);
|
||||
CList *varResult=new CList;
|
||||
for(int j=0; j<var.Functions().Total(); j++)
|
||||
{
|
||||
CDictionary_Obj_Double *p_fd=new CDictionary_Obj_Double;
|
||||
CLinearSugenoFunction *func=var.Functions().GetNodeAtIndex(j);
|
||||
p_fd.SetAll(func,func.Evaluate(inputValues));
|
||||
varResult.Add(p_fd);
|
||||
}
|
||||
CDictionary_Obj_Obj *p_vl=new CDictionary_Obj_Obj;
|
||||
p_vl.SetAll(var,varResult);
|
||||
result.Add(p_vl);
|
||||
}
|
||||
//--- return result
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Combine results of functions and rule evaluation |
|
||||
//+------------------------------------------------------------------+
|
||||
CList *CSugenoFuzzySystem::CombineResult(CList *ruleWeights,CList *functionResults)
|
||||
{
|
||||
CList *results=new CList;
|
||||
CList *numerators=new CList;
|
||||
CDictionary_Obj_Double *p_vd1;
|
||||
CList *denominators=new CList;
|
||||
CDictionary_Obj_Double *p_vd2;
|
||||
//--- Calculate numerator and denominator separately for each output
|
||||
for(int i=0; i<Output().Total(); i++)
|
||||
{
|
||||
p_vd1=new CDictionary_Obj_Double;
|
||||
p_vd1.SetAll(Output().GetNodeAtIndex(i),0.0);
|
||||
numerators.Add(p_vd1);
|
||||
p_vd2=new CDictionary_Obj_Double;
|
||||
p_vd2.SetAll(Output().GetNodeAtIndex(i),0.0);
|
||||
denominators.Add(p_vd2);
|
||||
}
|
||||
for(int i=0; i<ruleWeights.Total(); i++)
|
||||
{
|
||||
double z=NULL;
|
||||
double w=NULL;
|
||||
CDictionary_Obj_Double *p_rd=ruleWeights.GetNodeAtIndex(i);
|
||||
CSugenoFuzzyRule *rule=p_rd.Key();
|
||||
CSugenoVariable *var=rule.Conclusion().Var();
|
||||
for(int j=0; j<functionResults.Total(); j++)
|
||||
{
|
||||
CDictionary_Obj_Obj *p_vl=functionResults.GetNodeAtIndex(j);
|
||||
if(p_vl.Key()==var)
|
||||
{
|
||||
CList *list=p_vl.Value();
|
||||
for(int k=0; k<list.Total(); k++)
|
||||
{
|
||||
CDictionary_Obj_Double *p_fd=list.GetNodeAtIndex(k);
|
||||
if(p_fd.Key()==rule.Conclusion().Term())
|
||||
{
|
||||
z=p_fd.Value();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int j=0; j<ruleWeights.Total(); j++)
|
||||
{
|
||||
p_rd=ruleWeights.GetNodeAtIndex(j);
|
||||
if(p_rd.Key()==rule)
|
||||
{
|
||||
w=p_rd.Value();
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int j=0; j<numerators.Total(); j++)
|
||||
{
|
||||
p_vd1=numerators.GetNodeAtIndex(j);
|
||||
double num=p_vd1.Value();
|
||||
if(p_vd1.Key()==rule.Conclusion().Var())
|
||||
{
|
||||
num=num+(z*w);
|
||||
p_vd1.Value(num);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int j=0; j<denominators.Total(); j++)
|
||||
{
|
||||
p_vd2=denominators.GetNodeAtIndex(j);
|
||||
double den=p_vd2.Value();
|
||||
if(p_vd2.Key()==rule.Conclusion().Var())
|
||||
{
|
||||
den=den+w;
|
||||
p_vd2.Value(den);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- Calculate the fractions
|
||||
for(int i=0; i<Output().Total(); i++)
|
||||
{
|
||||
CSugenoVariable *var=Output().GetNodeAtIndex(i);
|
||||
CDictionary_Obj_Double *p_vd_res=new CDictionary_Obj_Double;
|
||||
CDictionary_Obj_Double *p_vd_num;
|
||||
CDictionary_Obj_Double *p_vd_den;
|
||||
for(int j=0; j<numerators.Total(); j++)
|
||||
{
|
||||
p_vd_num=numerators.GetNodeAtIndex(j);
|
||||
if(p_vd_num.Key()==var)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int j=0; j<denominators.Total(); j++)
|
||||
{
|
||||
p_vd_den=denominators.GetNodeAtIndex(j);
|
||||
if(p_vd_den.Key()==var)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(p_vd_den.Value()==0.0)
|
||||
{
|
||||
p_vd_res.Value(0.0);
|
||||
results.Add(p_vd_res);
|
||||
}
|
||||
else
|
||||
{
|
||||
p_vd_res.Value(p_vd_num.Value()/p_vd_den.Value());
|
||||
results.Add(p_vd_res);
|
||||
}
|
||||
}
|
||||
//--- return result
|
||||
delete numerators;
|
||||
delete denominators;
|
||||
return (results);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate output of fuzzy system |
|
||||
//+------------------------------------------------------------------+
|
||||
CList *CSugenoFuzzySystem::Calculate(CList *inputValues)
|
||||
{
|
||||
//--- There should be one rule as minimum
|
||||
if(m_rules.Total()==0)
|
||||
{
|
||||
Print("There should be one rule as minimum.");
|
||||
//--- return
|
||||
return (NULL);
|
||||
}
|
||||
//--- Fuzzification step
|
||||
CList *fuzzifiedInput=Fuzzify(inputValues);
|
||||
//--- Evaluate the conditions
|
||||
CList *ruleWeights=EvaluateConditions(fuzzifiedInput);
|
||||
//--- Functions evaluation
|
||||
CList *functionsResult=EvaluateFunctions(inputValues);
|
||||
//--- Combine output
|
||||
CList *result=CombineResult(ruleWeights,functionsResult);
|
||||
//---
|
||||
for(int i=0; i<functionsResult.Total(); i++)
|
||||
{
|
||||
CDictionary_Obj_Obj *pair=functionsResult.GetNodeAtIndex(i);
|
||||
delete pair.Value();
|
||||
}
|
||||
delete functionsResult;
|
||||
delete ruleWeights;
|
||||
for(int i=0; i<fuzzifiedInput.Total(); i++)
|
||||
{
|
||||
CDictionary_Obj_Obj *pair=fuzzifiedInput.GetNodeAtIndex(i);
|
||||
delete pair.Value();
|
||||
}
|
||||
delete fuzzifiedInput;
|
||||
//--- return result
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,254 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| sugenovariable.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| 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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Reference in New Issue
Block a user