diff options
author | Johannes 'josch' Schauer <josch@debian.org> | 2019-01-27 13:56:24 +0100 |
---|---|---|
committer | Johannes 'josch' Schauer <josch@debian.org> | 2019-01-27 13:56:33 +0100 |
commit | 6ce553563bc795f389f639a3a8cdfe356de71441 (patch) | |
tree | da4c9ede3087ca534d93bc1ac5a14f044f036600 /fuzzylite/src/defuzzifier | |
parent | bbefa170378553e5a6e0d72e4d52328b61f3e8ac (diff) |
new upstream version 6.0
Diffstat (limited to 'fuzzylite/src/defuzzifier')
-rw-r--r-- | fuzzylite/src/defuzzifier/Bisector.cpp | 59 | ||||
-rw-r--r-- | fuzzylite/src/defuzzifier/Centroid.cpp | 66 | ||||
-rw-r--r-- | fuzzylite/src/defuzzifier/IntegralDefuzzifier.cpp | 31 | ||||
-rw-r--r-- | fuzzylite/src/defuzzifier/LargestOfMaximum.cpp | 48 | ||||
-rw-r--r-- | fuzzylite/src/defuzzifier/MeanOfMaximum.cpp | 53 | ||||
-rw-r--r-- | fuzzylite/src/defuzzifier/SmallestOfMaximum.cpp | 50 | ||||
-rw-r--r-- | fuzzylite/src/defuzzifier/WeightedAverage.cpp | 119 | ||||
-rw-r--r-- | fuzzylite/src/defuzzifier/WeightedAverageCustom.cpp | 117 | ||||
-rw-r--r-- | fuzzylite/src/defuzzifier/WeightedDefuzzifier.cpp | 130 | ||||
-rw-r--r-- | fuzzylite/src/defuzzifier/WeightedSum.cpp | 116 | ||||
-rw-r--r-- | fuzzylite/src/defuzzifier/WeightedSumCustom.cpp | 112 |
11 files changed, 455 insertions, 446 deletions
diff --git a/fuzzylite/src/defuzzifier/Bisector.cpp b/fuzzylite/src/defuzzifier/Bisector.cpp index ee4d2fc..ed61b6f 100644 --- a/fuzzylite/src/defuzzifier/Bisector.cpp +++ b/fuzzylite/src/defuzzifier/Bisector.cpp @@ -1,76 +1,60 @@ /* - Author: Juan Rada-Vilela, Ph.D. - Copyright (C) 2010-2014 FuzzyLite Limited - All rights reserved + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. + the terms of the FuzzyLite License included with the software. - fuzzylite 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 Lesser General Public License - for more details. - - You should have received a copy of the GNU Lesser General Public License - along with fuzzylite. If not, see <http://www.gnu.org/licenses/>. - - fuzzylite™ is a trademark of FuzzyLite Limited. + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + fuzzylite is a registered trademark of FuzzyLite Limited. */ #include "fl/defuzzifier/Bisector.h" -#include "fl/term/Accumulated.h" #include "fl/term/Term.h" namespace fl { Bisector::Bisector(int resolution) - : IntegralDefuzzifier(resolution) { - } + : IntegralDefuzzifier(resolution) { } - Bisector::~Bisector() { - - } + Bisector::~Bisector() { } std::string Bisector::className() const { return "Bisector"; } + Complexity Bisector::complexity(const Term* term) const { + return Complexity().comparison(1).arithmetic(1 + 2 + 5) + + term->complexity().comparison(1).arithmetic(1 + 5).multiply(getResolution()); + } + scalar Bisector::defuzzify(const Term* term, scalar minimum, scalar maximum) const { - if (not fl::Op::isFinite(minimum + maximum)) { - return fl::nan; - } - if (maximum - minimum > _resolution) { - FL_DBG("[accuracy warning] the resolution <" << _resolution << "> " - "is smaller than the range <" << minimum << ", " << maximum << ">. In order to " - "improve the accuracy, the resolution should be at least equal to the range."); - } - scalar dx = (maximum - minimum) / _resolution; + if (not Op::isFinite(minimum + maximum)) return fl::nan; - int counter = _resolution; + const scalar dx = (maximum - minimum) / getResolution(); + int counter = getResolution(); int left = 0, right = 0; scalar leftArea = 0, rightArea = 0; scalar xLeft = minimum, xRight = maximum; while (counter-- > 0) { - if (fl::Op::isLE(leftArea, rightArea)) { + if (Op::isLE(leftArea, rightArea)) { xLeft = minimum + (left + 0.5) * dx; leftArea += term->membership(xLeft); - left++; + ++left; } else { xRight = maximum - (right + 0.5) * dx; rightArea += term->membership(xRight); - right++; + ++right; } } - //Inverse weighted average to compensate - scalar bisector = (leftArea * xRight + rightArea * xLeft) / (leftArea + rightArea); - return bisector; + return (leftArea * xRight + rightArea * xLeft) / (leftArea + rightArea); } Bisector* Bisector::clone() const { @@ -81,5 +65,4 @@ namespace fl { return new Bisector; } - } diff --git a/fuzzylite/src/defuzzifier/Centroid.cpp b/fuzzylite/src/defuzzifier/Centroid.cpp index 01490d3..177da26 100644 --- a/fuzzylite/src/defuzzifier/Centroid.cpp +++ b/fuzzylite/src/defuzzifier/Centroid.cpp @@ -1,71 +1,60 @@ /* - Author: Juan Rada-Vilela, Ph.D. - Copyright (C) 2010-2014 FuzzyLite Limited - All rights reserved + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. + the terms of the FuzzyLite License included with the software. - fuzzylite 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 Lesser General Public License - for more details. - - You should have received a copy of the GNU Lesser General Public License - along with fuzzylite. If not, see <http://www.gnu.org/licenses/>. - - fuzzylite™ is a trademark of FuzzyLite Limited. + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + fuzzylite is a registered trademark of FuzzyLite Limited. */ #include "fl/defuzzifier/Centroid.h" -#include "fl/term/Accumulated.h" #include "fl/term/Term.h" - namespace fl { Centroid::Centroid(int resolution) - : IntegralDefuzzifier(resolution) { - } - - Centroid::~Centroid() { + : IntegralDefuzzifier(resolution) { } - } + Centroid::~Centroid() { } std::string Centroid::className() const { return "Centroid"; } + Complexity Centroid::complexity(const Term* term) const { + return Complexity().comparison(1).arithmetic(1 + 2 + 1) + + term->complexity().arithmetic(6).multiply(getResolution()); + } + scalar Centroid::defuzzify(const Term* term, scalar minimum, scalar maximum) const { - if (not fl::Op::isFinite(minimum + maximum)) { - return fl::nan; - } - if (maximum - minimum > _resolution) { - FL_DBG("[accuracy warning] the resolution <" << _resolution << "> " - "is smaller than the range <" << minimum << ", " << maximum << ">. In order to " - "improve the accuracy, the resolution should be at least equal to the range."); - } - scalar dx = (maximum - minimum) / _resolution; + if (not Op::isFinite(minimum + maximum)) return fl::nan; + + const int resolution = getResolution(); + const scalar dx = (maximum - minimum) / resolution; scalar x, y; - scalar area = 0, xcentroid = 0, ycentroid = 0; - for (int i = 0; i < _resolution; ++i) { + scalar area = 0, xcentroid = 0; + //scalar ycentroid = 0; + for (int i = 0; i < resolution; ++i) { x = minimum + (i + 0.5) * dx; y = term->membership(x); xcentroid += y * x; - ycentroid += y * y; + //ycentroid += y * y; area += y; } - xcentroid /= area; - ycentroid /= 2 * area; - area *= dx; //total area... unused, but for future reference. - return xcentroid; + //Final results not computed for efficiency + //xcentroid /= area; + //ycentroid /= 2 * area; + //area *= dx; + return xcentroid / area; } Centroid* Centroid::clone() const { @@ -76,5 +65,4 @@ namespace fl { return new Centroid; } - } diff --git a/fuzzylite/src/defuzzifier/IntegralDefuzzifier.cpp b/fuzzylite/src/defuzzifier/IntegralDefuzzifier.cpp index 2badf14..3b06b42 100644 --- a/fuzzylite/src/defuzzifier/IntegralDefuzzifier.cpp +++ b/fuzzylite/src/defuzzifier/IntegralDefuzzifier.cpp @@ -1,32 +1,24 @@ /* - Author: Juan Rada-Vilela, Ph.D. - Copyright (C) 2010-2014 FuzzyLite Limited - All rights reserved + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. + the terms of the FuzzyLite License included with the software. - fuzzylite 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 Lesser General Public License - for more details. - - You should have received a copy of the GNU Lesser General Public License - along with fuzzylite. If not, see <http://www.gnu.org/licenses/>. - - fuzzylite™ is a trademark of FuzzyLite Limited. + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + fuzzylite is a registered trademark of FuzzyLite Limited. */ #include "fl/defuzzifier/IntegralDefuzzifier.h" namespace fl { - int IntegralDefuzzifier::_defaultResolution = 200; + int IntegralDefuzzifier::_defaultResolution = 100; void IntegralDefuzzifier::setDefaultResolution(int defaultResolution) { _defaultResolution = defaultResolution; @@ -37,11 +29,9 @@ namespace fl { } IntegralDefuzzifier::IntegralDefuzzifier(int resolution) - : Defuzzifier(), _resolution(resolution) { - } + : Defuzzifier(), _resolution(resolution) { } - IntegralDefuzzifier::~IntegralDefuzzifier() { - } + IntegralDefuzzifier::~IntegralDefuzzifier() { } void IntegralDefuzzifier::setResolution(int resolution) { this->_resolution = resolution; @@ -50,4 +40,5 @@ namespace fl { int IntegralDefuzzifier::getResolution() const { return this->_resolution; } + } diff --git a/fuzzylite/src/defuzzifier/LargestOfMaximum.cpp b/fuzzylite/src/defuzzifier/LargestOfMaximum.cpp index 470af52..ff05707 100644 --- a/fuzzylite/src/defuzzifier/LargestOfMaximum.cpp +++ b/fuzzylite/src/defuzzifier/LargestOfMaximum.cpp @@ -1,25 +1,17 @@ /* - Author: Juan Rada-Vilela, Ph.D. - Copyright (C) 2010-2014 FuzzyLite Limited - All rights reserved + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. + the terms of the FuzzyLite License included with the software. - fuzzylite 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 Lesser General Public License - for more details. - - You should have received a copy of the GNU Lesser General Public License - along with fuzzylite. If not, see <http://www.gnu.org/licenses/>. - - fuzzylite™ is a trademark of FuzzyLite Limited. + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + fuzzylite is a registered trademark of FuzzyLite Limited. */ #include "fl/defuzzifier/LargestOfMaximum.h" @@ -30,29 +22,27 @@ namespace fl { LargestOfMaximum::LargestOfMaximum(int resolution) - : IntegralDefuzzifier(resolution) { - } + : IntegralDefuzzifier(resolution) { } - LargestOfMaximum::~LargestOfMaximum() { - } + LargestOfMaximum::~LargestOfMaximum() { } std::string LargestOfMaximum::className() const { return "LargestOfMaximum"; } + Complexity LargestOfMaximum::complexity(const Term* term) const { + return Complexity().comparison(1).arithmetic(1 + 2) + + term->complexity().comparison(1).arithmetic(3).multiply(getResolution()); + } + scalar LargestOfMaximum::defuzzify(const Term* term, scalar minimum, scalar maximum) const { - if (not fl::Op::isFinite(minimum + maximum)) { - return fl::nan; - } - if (maximum - minimum > _resolution) { - FL_DBG("[accuracy warning] the resolution <" << _resolution << "> " - "is smaller than the range <" << minimum << ", " << maximum << ">. In order to " - "improve the accuracy, the resolution should be at least equal to the range."); - } - scalar dx = (maximum - minimum) / _resolution; + if (not Op::isFinite(minimum + maximum)) return fl::nan; + + const int resolution = getResolution(); + const scalar dx = (maximum - minimum) / resolution; scalar x, y; scalar ymax = -1.0, xlargest = maximum; - for (int i = 0; i < _resolution; ++i) { + for (int i = 0; i < resolution; ++i) { x = minimum + (i + 0.5) * dx; y = term->membership(x); diff --git a/fuzzylite/src/defuzzifier/MeanOfMaximum.cpp b/fuzzylite/src/defuzzifier/MeanOfMaximum.cpp index 7c40527..961e505 100644 --- a/fuzzylite/src/defuzzifier/MeanOfMaximum.cpp +++ b/fuzzylite/src/defuzzifier/MeanOfMaximum.cpp @@ -1,25 +1,17 @@ /* - Author: Juan Rada-Vilela, Ph.D. - Copyright (C) 2010-2014 FuzzyLite Limited - All rights reserved + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. + the terms of the FuzzyLite License included with the software. - fuzzylite 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 Lesser General Public License - for more details. - - You should have received a copy of the GNU Lesser General Public License - along with fuzzylite. If not, see <http://www.gnu.org/licenses/>. - - fuzzylite™ is a trademark of FuzzyLite Limited. + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + fuzzylite is a registered trademark of FuzzyLite Limited. */ #include "fl/defuzzifier/MeanOfMaximum.h" @@ -27,36 +19,33 @@ #include "fl/Exception.h" #include "fl/term/Term.h" - namespace fl { MeanOfMaximum::MeanOfMaximum(int resolution) - : IntegralDefuzzifier(resolution) { - } + : IntegralDefuzzifier(resolution) { } - MeanOfMaximum::~MeanOfMaximum() { - } + MeanOfMaximum::~MeanOfMaximum() { } std::string MeanOfMaximum::className() const { return "MeanOfMaximum"; } + Complexity MeanOfMaximum::complexity(const Term* term) const { + return Complexity().comparison(1).arithmetic(1 + 2 + 2) + + term->complexity().comparison(4).arithmetic(3).multiply(getResolution()); + } + scalar MeanOfMaximum::defuzzify(const Term* term, scalar minimum, scalar maximum) const { - if (not fl::Op::isFinite(minimum + maximum)) { - return fl::nan; - } - if (maximum - minimum > _resolution) { - FL_DBG("[accuracy warning] the resolution <" << _resolution << "> " - "is smaller than the range <" << minimum << ", " << maximum << ">. In order to " - "improve the accuracy, the resolution should be at least equal to the range."); - } - scalar dx = (maximum - minimum) / _resolution; + if (not Op::isFinite(minimum + maximum)) return fl::nan; + + const int resolution = getResolution(); + const scalar dx = (maximum - minimum) / resolution; scalar x, y; scalar ymax = -1.0; scalar xsmallest = minimum; scalar xlargest = maximum; bool samePlateau = false; - for (int i = 0; i < _resolution; ++i) { + for (int i = 0; i < resolution; ++i) { x = minimum + (i + 0.5) * dx; y = term->membership(x); @@ -67,14 +56,14 @@ namespace fl { xlargest = x; samePlateau = true; - } else if (Op::isEq(y, ymax) and samePlateau) { + } else if (samePlateau and Op::isEq(y, ymax)) { xlargest = x; } else if (Op::isLt(y, ymax)) { samePlateau = false; } } - return (xlargest + xsmallest) / 2.0; + return 0.5 * (xlargest + xsmallest); } MeanOfMaximum* MeanOfMaximum::clone() const { diff --git a/fuzzylite/src/defuzzifier/SmallestOfMaximum.cpp b/fuzzylite/src/defuzzifier/SmallestOfMaximum.cpp index 1e67395..7333702 100644 --- a/fuzzylite/src/defuzzifier/SmallestOfMaximum.cpp +++ b/fuzzylite/src/defuzzifier/SmallestOfMaximum.cpp @@ -1,25 +1,17 @@ /* - Author: Juan Rada-Vilela, Ph.D. - Copyright (C) 2010-2014 FuzzyLite Limited - All rights reserved + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. + the terms of the FuzzyLite License included with the software. - fuzzylite 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 Lesser General Public License - for more details. - - You should have received a copy of the GNU Lesser General Public License - along with fuzzylite. If not, see <http://www.gnu.org/licenses/>. - - fuzzylite™ is a trademark of FuzzyLite Limited. + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + fuzzylite is a registered trademark of FuzzyLite Limited. */ #include "fl/defuzzifier/SmallestOfMaximum.h" @@ -27,33 +19,30 @@ #include "fl/Exception.h" #include "fl/term/Term.h" - namespace fl { SmallestOfMaximum::SmallestOfMaximum(int resolution) - : IntegralDefuzzifier(resolution) { - } + : IntegralDefuzzifier(resolution) { } - SmallestOfMaximum::~SmallestOfMaximum() { - } + SmallestOfMaximum::~SmallestOfMaximum() { } std::string SmallestOfMaximum::className() const { return "SmallestOfMaximum"; } + Complexity SmallestOfMaximum::complexity(const Term* term) const { + return Complexity().comparison(1).arithmetic(1 + 2) + + term->complexity().comparison(1).arithmetic(3).multiply(getResolution()); + } + scalar SmallestOfMaximum::defuzzify(const Term* term, scalar minimum, scalar maximum) const { - if (not fl::Op::isFinite(minimum + maximum)) { - return fl::nan; - } - if (maximum - minimum > _resolution) { - FL_DBG("[accuracy warning] the resolution <" << _resolution << "> " - "is smaller than the range <" << minimum << ", " << maximum << ">. In order to " - "improve the accuracy, the resolution should be at least equal to the range."); - } - scalar dx = (maximum - minimum) / _resolution; + if (not Op::isFinite(minimum + maximum)) return fl::nan; + + const int resolution = getResolution(); + const scalar dx = (maximum - minimum) / resolution; scalar x, y; scalar ymax = -1.0, xsmallest = minimum; - for (int i = 0; i < _resolution; ++i) { + for (int i = 0; i < resolution; ++i) { x = minimum + (i + 0.5) * dx; y = term->membership(x); @@ -74,4 +63,3 @@ namespace fl { } } - diff --git a/fuzzylite/src/defuzzifier/WeightedAverage.cpp b/fuzzylite/src/defuzzifier/WeightedAverage.cpp index 105c9d4..34af8c9 100644 --- a/fuzzylite/src/defuzzifier/WeightedAverage.cpp +++ b/fuzzylite/src/defuzzifier/WeightedAverage.cpp @@ -1,113 +1,89 @@ /* - Author: Juan Rada-Vilela, Ph.D. - Copyright (C) 2010-2014 FuzzyLite Limited - All rights reserved + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. + the terms of the FuzzyLite License included with the software. - fuzzylite 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 Lesser General Public License - for more details. - - You should have received a copy of the GNU Lesser General Public License - along with fuzzylite. If not, see <http://www.gnu.org/licenses/>. - - fuzzylite™ is a trademark of FuzzyLite Limited. + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + fuzzylite is a registered trademark of FuzzyLite Limited. */ #include "fl/defuzzifier/WeightedAverage.h" -#include "fl/term/Accumulated.h" -#include "fl/term/Activated.h" -#include "fl/norm/Norm.h" -#include "fl/norm/SNorm.h" -#include "fl/norm/TNorm.h" +#include "fl/term/Aggregated.h" #include <map> namespace fl { - WeightedAverage::WeightedAverage(Type type) : WeightedDefuzzifier(type) { - } + WeightedAverage::WeightedAverage(Type type) : WeightedDefuzzifier(type) { } - WeightedAverage::WeightedAverage(const std::string& type) : WeightedDefuzzifier(type) { - } + WeightedAverage::WeightedAverage(const std::string& type) : WeightedDefuzzifier(type) { } - WeightedAverage::~WeightedAverage() { - } + WeightedAverage::~WeightedAverage() { } std::string WeightedAverage::className() const { return "WeightedAverage"; } + Complexity WeightedAverage::complexity(const Term* term) const { + Complexity result; + result.comparison(4).function(1); //for dynamic_cast + const Aggregated* fuzzyOutput = dynamic_cast<const Aggregated*> (term); + if (fuzzyOutput) { + result += term->complexity().arithmetic(3).multiply(scalar(fuzzyOutput->numberOfTerms())); + } + return result; + } + scalar WeightedAverage::defuzzify(const Term* term, scalar minimum, scalar maximum) const { - const Accumulated* fuzzyOutput = dynamic_cast<const Accumulated*> (term); + const Aggregated* fuzzyOutput = dynamic_cast<const Aggregated*> (term); if (not fuzzyOutput) { std::ostringstream ss; ss << "[defuzzification error]" - << "expected an Accumulated term instead of" - << "<" << term->toString() << ">"; - throw fl::Exception(ss.str(), FL_AT); + << "expected an Aggregated term instead of" + << "<" << (term ? term->toString() : "null") << ">"; + throw Exception(ss.str(), FL_AT); } + if (fuzzyOutput->isEmpty()) return fl::nan; + minimum = fuzzyOutput->getMinimum(); maximum = fuzzyOutput->getMaximum(); + Type type = getType(); + if (type == Automatic) { + type = inferType(&(fuzzyOutput->terms().front())); + } + scalar sum = 0.0; scalar weights = 0.0; - - if (not fuzzyOutput->getAccumulation()) { - Type type = _type; - for (int i = 0; i < fuzzyOutput->numberOfTerms(); ++i) { - Activated* activated = fuzzyOutput->getTerm(i); - scalar w = activated->getDegree(); - - if (type == Automatic) type = inferType(activated->getTerm()); - - scalar z = (type == TakagiSugeno) - //? activated.getTerm()->membership(fl::nan) Would ensure no Tsukamoto applies, but Inverse Tsukamoto with Functions would not work. - ? activated->getTerm()->membership(w) //Provides Takagi-Sugeno and Inverse Tsukamoto of Functions - : tsukamoto(activated->getTerm(), w, minimum, maximum); - + const std::size_t numberOfTerms = fuzzyOutput->numberOfTerms(); + if (type == TakagiSugeno) { + //Provides Takagi-Sugeno and Inverse Tsukamoto of Functions + scalar w, z; + for (std::size_t i = 0; i < numberOfTerms; ++i) { + const Activated& activated = fuzzyOutput->getTerm(i); + w = activated.getDegree(); + z = activated.getTerm()->membership(w); sum += w * z; weights += w; } } else { - typedef std::map<const Term*, std::vector<Activated*> > TermGroup; - TermGroup groups; - for (int i = 0; i < fuzzyOutput->numberOfTerms(); ++i) { - Activated* value = fuzzyOutput->getTerm(i); - const Term* key = value->getTerm(); - groups[key].push_back(value); - } - TermGroup::const_iterator it = groups.begin(); - Type type = _type; - while (it != groups.end()) { - const Term* activatedTerm = it->first; - scalar accumulatedDegree = 0.0; - for (std::size_t i = 0; i < it->second.size(); ++i) - accumulatedDegree = fuzzyOutput->getAccumulation()->compute( - accumulatedDegree, it->second.at(i)->getDegree()); - - if (type == Automatic) type = inferType(activatedTerm); - - scalar z = (type == TakagiSugeno) - //? activated.getTerm()->membership(fl::nan) Would ensure no Tsukamoto applies, but Inverse Tsukamoto with Functions would not work. - ? activatedTerm->membership(accumulatedDegree) //Provides Takagi-Sugeno and Inverse Tsukamoto of Functions - : tsukamoto(activatedTerm, accumulatedDegree, minimum, maximum); - - sum += accumulatedDegree * z; - weights += accumulatedDegree; - - ++it; + scalar w, z; + for (std::size_t i = 0; i < numberOfTerms; ++i) { + const Activated& activated = fuzzyOutput->getTerm(i); + w = activated.getDegree(); + z = activated.getTerm()->tsukamoto(w, minimum, maximum); + sum += w * z; + weights += w; } } return sum / weights; @@ -120,4 +96,5 @@ namespace fl { Defuzzifier* WeightedAverage::constructor() { return new WeightedAverage; } + } diff --git a/fuzzylite/src/defuzzifier/WeightedAverageCustom.cpp b/fuzzylite/src/defuzzifier/WeightedAverageCustom.cpp new file mode 100644 index 0000000..0beb722 --- /dev/null +++ b/fuzzylite/src/defuzzifier/WeightedAverageCustom.cpp @@ -0,0 +1,117 @@ +/* + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> + + This file is part of fuzzylite. + + fuzzylite is free software: you can redistribute it and/or modify it under + the terms of the FuzzyLite License included with the software. + + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + + fuzzylite is a registered trademark of FuzzyLite Limited. + */ + +#include "fl/defuzzifier/WeightedAverageCustom.h" + +#include "fl/term/Aggregated.h" + +#include <map> + +namespace fl { + + WeightedAverageCustom::WeightedAverageCustom(Type type) : WeightedDefuzzifier(type) { } + + WeightedAverageCustom::WeightedAverageCustom(const std::string& type) : WeightedDefuzzifier(type) { } + + WeightedAverageCustom::~WeightedAverageCustom() { } + + std::string WeightedAverageCustom::className() const { + return "WeightedAverageCustom"; + } + + Complexity WeightedAverageCustom::complexity(const Term* term) const { + Complexity result; + result.comparison(3).arithmetic(1).function(1); + const Aggregated* fuzzyOutput = dynamic_cast<const Aggregated*> (term); + if (fuzzyOutput) { + result += term->complexity().arithmetic(3).comparison(2) + .multiply(scalar(fuzzyOutput->numberOfTerms())); + } + return result; + } + + scalar WeightedAverageCustom::defuzzify(const Term* term, + scalar minimum, scalar maximum) const { + const Aggregated* fuzzyOutput = dynamic_cast<const Aggregated*> (term); + if (not fuzzyOutput) { + std::ostringstream ss; + ss << "[defuzzification error]" + << "expected an Aggregated term instead of" + << "<" << (term ? term->toString() : "null") << ">"; + throw Exception(ss.str(), FL_AT); + } + + if (fuzzyOutput->isEmpty()) return fl::nan; + + minimum = fuzzyOutput->getMinimum(); + maximum = fuzzyOutput->getMaximum(); + + SNorm* aggregation = fuzzyOutput->getAggregation(); + + Type type = getType(); + if (type == Automatic) { + type = inferType(&(fuzzyOutput->terms().front())); + } + + scalar sum = 0.0; + scalar weights = 0.0; + const std::size_t numberOfTerms = fuzzyOutput->numberOfTerms(); + if (type == TakagiSugeno) { + //Provides Takagi-Sugeno and Inverse Tsukamoto of Functions + scalar w, z, wz; + for (std::size_t i = 0; i < numberOfTerms; ++i) { + const Activated& activated = fuzzyOutput->getTerm(i); + w = activated.getDegree(); + z = activated.getTerm()->membership(w); + const TNorm* implication = activated.getImplication(); + wz = implication ? implication->compute(w, z) : (w * z); + if (aggregation) { + sum = aggregation->compute(sum, wz); + weights = aggregation->compute(weights, w); + } else { + sum += wz; + weights += w; + } + } + } else { + scalar w, z, wz; + for (std::size_t i = 0; i < numberOfTerms; ++i) { + const Activated& activated = fuzzyOutput->getTerm(i); + w = activated.getDegree(); + z = activated.getTerm()->tsukamoto(w, minimum, maximum); + const TNorm* implication = activated.getImplication(); + wz = implication ? implication->compute(w, z) : (w * z); + if (aggregation) { + sum = aggregation->compute(sum, wz); + weights = aggregation->compute(weights, w); + } else { + sum += wz; + weights += w; + } + } + } + return sum / weights; + } + + WeightedAverageCustom* WeightedAverageCustom::clone() const { + return new WeightedAverageCustom(*this); + } + + Defuzzifier* WeightedAverageCustom::constructor() { + return new WeightedAverageCustom; + } + +} diff --git a/fuzzylite/src/defuzzifier/WeightedDefuzzifier.cpp b/fuzzylite/src/defuzzifier/WeightedDefuzzifier.cpp index 760a5dc..743c59f 100644 --- a/fuzzylite/src/defuzzifier/WeightedDefuzzifier.cpp +++ b/fuzzylite/src/defuzzifier/WeightedDefuzzifier.cpp @@ -1,25 +1,17 @@ /* - Author: Juan Rada-Vilela, Ph.D. - Copyright (C) 2010-2014 FuzzyLite Limited - All rights reserved + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. + the terms of the FuzzyLite License included with the software. - fuzzylite 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 Lesser General Public License - for more details. - - You should have received a copy of the GNU Lesser General Public License - along with fuzzylite. If not, see <http://www.gnu.org/licenses/>. - - fuzzylite™ is a trademark of FuzzyLite Limited. + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + fuzzylite is a registered trademark of FuzzyLite Limited. */ #include "fl/defuzzifier/WeightedDefuzzifier.h" @@ -36,24 +28,20 @@ namespace fl { - WeightedDefuzzifier::WeightedDefuzzifier(Type type) : _type(type) { - - } + WeightedDefuzzifier::WeightedDefuzzifier(Type type) : _type(type) { } WeightedDefuzzifier::WeightedDefuzzifier(const std::string& type) { - if (type == "Automatic") _type = Automatic; - else if (type == "TakagiSugeno") _type = TakagiSugeno; - else if (type == "Tsukamoto") _type = Tsukamoto; + if (type == "Automatic") setType(Automatic); + else if (type == "TakagiSugeno") setType(TakagiSugeno); + else if (type == "Tsukamoto") setType(Tsukamoto); else { - _type = Automatic; + setType(Automatic); FL_LOG("[warning] incorrect type <" + type + "> of WeightedDefuzzifier" + " has been defaulted to <Automatic>"); } } - WeightedDefuzzifier::~WeightedDefuzzifier() { - - } + WeightedDefuzzifier::~WeightedDefuzzifier() { } std::string WeightedDefuzzifier::typeName(Type type) { switch (type) { @@ -73,7 +61,7 @@ namespace fl { } std::string WeightedDefuzzifier::getTypeName() const { - return typeName(this->_type); + return typeName(getType()); } WeightedDefuzzifier::Type WeightedDefuzzifier::inferType(const Term* term) const { @@ -85,94 +73,4 @@ namespace fl { return Tsukamoto; } - bool WeightedDefuzzifier::isMonotonic(const Term* term) const { - return (dynamic_cast<const Concave*> (term)) or - (dynamic_cast<const Ramp*> (term)) or - (dynamic_cast<const Sigmoid*> (term)) or - (dynamic_cast<const SShape*> (term)) or - (dynamic_cast<const ZShape*> (term)); - } - - /** - * Instead of computing y=f(x), the goal of Tsukamoto is to find x=f(w), - * where f is monotonic. - */ - scalar WeightedDefuzzifier::tsukamoto(const Term* monotonic, scalar activationDegree, - scalar minimum, scalar maximum) const { - scalar w = activationDegree; - scalar z = fl::nan; //result; - bool isTsukamoto = true; - if (const Ramp* ramp = dynamic_cast<const Ramp*> (monotonic)) { - z = Op::scale(w, 0, 1, ramp->getStart(), ramp->getEnd()); - - } else if (const Sigmoid* sigmoid = dynamic_cast<const Sigmoid*> (monotonic)) { - if (Op::isEq(w, 1.0)) { - if (Op::isGE(sigmoid->getSlope(), 0.0)) { - z = maximum; - } else { - z = minimum; - } - - } else if (Op::isEq(w, 0.0)) { - if (Op::isGE(sigmoid->getSlope(), 0.0)) { - z = minimum; - } else { - z = maximum; - } - } else { - scalar a = sigmoid->getSlope(); - scalar b = sigmoid->getInflection(); - z = b + (std::log(1.0 / w - 1.0) / -a); - } - - } else if (const SShape* sshape = dynamic_cast<const SShape*> (monotonic)) { - scalar difference = sshape->getEnd() - sshape->getStart(); - scalar a = sshape->getStart() + std::sqrt(w * difference * difference / 2.0); - scalar b = sshape->getEnd() + std::sqrt(difference * difference * (w - 1.0) / -2.0); - if (std::fabs(w - monotonic->membership(a)) < - std::fabs(w - monotonic->membership(b))) { - z = a; - } else { - z = b; - } - - } else if (const ZShape* zshape = dynamic_cast<const ZShape*> (monotonic)) { - scalar difference = zshape->getEnd() - zshape->getStart(); - scalar a = zshape->getStart() + std::sqrt(difference * difference * (w - 1.0) / -2.0); - scalar b = zshape->getEnd() + std::sqrt(w * difference * difference / 2.0); - if (std::fabs(w - monotonic->membership(a)) < - std::fabs(w - monotonic->membership(b))) { - z = a; - } else { - z = b; - } - - } else if (const Concave* concave = dynamic_cast<const Concave*> (monotonic)) { - scalar i = concave->getInflection(); - scalar e = concave->getEnd(); - z = (i - e) / concave->membership(w) + 2 * e - i; - } else { - isTsukamoto = false; - } - - if (isTsukamoto) { - //Compare difference between estimated and true value - scalar fz = monotonic->membership(z); - if (not Op::isEq(w, fz, 1e-2)) { - FL_DBG("[tsukamoto warning] difference <" << Op::str(std::abs(w - fz)) << "> " - "might suggest an inaccurate computation of z because it is " - "expected w=f(z) in " << monotonic->className() << - " term <" << monotonic->getName() << ">, but " - "w=" << w << " " - "f(z)=" << fz << " and " - "z=" << Op::str(z)); - } - } else { - // else fallback to the regular Takagi-Sugeno or inverse Tsukamoto (according to term) - z = monotonic->membership(w); - } - return z; - } - - } diff --git a/fuzzylite/src/defuzzifier/WeightedSum.cpp b/fuzzylite/src/defuzzifier/WeightedSum.cpp index fb3e2e3..6c2343d 100644 --- a/fuzzylite/src/defuzzifier/WeightedSum.cpp +++ b/fuzzylite/src/defuzzifier/WeightedSum.cpp @@ -1,110 +1,86 @@ /* - Author: Juan Rada-Vilela, Ph.D. - Copyright (C) 2010-2014 FuzzyLite Limited - All rights reserved + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. + the terms of the FuzzyLite License included with the software. - fuzzylite 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 Lesser General Public License - for more details. - - You should have received a copy of the GNU Lesser General Public License - along with fuzzylite. If not, see <http://www.gnu.org/licenses/>. - - fuzzylite™ is a trademark of FuzzyLite Limited. + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + fuzzylite is a registered trademark of FuzzyLite Limited. */ #include "fl/defuzzifier/WeightedSum.h" -#include "fl/term/Accumulated.h" -#include "fl/term/Activated.h" -#include "fl/norm/SNorm.h" -#include "fl/norm/TNorm.h" +#include "fl/term/Aggregated.h" #include <map> + namespace fl { - WeightedSum::WeightedSum(Type type) : WeightedDefuzzifier(type) { - } + WeightedSum::WeightedSum(Type type) : WeightedDefuzzifier(type) { } - WeightedSum::WeightedSum(const std::string& type) : WeightedDefuzzifier(type) { + WeightedSum::WeightedSum(const std::string& type) : WeightedDefuzzifier(type) { } - } - - WeightedSum::~WeightedSum() { - } + WeightedSum::~WeightedSum() { } std::string WeightedSum::className() const { return "WeightedSum"; } + Complexity WeightedSum::complexity(const Term* term) const { + Complexity result; + result.comparison(4).function(1); + const Aggregated* fuzzyOutput = dynamic_cast<const Aggregated*> (term); + if (fuzzyOutput) { + result += term->complexity().arithmetic(2).multiply(scalar(fuzzyOutput->numberOfTerms())); + } + return result; + } + scalar WeightedSum::defuzzify(const Term* term, scalar minimum, scalar maximum) const { - const Accumulated* fuzzyOutput = dynamic_cast<const Accumulated*> (term); + const Aggregated* fuzzyOutput = dynamic_cast<const Aggregated*> (term); if (not fuzzyOutput) { std::ostringstream ss; ss << "[defuzzification error]" - << "expected an Accumulated term instead of" - << "<" << term->toString() << ">"; - throw fl::Exception(ss.str(), FL_AT); + << "expected an Aggregated term instead of" + << "<" << (term ? term->toString() : "null") << ">"; + throw Exception(ss.str(), FL_AT); } + if (fuzzyOutput->isEmpty()) return fl::nan; + minimum = fuzzyOutput->getMinimum(); maximum = fuzzyOutput->getMaximum(); + Type type = getType(); + if (type == Automatic) { + type = inferType(&(fuzzyOutput->terms().front())); + } scalar sum = 0.0; - - if (not fuzzyOutput->getAccumulation()) { - Type type = _type; - for (int i = 0; i < fuzzyOutput->numberOfTerms(); ++i) { - Activated* activated = fuzzyOutput->getTerm(i); - scalar w = activated->getDegree(); - - if (type == Automatic) type = inferType(activated->getTerm()); - - scalar z = (type == TakagiSugeno) - //? activated.getTerm()->membership(fl::nan) Would ensure no Tsukamoto applies, but Inverse Tsukamoto with Functions would not work. - ? activated->getTerm()->membership(w) //Provides Takagi-Sugeno and Inverse Tsukamoto of Functions - : tsukamoto(activated->getTerm(), w, minimum, maximum); - + const std::size_t numberOfTerms = fuzzyOutput->numberOfTerms(); + if (type == TakagiSugeno) { + //Provides Takagi-Sugeno and Inverse Tsukamoto of Functions + scalar w, z; + for (std::size_t i = 0; i < numberOfTerms; ++i) { + const Activated& activated = fuzzyOutput->getTerm(i); + w = activated.getDegree(); + z = activated.getTerm()->membership(w); sum += w * z; } } else { - typedef std::map<const Term*, std::vector<Activated*> > TermGroup; - TermGroup groups; - for (int i = 0; i < fuzzyOutput->numberOfTerms(); ++i) { - Activated* value = fuzzyOutput->getTerm(i); - const Term* key = value->getTerm(); - groups[key].push_back(value); - } - TermGroup::const_iterator it = groups.begin(); - Type type = _type; - while (it != groups.end()) { - const Term* activatedTerm = it->first; - scalar accumulatedDegree = 0.0; - for (std::size_t i = 0; i < it->second.size(); ++i) - accumulatedDegree = fuzzyOutput->getAccumulation()->compute( - accumulatedDegree, it->second.at(i)->getDegree()); - - if (type == Automatic) type = inferType(activatedTerm); - - scalar z = (type == TakagiSugeno) - //? activated.getTerm()->membership(fl::nan) Would ensure no Tsukamoto applies, but Inverse Tsukamoto with Functions would not work. - ? activatedTerm->membership(accumulatedDegree) //Provides Takagi-Sugeno and Inverse Tsukamoto of Functions - : tsukamoto(activatedTerm, accumulatedDegree, minimum, maximum); - - sum += accumulatedDegree * z; - - ++it; + scalar w, z; + for (std::size_t i = 0; i < numberOfTerms; ++i) { + const Activated& activated = fuzzyOutput->getTerm(i); + w = activated.getDegree(); + z = activated.getTerm()->tsukamoto(w, minimum, maximum); + sum += w * z; } } return sum; diff --git a/fuzzylite/src/defuzzifier/WeightedSumCustom.cpp b/fuzzylite/src/defuzzifier/WeightedSumCustom.cpp new file mode 100644 index 0000000..5a9084c --- /dev/null +++ b/fuzzylite/src/defuzzifier/WeightedSumCustom.cpp @@ -0,0 +1,112 @@ +/* + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> + + This file is part of fuzzylite. + + fuzzylite is free software: you can redistribute it and/or modify it under + the terms of the FuzzyLite License included with the software. + + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + + fuzzylite is a registered trademark of FuzzyLite Limited. + */ + +#include "fl/defuzzifier/WeightedSumCustom.h" + +#include "fl/term/Aggregated.h" + +#include <map> + +namespace fl { + + WeightedSumCustom::WeightedSumCustom(Type type) : WeightedDefuzzifier(type) { } + + WeightedSumCustom::WeightedSumCustom(const std::string& type) : WeightedDefuzzifier(type) { } + + WeightedSumCustom::~WeightedSumCustom() { } + + std::string WeightedSumCustom::className() const { + return "WeightedSumCustom"; + } + + Complexity WeightedSumCustom::complexity(const Term* term) const { + Complexity result; + result.comparison(4).function(1); + const Aggregated* fuzzyOutput = dynamic_cast<const Aggregated*> (term); + if (fuzzyOutput) { + result += term->complexity().arithmetic(2).comparison(2) + .multiply(scalar(fuzzyOutput->numberOfTerms())); + } + return result; + } + + scalar WeightedSumCustom::defuzzify(const Term* term, + scalar minimum, scalar maximum) const { + const Aggregated* fuzzyOutput = dynamic_cast<const Aggregated*> (term); + if (not fuzzyOutput) { + std::ostringstream ss; + ss << "[defuzzification error]" + << "expected an Aggregated term instead of" + << "<" << (term ? term->toString() : "null") << ">"; + throw Exception(ss.str(), FL_AT); + } + + if (fuzzyOutput->isEmpty()) return fl::nan; + + minimum = fuzzyOutput->getMinimum(); + maximum = fuzzyOutput->getMaximum(); + + Type type = getType(); + if (type == Automatic) { + type = inferType(&(fuzzyOutput->terms().front())); + } + + SNorm* aggregation = fuzzyOutput->getAggregation(); + + scalar sum = 0.0; + const std::size_t numberOfTerms = fuzzyOutput->numberOfTerms(); + if (type == TakagiSugeno) { + //Provides Takagi-Sugeno and Inverse Tsukamoto of Functions + scalar w, z, wz; + for (std::size_t i = 0; i < numberOfTerms; ++i) { + const Activated& activated = fuzzyOutput->getTerm(i); + w = activated.getDegree(); + z = activated.getTerm()->membership(w); + const TNorm* implication = activated.getImplication(); + wz = implication ? implication->compute(w, z) : (w * z); + if (aggregation) { + sum = aggregation->compute(sum, wz); + } else { + sum += wz; + } + } + } else { + scalar w, z, wz; + for (std::size_t i = 0; i < numberOfTerms; ++i) { + const Activated& activated = fuzzyOutput->getTerm(i); + w = activated.getDegree(); + z = activated.getTerm()->tsukamoto(w, minimum, maximum); + const TNorm* implication = activated.getImplication(); + wz = implication ? implication->compute(w, z) : (w * z); + if (aggregation) { + sum = aggregation->compute(sum, wz); + } else { + sum += wz; + } + } + } + return sum; + } + + WeightedSumCustom* WeightedSumCustom::clone() const { + return new WeightedSumCustom(*this); + } + + Defuzzifier* WeightedSumCustom::constructor() { + return new WeightedSumCustom; + } + +} |