diff options
Diffstat (limited to 'fuzzylite/src/defuzzifier/WeightedAverage.cpp')
-rw-r--r-- | fuzzylite/src/defuzzifier/WeightedAverage.cpp | 119 |
1 files changed, 48 insertions, 71 deletions
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; } + } |