summaryrefslogtreecommitdiff
path: root/fuzzylite/src/defuzzifier
diff options
context:
space:
mode:
authorJohannes 'josch' Schauer <josch@debian.org>2019-01-27 13:56:24 +0100
committerJohannes 'josch' Schauer <josch@debian.org>2019-01-27 13:56:33 +0100
commit6ce553563bc795f389f639a3a8cdfe356de71441 (patch)
treeda4c9ede3087ca534d93bc1ac5a14f044f036600 /fuzzylite/src/defuzzifier
parentbbefa170378553e5a6e0d72e4d52328b61f3e8ac (diff)
new upstream version 6.0
Diffstat (limited to 'fuzzylite/src/defuzzifier')
-rw-r--r--fuzzylite/src/defuzzifier/Bisector.cpp59
-rw-r--r--fuzzylite/src/defuzzifier/Centroid.cpp66
-rw-r--r--fuzzylite/src/defuzzifier/IntegralDefuzzifier.cpp31
-rw-r--r--fuzzylite/src/defuzzifier/LargestOfMaximum.cpp48
-rw-r--r--fuzzylite/src/defuzzifier/MeanOfMaximum.cpp53
-rw-r--r--fuzzylite/src/defuzzifier/SmallestOfMaximum.cpp50
-rw-r--r--fuzzylite/src/defuzzifier/WeightedAverage.cpp119
-rw-r--r--fuzzylite/src/defuzzifier/WeightedAverageCustom.cpp117
-rw-r--r--fuzzylite/src/defuzzifier/WeightedDefuzzifier.cpp130
-rw-r--r--fuzzylite/src/defuzzifier/WeightedSum.cpp116
-rw-r--r--fuzzylite/src/defuzzifier/WeightedSumCustom.cpp112
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;
+ }
+
+}