source: cpp/frams/genetics/fL/fL_matheval.h @ 787

Last change on this file since 787 was 780, checked in by Maciej Komosinski, 7 years ago

Added sources for genetic encodings fB, fH, fL

File size: 7.4 KB
Line 
1#ifndef _FL_MATHEVAL_H_
2#define _FL_MATHEVAL_H_
3
4#include <string>
5#include <unordered_map>
6#include <list>
7#include <vector>
8
9#define VARIABLEPREFIX '$'
10
11/** @name Available operators for MathEvaluation */
12//@{
13double madd(double left, double right); ///<add
14double msub(double left, double right); ///<subtract
15double mmul(double left, double right); ///<multiply
16double mand(double left, double right); ///<and
17double mor(double left, double right); ///<or
18double mgreater(double left, double right); ///<greater than
19double mless(double left, double right); ///<less than
20double mequal(double left, double right); ///<equal to
21double mnotequal(double left, double right); ///<not equal to
22double meqless(double left, double right); ///<less or equal
23double meqgreater(double left, double right); ///<greater or equal
24//@}
25
26/**
27 * Class for performing simple mathematical parsing and evaluations of expressions
28 * stored in strings. At first, the class object converts given string into list
29 * of objects that can be described as Reverse Polish Notation, or suffix notation.
30 * From this notation object can efficiently perform calculations for different
31 * values of variables, without re-tokenizing of a string.
32 */
33class MathEvaluation
34{
35        /// determines to whih class token belongs
36        enum TokenType {
37                NUMBER, ///<Number token
38                PARENTHESIS, ///<Parenthesis token
39                OPERATOR,  ///<Operator token
40                VARIABLE ///<Variable token
41        };
42        /// associativity of operator
43        enum Associativity {
44                RIGHT,
45                LEFT
46        };
47        /// determines if parenthesis is opening of closing
48        enum ParenthesisType {
49                OPEN,
50                CLOSE
51        };
52
53        /**
54         * Simplest token of MathEvaluation Reverse Polish Notation. Every class used
55         * in RPN notation should inherit from this class.
56         */
57        class Token
58        {
59        public:
60                TokenType type; ///<type of token
61                /**
62                 * Method is used during converting list of token objects into infix
63                 * notation. Every class should implement this method and provide useful
64                 * and valid information for infix notation.
65                 * @return stringified token
66                 */
67                virtual std::string toString() = 0;
68                Token(TokenType type) : type(type) {}
69                virtual ~Token() {}
70        };
71
72        /**
73         * Describes all numbers available in object infix notation.
74         */
75        class Number : public Token
76        {
77        public:
78                double value; ///<value of stored number
79                Number(double value) : Token(TokenType::NUMBER), value(value)
80                { }
81                ~Number() {}
82                std::string toString();
83                /**
84                 * Copies value field from given source.
85                 * @param src other Number object
86                 */
87                void operator=(const Number& src);
88        };
89
90        /**
91         * Special type of Number object, which holds external variables, represented
92         * as $id, where id is a number.
93         */
94        class Variable : public Number
95        {
96        public:
97                int id; ///<id of Variable object. Object is accessed via $id
98                Variable(int id) : Number(0), id(id)
99                {
100                        type = TokenType::VARIABLE;
101                }
102                ~Variable() {}
103                std::string toString();
104        };
105
106        /**
107         * Class describing operator in RPN objects. It holds informations about
108         * precedence, associativity and symbol of the operator. Operator can have 1
109         * or 2 characters, not more or less. Operator requires function that takes
110         * two doubles and returns double value -- the result of this function is the
111         * result of operator execution.
112         */
113        class Operator : public Token
114        {
115                double(*operation)(double left, double right); ///<field holding pointer to operator function
116        public:
117                int precedence; ///<precedence of the operator
118                Associativity assoc; ///<associativity of the operator
119                std::string opname; ///<symbol of the operator, can have 1 or 2 characters
120
121                /**
122                 * Uses method pointed by 'operation' pointer to return operator result
123                 * for a given numbers.
124                 * @param left number on the left side of the operator
125                 * @param right number on the right side of the operator
126                 * @return operator result
127                 */
128                double execute(double left, double right);
129
130                Operator(double(*operation)(double left, double right), int precedence,
131                        Associativity assoc, std::string opname) :
132                        Token(TokenType::OPERATOR),
133                        operation(operation),
134                        precedence(precedence),
135                        assoc(assoc),
136                        opname(opname)
137                { }
138                ~Operator() {}
139                std::string toString();
140        };
141
142        /**
143         * Class represents parenthesis token. Parenthesis are considered only during
144         * creation of RPN notation - the notation itself does not contain any
145         * parenthesis, because the order of calculation is determined directly by
146         * operators and numbers order.
147         */
148        class Parenthesis : public Token
149        {
150        public:
151                ParenthesisType ptype; ///<determines if parenthesis is open or closed
152                Parenthesis(ParenthesisType ptype) :
153                        Token(TokenType::PARENTHESIS),
154                        ptype(ptype)
155                { }
156                ~Parenthesis() { }
157                std::string toString();
158        };
159
160        /**
161         * Clears postfix objects stored in MathEvaluation object.
162         */
163        void clearPostfix();
164
165        /**
166         * Registers operators available in MathEvaluation object. Default operators
167         * are +, -, *, &, |, >, <, >=, <=, =, ~, where ~ is inequality.
168         * Registered operators can have maximally two characters, otherwise they are
169         * ignored.
170         */
171        void registerOperators();
172
173        std::unordered_map<std::string, Operator *> operators; ///<map containing available operators for MathEvaluation
174        std::list<Token *> postfixlist; ///<list with tokens ordered as postfix (RPN) notation of the given string
175        int varcount; ///<amount of variables declared for this MathEvaluation object
176        std::vector<Variable *> vars; ///<vector of variables, default values are 0
177        Variable *t; ///<additional t variable, that can act as time for evaluation
178public:
179
180        /**
181         * Default constructor. It registers operators for MathEvaluation and prepares
182         * vector of variables.
183         */
184        MathEvaluation(int varcount);
185
186        /**
187         * Destructor is responsible for clearing all objects in postfix, all operator
188         * objects and all variables.
189         */
190        ~MathEvaluation();
191
192        /**
193         * Converts string to std::list of tokens in postfix order that can be later
194         * evaluated. Detailed description of algorithm can be found in source of
195         * method.
196         * @param expression infix mathematical expression
197         * @return 0 if conversion is successful, or -1 if an error occurred
198         */
199        int convertString(std::string expression);
200
201        /**
202         * Evaluates expression stored in postfix list. It takes into account changes
203         * made by modifyVariable method. This method should be called if the only
204         * thing changed in expression are variable values - it saves time because
205         * it uses objects created during convertString or evaluate method.
206         * @param res reference to the variable, in which result will be stored
207         * @return 0 if evaluation went successful, or -1 if an error occurred
208         */
209        int evaluateRPN(double &res);
210
211        /**
212         * Performs convertString and evaluateRPN methods respectively. It holds
213         * objects created by convertString method.
214         * @param expression infix mathematical expression
215         * @param result reference to the variable, in which result will be stored
216         * @return 0 if evaluation went successful, otherwise it returns the error of previous functions
217         */
218        int evaluate(std::string expression, double &result);
219
220        /**
221         * Sets variable with index i with value val.
222         * @param i id of variable, -1 if changed variable should be variable 't' (time)
223         * @param val new value
224         */
225        void modifyVariable(int i, double val);
226
227        /**
228         * Converts stored RPN list to infix string.
229         * @param result reference to variable that will hold the result
230         * @return 0 if method went successful, or -1 if an error occurred
231         */
232        int RPNToInfix(std::string &result);
233};
234
235#endif // _FL_MATHEVAL_H_
Note: See TracBrowser for help on using the repository browser.