summaryrefslogtreecommitdiff
path: root/fuzzylite/src/defuzzifier/WeightedAverage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fuzzylite/src/defuzzifier/WeightedAverage.cpp')
-rw-r--r--fuzzylite/src/defuzzifier/WeightedAverage.cpp119
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;
}
+
}