OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
Expression.h
Go to the documentation of this file.
1//
2// Class Expression
3// Expression to be evaluated in the framework.
4//
5// @see GlobalFunctions.h
6//
7// This class uses the Boost Spirit parser to parse and evaluate string
8// expressions (objectives or constraints).
9// Custom functions called in the expression should be registered by the
10// driver. A collection of C math default functions is always included.
11// For constraints the operator type can be queried.
12//
13// Copyright (c) 2010 - 2013, Yves Ineichen, ETH Zürich
14// All rights reserved
15//
16// Implemented as part of the PhD thesis
17// "Toward massively parallel multi-objective optimization with application to
18// particle accelerators" (https://doi.org/10.3929/ethz-a-009792359)
19//
20// This file is part of OPAL.
21//
22// OPAL is free software: you can redistribute it and/or modify
23// it under the terms of the GNU General Public License as published by
24// the Free Software Foundation, either version 3 of the License, or
25// (at your option) any later version.
26//
27// You should have received a copy of the GNU General Public License
28// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
29//
30#ifndef __EXPRESSION_H__
31#define __EXPRESSION_H__
32
33#include <map>
34#include <set>
35#include <string>
36#include <string_view>
37#include <tuple>
38#include <variant>
39
40#include "Util/Types.h"
42
48
49#include <boost/function.hpp>
50#include <boost/lexical_cast.hpp>
51#include "boost/algorithm/string.hpp"
52
53
54typedef std::map<std::string, double> variableDictionary_t;
55typedef std::map<std::string, client::function::type> functionDictionary_t;
56
57
58class Expression;
59namespace Expressions {
60
63
64 // result of an evaluated expression
65 typedef std::tuple<double, bool> Result_t;
70
71 //FIXME: this actually should be a map of type (name, fusion::vector<...>)
73 typedef std::map<std::string, Expressions::Expr_t*> Named_t;
74
75 //XXX name of one single expression
76 typedef std::pair<std::string, Expressions::Expr_t*> SingleNamed_t;
77
79 enum class OperatorType_t {
80 NONE,
81 EQ, // ==
82 NOT_EQ, // !=
83 INEQ_LHS, // <
84 INEQ_LHS_EQ, // <=
85 INEQ_RHS, // >
86 INEQ_RHS_EQ // >=
87 };
88
89}
90
92
94
95public:
96
98 {}
99
100 Expression(std::string expr)
101 : expr_(expr)
102 {
104 functionDictionary_t global_funcs = GlobalFunctions::get();
105 known_expr_funcs_.insert(global_funcs.begin(), global_funcs.end());
106 parse();
107 }
108
109 Expression(std::string expr, functionDictionary_t known_expr_funcs)
110 : expr_(std::move(expr))
111 , known_expr_funcs_(known_expr_funcs)
112 {
114 functionDictionary_t global_funcs = GlobalFunctions::get();
115 known_expr_funcs_.insert(global_funcs.begin(), global_funcs.end());
116 parse();
117 }
118
119 virtual ~Expression()
120 {}
121
122 const std::set<std::string>& getReqVars() const { return vars_; }
123 const std::set<std::string>& getReqFuncs() const { return funcs_; }
124 const std::string& toString() const { return expr_; }
125
127
130
133
134 iterator_type iter = expr_.begin();
135 iterator_type end = expr_.end();
136 client::error_handler<iterator_type> error_handler(iter, end);
137 client::code_gen::StackEvaluator evaluator(error_handler);
138 evaluator.registerVariables(vars);
140
141 double result = 0.0;
142 bool valid = false;
143 if (evaluator(ast_)) {
144 result = evaluator.result();
145 valid = true;
146 }
147
148 return std::make_tuple(result, valid);
149 }
150
151
152private:
153
154 typedef std::string::const_iterator iterator_type;
156
157 std::set<std::string> vars_;
158 std::set<std::string> funcs_;
159
160 std::string expr_;
162
164
167 std::string_view op(expr_);
168
169 constexpr std::pair<std::string_view, Expressions::OperatorType_t> op_map[] = {
176 };
177
178 for (const auto& p : op_map) {
179 if (op.find(p.first) != std::string_view::npos) {
180 type_ = p.second;
181 break;
182 }
183 }
184 }
185
186 void parse() {
187 iterator_type iter = expr_.begin();
188 iterator_type end = expr_.end();
189
190 client::error_handler<iterator_type> error_handler(iter, end);
191 client::parser::expression<iterator_type> expression(error_handler);
193 client::code_gen::requirements requirements(error_handler);
194
195 bool success = phrase_parse(iter, end, expression, skipper, ast_);
196
197 if (!success || iter != end) {
198 std::cout << "Parsing failed!" << std::endl;
199 std::string here = (iter != end ? std::string(iter, end): expr_);
200 throw new OptPilotException("Expression::parse()",
201 "Parsing failed here: " + here + "!");
202 }
203
204 // store the functions and variables required to evaluate this
205 // expression
206 if (requirements(ast_)) {
207 vars_ = requirements.variables();
208 funcs_ = requirements.functions();
209 }
210 }
211};
212
213#endif
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
std::map< std::string, client::function::type > functionDictionary_t
Definition Expression.h:55
std::map< std::string, double > variableDictionary_t
Definition Expression.h:54
Representation objects and parsers for attribute expressions.
Definition Expressions.h:64
std::map< std::string, Expressions::Expr_t * > Named_t
type of an expressions with a name
Definition Expression.h:73
Expression Expr_t
type of an expression
Definition Expression.h:62
OperatorType_t
distinguish different constraints
Definition Expression.h:79
std::tuple< double, bool > Result_t
Definition Expression.h:65
std::pair< std::string, Expressions::Expr_t * > SingleNamed_t
Definition Expression.h:76
std::set< std::string > vars_
Definition Expression.h:157
std::set< std::string > funcs_
Definition Expression.h:158
functionDictionary_t known_expr_funcs_
Definition Expression.h:161
virtual ~Expression()
Definition Expression.h:119
Expressions::OperatorType_t type_
Definition Expression.h:163
client::ast::expression ast_
Definition Expression.h:155
std::string::const_iterator iterator_type
Definition Expression.h:154
const std::set< std::string > & getReqFuncs() const
Definition Expression.h:123
void determineConstrOperator()
Definition Expression.h:165
Expressions::OperatorType_t getOpType() const
get operator type present (if expression is constraint)
Definition Expression.h:129
std::string expr_
Definition Expression.h:160
void parse()
Definition Expression.h:186
functionDictionary_t getRegFuncs() const
Definition Expression.h:126
const std::string & toString() const
Definition Expression.h:124
Expressions::Result_t evaluate(const variableDictionary_t &vars)
evaluate an expression given a value dictionary of free variables
Definition Expression.h:132
Expression(std::string expr)
Definition Expression.h:100
Expression(std::string expr, functionDictionary_t known_expr_funcs)
Definition Expression.h:109
const std::set< std::string > & getReqVars() const
Definition Expression.h:122
void registerVariables(std::map< std::string, double > variableDictionary)
Definition evaluator.hpp:61
void registerFunctions(std::map< std::string, client::function::type > functions)
Definition evaluator.hpp:56
std::set< std::string > variables()
std::set< std::string > functions()