//+------------------------------------------------------------------+ //| mandanifuzzysystem.mqh | //| Copyright 2000-2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ //| Implementation of Fuzzy library in MetaQuotes Language 5 | //| | //| The features of the library include: | //| - Create Mamdani fuzzy model | //| - Create Sugeno fuzzy model | //| - Normal membership function | //| - Triangular membership function | //| - Trapezoidal membership function | //| - Constant membership function | //| - Defuzzification method of center of gravity (COG) | //| - Defuzzification method of bisector of area (BOA) | //| - Defuzzification method of mean of maxima (MeOM) | //| | //| This file is free software; you can redistribute it and/or | //| modify it under the terms of the GNU General Public License as | //| published by the Free Software Foundation (www.fsf.org); either | //| version 2 of the License, or (at your option) any later version. | //| | //| This program is distributed in the hope that it will be useful, | //| but WITHOUT ANY WARRANTY; without even the implied warranty of | //| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | //| GNU General Public License for more details. | //+------------------------------------------------------------------+ #include #include #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=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; imf.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; imf.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; imf.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.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); } } //+------------------------------------------------------------------+