summaryrefslogtreecommitdiff
path: root/fuzzylite/src/defuzzifier/WeightedDefuzzifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fuzzylite/src/defuzzifier/WeightedDefuzzifier.cpp')
-rw-r--r--fuzzylite/src/defuzzifier/WeightedDefuzzifier.cpp130
1 files changed, 14 insertions, 116 deletions
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;
- }
-
-
}