summaryrefslogtreecommitdiff
path: root/fuzzylite/fl/term/Function.h
diff options
context:
space:
mode:
Diffstat (limited to 'fuzzylite/fl/term/Function.h')
-rw-r--r--fuzzylite/fl/term/Function.h312
1 files changed, 270 insertions, 42 deletions
diff --git a/fuzzylite/fl/term/Function.h b/fuzzylite/fl/term/Function.h
index 99580b7..14e3427 100644
--- a/fuzzylite/fl/term/Function.h
+++ b/fuzzylite/fl/term/Function.h
@@ -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.
*/
#ifndef FL_FUNCTION_H
@@ -34,27 +26,77 @@ namespace fl {
class Engine;
+ /**
+ The Function class is a polynomial Term that represents a generic
+ function @f$ f : x \mapsto f(x) @f$. Every Function object has a public
+ key-value map, namely Function::variables, that links variable names to
+ fl::scalar values, which are utilized to replace the variable names for
+ their respective values in the given formula whenever the function
+ @f$f@f$ is evaluated. Specifically, when the method
+ Function::membership() is called, the name and value of the variable
+ @f$x@f$ are automatically loaded into the map. Furthermore, if an Engine
+ is given, the names of its InputVariable%s and OutputVariable%s will also
+ be automatically loaded into the map linking to their respective input
+ values and (previously defuzzified) output values. The
+ Function::variables need to be manually loaded whenever variables other
+ than @f$x@f$, input variables, and output variables, are expressed in the
+ given formula, always having in mind that (a) the map replaces existing
+ keys, and (b) the variable @f$x@f$, and input variables and output
+ variables of an engine will automatically be replaced and will also take
+ precedence over previously loaded variables.
+
+ Besides the use of Function as a linguistic Term, it is also utilized to
+ convert the text of the Antecedent of a Rule, expressed in infix
+ notation, into postfix notation.
+
+
+ @author Juan Rada-Vilela, Ph.D.
+ @see Term
+ @see Variable
+ @see FunctionFactory
+ @see Antecedent::load()
+ @since 4.0
+ */
class FL_API Function : public Term {
- /****************************
- * Parsing Elements
- ****************************/
-
public:
typedef scalar(*Unary)(scalar);
typedef scalar(*Binary)(scalar, scalar);
+ /**
+ The Element class represents a single element in a formula, be that
+ either a function or an operator. If the Element represents a
+ function, the function can be Unary or Binary, that is, the function
+ take one or two parameters (respectively). Else, if the Element
+ represents an operator, the parameters to be defined are its `arity`,
+ its `precedence`, and its `associativity`.
+ */
struct FL_API Element {
+ /**
+ Determines the type of the element
+ */
enum Type {
- OPERATOR, FUNCTION
+ Operator, Function
};
+ /**Name of the element*/
std::string name;
+ /**Description of the element*/
std::string description;
+ /**Type of the element*/
Type type;
+ /**Pointer to unary method*/
Unary unary;
+ /**Pointer to binary method*/
Binary binary;
+ /**Number of operands required*/
int arity;
- int precedence; //Operator
+ /**Precedence of the element: clarifies which procedures should be
+ performed first in a given mathematical expression
+ (https://en.wikipedia.org/wiki/Order_of_operations)*/
+ int precedence;
+ /**Associativity of the element: determines how operators of the
+ same precedence are grouped in the absence of parentheses
+ (https://en.wikipedia.org/wiki/Operator_associativity)*/
int associativity;
Element(const std::string& name, const std::string& description, Type type);
Element(const std::string& name, const std::string& description,
@@ -64,24 +106,46 @@ namespace fl {
virtual ~Element();
FL_DEFAULT_COPY_AND_MOVE(Element)
+ /**
+ Indicates whether the element is a Type::Operator
+ @return whether the element is a Type::Operator
+ */
virtual bool isOperator() const;
+ /**
+ Indicates whether the element is a Type::Function
+ @return whether the element is a Type::Function
+ */
virtual bool isFunction() const;
-
+ /**
+ Clones the element
+ @return a clone of the element
+ */
virtual Element* clone() const;
+ /**
+ Returns a description of the element and its members
+ @return a description of the element and its members
+ */
virtual std::string toString() const;
};
- /**************************
- * Tree elements, wrap Elements into Nodes.
- **************************/
-
+ /**
+ The Node class structures a binary tree by storing pointers to a left
+ Node and a right Node, and storing its content as a
+ Function::Element, the name of an InputVariable or OutputVariable, or
+ a constant value.
+ */
struct FL_API Node {
+ /**The node takes an operation or a function*/
FL_unique_ptr<Element> element;
+ /**The node can have an expression tree on the left*/
FL_unique_ptr<Node> left;
+ /**The node can have an expression tree on the right*/
FL_unique_ptr<Node> right;
+ /**The node can refer to a variable by name*/
std::string variable;
+ /**The node can take an arbitrary floating-point value*/
scalar value;
explicit Node(Element* element, Node* left = fl::null, Node* right = fl::null);
@@ -92,14 +156,79 @@ namespace fl {
virtual ~Node();
FL_DEFAULT_MOVE(Node)
+ /**
+ Evaluates the node and substitutes the variables therein for the
+ values passed in the map. The expression tree is evaluated
+ recursively.
+
+ @param variables is a map of substitutions of variable names for
+ fl::scalar%s
+
+ @return a fl::scalar indicating the result of the evaluation of
+ the node
+ */
virtual scalar evaluate(const std::map<std::string, scalar>*
variables = fl::null) const;
+ /**
+ Computes the size of the subtree under the given node. The complexity
+ of calling this method is O(n).
+ @param node is the root of the subtree, which is this node if
+ fl::null is given
+ @return the size of the subtree under the given node
+ */
+ virtual std::size_t treeSize(const Node* node = fl::null) const;
+
+ /**
+ Computes the size of the subtree under the given node whose elements
+ are of the given type. The complexity of calling this method is O(n).
+ @param type is the type of elements to account for
+ @param node is the root of the subtree, which is this node if
+ fl::null is given
+ @return
+ */
+ virtual std::size_t treeSize(Element::Type type,
+ const Node* node = fl::null) const;
+
+ /**
+ Creates a clone of the node.
+ @return a clone of the node
+ */
virtual Node* clone() const;
+ /**
+ Returns a string with the name of the element, the name of the
+ variable, or the constant value, accordingly.
+ @return a string with the name of the element, the name of the
+ variable, or the constant value, accordingly.
+ */
virtual std::string toString() const;
+ /**
+ Returns a prefix representation of the expression tree under the
+ given node
+ @param node is the node to start the prefix representation from.
+ If the node is `fl::null`, then the starting point is `this` node
+ @return a prefix representation of the expression tree under the
+ given node
+ */
virtual std::string toPrefix(const Node* node = fl::null) const;
+ /**
+ Returns an infix representation of the expression tree under the
+ given node
+ @param node is the node to start the infix representation from.
+ If the node is `fl::null`, then the starting point is `this` node
+ @return an infix representation of the expression tree under the
+ given node
+ */
virtual std::string toInfix(const Node* node = fl::null) const;
+ /**
+ Returns a postfix representation of the expression tree under the
+ given node
+ @param node is the node to start the postfix representation from.
+ If the node is `fl::null`, then the starting point is `this` node
+ @return a postfix representation of the expression tree under the
+ given node
+ */
virtual std::string toPostfix(const Node* node = fl::null) const;
private:
void copyFrom(const Node& source);
@@ -112,11 +241,12 @@ namespace fl {
* Term
******************************/
- protected:
+ private:
FL_unique_ptr<Node> _root;
std::string _formula;
const Engine* _engine;
public:
+ /**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);
@@ -125,47 +255,145 @@ namespace fl {
virtual ~Function() FL_IOVERRIDE;
FL_DEFAULT_MOVE(Function)
+ /**
+ Creates a Function term with the given parameters
+ @param name is the name of the term
+ @param formula is the formula defining the membership function
+ @param engine is the engine to which the Function can have access
+ @return a Function term configured with the given parameters
+ @throws fl::Exception if the formula has a syntax error
+ */
static Function* create(const std::string& name,
const std::string& formula,
- const Engine* engine = fl::null); // throw (fl::Exception);
-
+ const Engine* engine = fl::null);
+
+ virtual Complexity complexity() const FL_IOVERRIDE;
+
+ /**
+ Computes the membership function value of @f$x@f$ at the root node.
+ If the engine has been set, the current values of the input variables
+ and output variables are added to the map of Function::variables. In
+ addition, the variable @f$x@f$ will also be added to the map.
+ @param x
+ @return the membership function value of @f$x@f$ at the root node
+ */
virtual scalar membership(scalar x) const FL_IOVERRIDE;
- virtual scalar evaluate(const std::map<std::string, scalar>* variables) const;
+ /**
+ Computes the function value of this term using the given map of
+ variable substitutions.
+ @param variables is a map of substitution variables
+ @return the function value of this term using the given map of
+ variable substitutions.
+ */
+ virtual scalar evaluate(const std::map<std::string, scalar>* variables = fl::null) const;
virtual std::string className() const FL_IOVERRIDE;
+ /**
+ Returns the parameters of the term as `formula`
+ @return `formula`
+ */
virtual std::string parameters() const FL_IOVERRIDE;
+ /**
+ Configures the term with the parameters given as `formula`
+ @param parameters as `formula`
+ */
virtual void configure(const std::string& parameters) FL_IOVERRIDE;
+ /**
+ Sets the formula of the function
+ @param formula is the formula of the function
+ */
virtual void setFormula(const std::string& formula);
+ /**
+ Gets the formula of the function
+ @return the formula of the function
+ */
virtual std::string getFormula() const;
+ /**
+ Sets the engine to which the formula can refer
+ @param engine is the engine to which the formula can refer
+ */
virtual void setEngine(const Engine* engine);
+ /**
+ Gets the engine to which the formula can refer
+ @return the engine to which the formula can refer
+ */
virtual const Engine* getEngine() const;
+ /**
+ Gets the root node of the expression tree defining the Function. The
+ root is `fl::null` if the formula has not been loaded.
+ @return the root node of the expression tree defining the Function,
+ or `fl::null` if the formula has not been loaded
+ */
virtual Node* root() const;
+ /**
+ Indicates whether the formula is loaded
+ @return whether the formula is loaded
+ */
virtual bool isLoaded() const;
+ /**
+ Unloads the formula and resets the map of substitution variables.
+ */
virtual void unload();
- virtual void load(); // throw (fl::Exception);
- virtual void load(const std::string& formula); // throw (fl::Exception);
- virtual void load(const std::string& formula, const Engine* engine); // throw (fl::Exception);
-
- virtual Node* parse(const std::string& formula); // throw (fl::Exception);
-
- virtual std::string toPostfix(const std::string& formula) const; //throw (fl::Exception);
-
+ /**
+ Loads the current formula expressed in infix notation
+ */
+ virtual void load();
+ /**
+ Loads the given formula expressed in infix notation
+ @param formula is the right-hand side of a mathematical equation
+ @throws fl::Exception if the formula has syntax errors
+ */
+ virtual void load(const std::string& formula);
+ /**
+ Loads the given formula expressed in infix notation, and sets the
+ engine holding the variables to which the formula refers.
+ @param formula is the right-hand side of a mathematical equation
+ expressed in infix notation
+ @param engine is the engine to which the formula can refer
+ @throws fl::Exception if the formula has syntax errors
+ */
+ virtual void load(const std::string& formula, const Engine* engine);
+ /**
+ Creates a node representing a binary expression tree from the given formula
+ @param formula is the right-hand side of a mathematical equation
+ expressed in infix notation
+ @return a node representing a binary expression tree from the given formula
+ @throws fl::Exception if the formula has syntax errors
+ */
+ virtual Node* parse(const std::string& formula);
+
+ /**
+ Translates the given formula to postfix notation
+ @param formula is the right-hand side of a mathematical equation
+ expressed in infix notation
+ @return the formula represented in postfix notation
+ @throws fl::Exception if the formula has syntax errors
+ */
+ virtual std::string toPostfix(const std::string& formula) const;
+
+ /**
+ Adds spaces to the formula to separate parentheses, commas and
+ function operators such that these are treated as tokens when parsing
+ the function.
+ @param formula is the right-hand side of a mathematical equation
+ expressed in infix notation
+ @return the formula with spaces before and after parentheses, commas
+ and function operators
+ */
virtual std::string space(const std::string& formula) const;
+ virtual void updateReference(const Engine* engine) FL_IOVERRIDE;
+
virtual Function* clone() const FL_IOVERRIDE;
static Term* constructor();
- static void main();
-
};
-
}
-
#endif /* FL_FUNCTION_H */