diff options
Diffstat (limited to 'fuzzylite/src/defuzzifier/WeightedAverage.cpp')
-rw-r--r-- | fuzzylite/src/defuzzifier/WeightedAverage.cpp | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/fuzzylite/src/defuzzifier/WeightedAverage.cpp b/fuzzylite/src/defuzzifier/WeightedAverage.cpp new file mode 100644 index 0000000..105c9d4 --- /dev/null +++ b/fuzzylite/src/defuzzifier/WeightedAverage.cpp @@ -0,0 +1,123 @@ +/* + Author: Juan Rada-Vilela, Ph.D. + Copyright (C) 2010-2014 FuzzyLite Limited + All rights reserved + + 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. + + 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. + + */ + +#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 <map> + +namespace fl { + + WeightedAverage::WeightedAverage(Type type) : WeightedDefuzzifier(type) { + } + + WeightedAverage::WeightedAverage(const std::string& type) : WeightedDefuzzifier(type) { + } + + WeightedAverage::~WeightedAverage() { + } + + std::string WeightedAverage::className() const { + return "WeightedAverage"; + } + + scalar WeightedAverage::defuzzify(const Term* term, + scalar minimum, scalar maximum) const { + const Accumulated* fuzzyOutput = dynamic_cast<const Accumulated*> (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); + } + + minimum = fuzzyOutput->getMinimum(); + maximum = fuzzyOutput->getMaximum(); + + 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); + + 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; + } + } + return sum / weights; + } + + WeightedAverage* WeightedAverage::clone() const { + return new WeightedAverage(*this); + } + + Defuzzifier* WeightedAverage::constructor() { + return new WeightedAverage; + } +} |