Skip to content

Commit

Permalink
Test: Terms (#141)
Browse files Browse the repository at this point in the history
* Test: Terms

* Remove build type from Makefile

* Test: a few terms

* Better concat of strings

* Test: More terms

* Remove main from FL_SOURCES

* gcovr --verbose

* llvm-cov gcov

* Revert Mac

* Linux Quick Coverage

* Test or Coverage

* workflows: Linux Coverage

* Test: Windows

* Test: Windows 2

* Updated

* Coverage multiple outputs

* Using methods to naturally increase coverage

* 40% coverage on src/term

* Activated: reuse height in place of degree

* Fix: --coverage

* Discrete: reuse method

* Tests: Activated and Discrete

* Tests: Aggregated term + minor fixes

* Tests: Merged old term tests

* CMake: show location of Catch2

* Makefile: default is debug

* fuzzylite.h: TODO

* Engine: Better constructor

* Function: Better error messages + Minor improvements

* TODO: ** for pow

* Format

* Activated::isMonotonic()

* Activated::monotonic()

* Fix: Windows

* float -> scalar

* Fix: test
  • Loading branch information
jcrada committed Mar 5, 2024
1 parent 70c4e52 commit acaa42c
Show file tree
Hide file tree
Showing 38 changed files with 2,399 additions and 534 deletions.
6 changes: 1 addition & 5 deletions FL_TESTS
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
test/MainTest.cpp
test/BenchmarkTest.cpp
test/QuickTest.cpp
test/TestTerm.cpp
test/activation/ThresholdTest.cpp
test/hedge/HedgeFunctionTest.cpp
test/imex/FldExporterTest.cpp
test/imex/FllImporterTest.cpp
test/imex/RScriptExporterTest.cpp
test/norm/NormFunctionTest.cpp
test/term/AggregatedTest.cpp
test/term/DiscreteTest.cpp
test/term/FunctionTest.cpp
test/term/TrapezoidTest.cpp
test/term/TriangleTest.cpp
test/variable/VariableTest.cpp
9 changes: 8 additions & 1 deletion fuzzylite/Engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,14 @@ namespace fuzzylite {
void updateReferences() const;

public:
explicit Engine(const std::string& name = "");
explicit Engine(
const std::string& name = "",
const std::string& description = "",
const std::vector<InputVariable*>& inputVariables = std::vector<InputVariable*>(),
const std::vector<OutputVariable*>& outputVariables = std::vector<OutputVariable*>(),
const std::vector<RuleBlock*>& ruleBlocks = std::vector<RuleBlock*>(),
bool load = true
);
Engine(const Engine& other);
Engine& operator=(const Engine& other);
virtual ~Engine();
Expand Down
7 changes: 7 additions & 0 deletions fuzzylite/fuzzylite.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ fuzzylite is a registered trademark of FuzzyLite Limited.
#include <memory>
#include <sstream>

/**
* TODO:
* - Remove FL_BUILD_PATH
* - Declare FL_DEPRECATED
* - Move into Library class
*/

#ifndef FL_BUILD_PATH
#define FL_BUILD_PATH ""
#endif
Expand Down
4 changes: 2 additions & 2 deletions fuzzylite/term/Activated.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ namespace fuzzylite {
class FL_API Activated : public Term {
private:
const Term* _term;
scalar _degree;
const TNorm* _implication;

public:
Expand Down Expand Up @@ -66,7 +65,8 @@ namespace fuzzylite {
*/
virtual scalar membership(scalar x) const FL_IOVERRIDE;
virtual std::string toString() const FL_IOVERRIDE;

virtual std::string getName() const FL_IOVERRIDE;
virtual bool isMonotonic() const FL_IOVERRIDE;
/**
Sets the activated term
@param term is the activated term
Expand Down
1 change: 1 addition & 0 deletions fuzzylite/term/Binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ namespace fuzzylite {
/** `(_|)` increases to the right (infinity)*/
Positive,
/** `(--)` direction is NaN */
// TODO: Consistency with Sigmoid, Ramp
Undefined,
/** `(|_)` increases to the left (-infinity)*/
Negative
Expand Down
16 changes: 13 additions & 3 deletions fuzzylite/term/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,16 +156,20 @@ namespace fuzzylite {
/**The node can refer to a variable by name*/
std::string variable;
/**The node can take an arbitrary floating-point value*/
scalar value;
scalar constant;

explicit Node(Element* element, Node* left = fl::null, Node* right = fl::null);
explicit Node(const std::string& variable);
explicit Node(scalar value);
explicit Node(scalar constant);
Node(const Node& source);
Node& operator=(const Node& rhs);
virtual ~Node();
FL_DEFAULT_MOVE(Node)

/**
* Gets the value of the node.
*/
virtual std::string value() const;
/**
Evaluates the node and substitutes the variables therein for the
values passed in the map. The expression tree is evaluated
Expand Down Expand Up @@ -256,8 +260,14 @@ namespace fuzzylite {
/**A map of variables and substitution values**/
mutable std::map<std::string, scalar> variables;
explicit Function(
const std::string& name = "", const std::string& formula = "", const Engine* engine = fl::null
const std::string& name = "",
const std::string& formula = "",
const std::map<std::string, scalar>& variables = std::map<std::string, scalar>(),
const Engine* engine = fl::null,
bool load = false
);
// TODO: Deprecate
explicit Function(const std::string& name, const std::string& formula, const Engine* engine);
Function(const Function& other);
Function& operator=(const Function& other);
virtual ~Function() FL_IOVERRIDE;
Expand Down
21 changes: 20 additions & 1 deletion src/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,26 @@ fuzzylite is a registered trademark of FuzzyLite Limited.

namespace fuzzylite {

Engine::Engine(const std::string& name) : _name(name) {}
Engine::Engine(
const std::string& name,
const std::string& description,
const std::vector<InputVariable*>& inputVariables,
const std::vector<OutputVariable*>& outputVariables,
const std::vector<RuleBlock*>& ruleBlocks,
const bool load
) :
_name(name),
_description(description),
_inputVariables(inputVariables),
_outputVariables(outputVariables),
_ruleBlocks(ruleBlocks) {
if (load) {
updateReferences();

for (std::size_t r = 0; r < ruleBlocks.size(); ++r)
ruleBlocks.at(r)->loadRules(this);
}
}

Engine::Engine(const Engine& other) : _name(""), _description("") {
copyFrom(other);
Expand Down
1 change: 1 addition & 0 deletions src/factory/FunctionFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ namespace fuzzylite {
p -= 10;
// Second order: power
registerObject("^", new Function::Element("^", "Power", Function::Element::Operator, &(std::pow), p, 1));
// registerObject("**", new Function::Element("**", "Power", Function::Element::Operator, &(std::pow), p, 1));

p -= 10;
// Third order: multiplication, division, modulo
Expand Down
8 changes: 7 additions & 1 deletion src/imex/FllExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,13 @@ namespace fuzzylite {
}

std::string FllExporter::toString(const Term* term) const {
return "term: " + Op::validName(term->getName()) + " " + term->className() + " " + term->parameters();
std::vector<std::string> result;
result.push_back("term:");
result.push_back(Op::validName(term->getName()));
result.push_back(term->className());
if (not term->parameters().empty())
result.push_back(term->parameters());
return Op::join(result, " ");
}

std::string FllExporter::toString(const Norm* norm) const {
Expand Down
22 changes: 13 additions & 9 deletions src/term/Activated.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,24 @@ fuzzylite is a registered trademark of FuzzyLite Limited.
namespace fuzzylite {

Activated::Activated(const Term* term, scalar degree, const TNorm* implication) :
Term(""),
Term("", degree),
_term(term),
_degree(degree),
_implication(implication) {
if (term)
setName(term->getName());
}
_implication(implication) {}

Activated::~Activated() {}

std::string Activated::className() const {
return "Activated";
}

std::string Activated::getName() const {
return _term ? _term->getName() : "";
}

bool Activated::isMonotonic() const {
return _term ? _term->isMonotonic() : false;
}

scalar Activated::membership(scalar x) const {
if (Op::isNaN(x))
return fl::nan;
Expand All @@ -48,7 +52,7 @@ namespace fuzzylite {
+ getTerm()->toString(),
FL_AT
);
return _implication->compute(_term->membership(x), _degree);
return _implication->compute(_term->membership(x), _height);
}

std::string Activated::parameters() const {
Expand Down Expand Up @@ -84,11 +88,11 @@ namespace fuzzylite {
}

void Activated::setDegree(scalar degree) {
this->_degree = degree;
setHeight(degree);
}

scalar Activated::getDegree() const {
return this->_degree;
return getHeight();
}

void Activated::setImplication(const TNorm* implication) {
Expand Down
4 changes: 2 additions & 2 deletions src/term/Aggregated.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ namespace fuzzylite {
scalar Aggregated::membership(scalar x) const {
if (Op::isNaN(x))
return fl::nan;
if (not(_terms.empty() or _aggregation.get())) { // Exception for IntegralDefuzzifiers
if (not _terms.empty() and not _aggregation.get()) { // Exception for IntegralDefuzzifiers
throw Exception(
"[aggregation error] "
"aggregation operator needed to aggregate variable "
Expand Down Expand Up @@ -109,7 +109,7 @@ namespace fuzzylite {
FllExporter exporter;
std::ostringstream ss;
ss << exporter.toString(getAggregation());
ss << " " << Op::str(getMinimum()) << " " << Op::str(getMaximum()) << " ";
ss << " " << Op::str(getMinimum()) << " " << Op::str(getMaximum());
for (std::size_t i = 0; i < terms().size(); ++i)
ss << " " << exporter.toString(&terms().at(i));
return ss.str();
Expand Down
2 changes: 1 addition & 1 deletion src/term/Bell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace fuzzylite {
}

std::string Bell::parameters() const {
return Op::join(3, " ", _center, _width, _slope)
return Op::join(3, " ", getCenter(), getWidth(), getSlope())
+ (not Op::isEq(getHeight(), 1.0) ? " " + Op::str(getHeight()) : "");
}

Expand Down
2 changes: 1 addition & 1 deletion src/term/Binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace fuzzylite {
}

std::string Binary::parameters() const {
return Op::join(2, " ", _start, _direction)
return Op::join(2, " ", getStart(), getDirection())
+ (not Op::isEq(getHeight(), 1.0) ? " " + Op::str(getHeight()) : "");
}

Expand Down
3 changes: 2 additions & 1 deletion src/term/Concave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ namespace fuzzylite {
}

std::string Concave::parameters() const {
return Op::join(2, " ", _inflection, _end) + (not Op::isEq(getHeight(), 1.0) ? " " + Op::str(getHeight()) : "");
return Op::join(2, " ", getInflection(), getEnd())
+ (not Op::isEq(getHeight(), 1.0) ? " " + Op::str(getHeight()) : "");
}

void Concave::configure(const std::string& parameters) {
Expand Down
2 changes: 1 addition & 1 deletion src/term/Constant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace fuzzylite {
}

std::string Constant::parameters() const {
return Op::str(_value);
return Op::str(getValue());
}

void Constant::configure(const std::string& parameters) {
Expand Down
3 changes: 2 additions & 1 deletion src/term/Cosine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ namespace fuzzylite {
}

std::string Cosine::parameters() const {
return Op::join(2, " ", _center, _width) + (not Op::isEq(getHeight(), 1.0) ? " " + Op::str(getHeight()) : "");
return Op::join(2, " ", getCenter(), getWidth())
+ (not Op::isEq(getHeight(), 1.0) ? " " + Op::str(getHeight()) : "");
}

void Cosine::configure(const std::string& parameters) {
Expand Down
28 changes: 11 additions & 17 deletions src/term/Discrete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,14 @@ namespace fuzzylite {
}

std::string Discrete::parameters() const {
std::ostringstream ss;
for (std::size_t i = 0; i < _xy.size(); ++i) {
ss << Op::str(_xy.at(i).first) << " " << Op::str(_xy.at(i).second);
if (i + 1 < _xy.size())
ss << " ";
std::vector<std::string> result;
for (std::size_t i = 0; i < xy().size(); ++i) {
result.push_back(Op::str(xy().at(i).first));
result.push_back(Op::str(xy().at(i).second));
}
if (not Op::isEq(getHeight(), 1.0))
ss << " " << Op::str(getHeight());
return ss.str();
result.push_back(Op::str(getHeight()));
return Op::join(result, " ");
}

void Discrete::configure(const std::string& parameters) {
Expand Down Expand Up @@ -168,16 +167,11 @@ namespace fuzzylite {
}

std::vector<Discrete::Pair> Discrete::toPairs(const std::vector<scalar>& xy, scalar missingValue) FL_INOEXCEPT {
std::vector<Pair> result((xy.size() + 1) / 2);
for (std::size_t i = 0; i + 1 < xy.size(); i += 2) {
result.at(i / 2).first = xy.at(i);
result.at(i / 2).second = xy.at(i + 1);
}
if (xy.size() % 2 != 0) {
result.back().first = xy.back();
result.back().second = missingValue;
}
return result;
if (xy.size() % 2 == 0)
return toPairs(xy);
std::vector<scalar> copy(xy);
copy.push_back(missingValue);
return toPairs(copy);
}

std::vector<scalar> Discrete::toVector(const std::vector<Pair>& xy) {
Expand Down
Loading

0 comments on commit acaa42c

Please sign in to comment.