OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
matheval.hpp
Go to the documentation of this file.
1// Copyright (C) 2011-2013 Rhys Ulerich
2// Copyright (C) ??? Martin Bauer
3// Copyright (C) 2017 Henri Menke
4//
5// This code borrows heavily from code written by Rhys Ulerich and
6// Martin Bauer. They licensed it under the Mozilla Public License,
7// v. 2.0 and the GNU General Public License (no version info),
8// respectively. I believe that I have made enough contributions and
9// altered this code far enough from the originals that I can
10// relicense it under the Boost Software License.
11//
12// Distributed under the Boost Software License, Version 1.0. (See
13// accompanying file LICENSE_1_0.txt or copy at
14// http://www.boost.org/LICENSE_1_0.txt)
15#pragma once
16
17#include <algorithm>
18#include <cmath>
19#include <functional>
20#include <iterator>
21#include <limits>
22#include <map>
23#include <sstream>
24#include <stdexcept>
25#include <string>
26
27#define BOOST_RESULT_OF_USE_DECLTYPE
28#define BOOST_SPIRIT_USE_PHOENIX_V3
29#include <boost/math/constants/constants.hpp>
30#include <boost/spirit/include/phoenix.hpp>
31#include <boost/spirit/include/qi.hpp>
32#include <boost/variant.hpp>
33
34
35namespace matheval {
36
37 namespace detail {
38
39 namespace qi = boost::spirit::qi;
40 namespace ascii = boost::spirit::ascii;
41
42 namespace math {
43
61 template < typename T >
62 T sgn(T x) { return (T{0} < x) - (x < T{0}); }
63
65 template < typename T >
66 T isnan(T x) { return std::isnan(x); }
67
69 template < typename T >
70 T isinf(T x) { return std::isinf(x); }
71
73 template < typename T >
74 T deg(T x) { return x*boost::math::constants::radian<T>(); }
75
77 template < typename T >
78 T rad(T x) { return x*boost::math::constants::degree<T>(); }
79
80 }
81
82 // AST
83
84 template < typename real_t > struct unary_op;
85 template < typename real_t > struct binary_op;
86
87 struct nil {};
88
94 template < typename real_t >
95 struct expr_ast
96 {
97 using tree_t = boost::variant<
98 nil // can't happen!
99 , real_t
100 , std::string
101 , boost::recursive_wrapper<expr_ast<real_t>>
102 , boost::recursive_wrapper<binary_op<real_t>>
103 , boost::recursive_wrapper<unary_op<real_t>>
104 >;
105 public:
114
120 expr_ast() : tree(nil{}) {}
121
126 template <typename Expr>
127 expr_ast(Expr other) : tree(std::move(other)) {} // NOLINT
128
130 expr_ast& operator+=(expr_ast const &rhs);
132 expr_ast& operator-=(expr_ast const &rhs);
134 expr_ast& operator*=(expr_ast const &rhs);
136 expr_ast& operator/=(expr_ast const &rhs);
137 };
138
140 template < typename real_t >
141 struct unary_op
142 {
144 using op_t = std::function<real_t(real_t)>;
145
148 : op(std::move(op)), rhs(std::move(rhs))
149 {}
150
155 };
156
158 template < typename real_t >
160 {
162 using op_t = std::function<real_t(real_t,real_t)>;
163
166 : op(std::move(op)), lhs(std::move(lhs)), rhs(std::move(rhs))
167 {}
168
175 };
176
177 template < typename real_t >
179 {
180 tree = binary_op<real_t>(std::plus<real_t>{}, tree, rhs);
181 return *this;
182 }
183 template < typename real_t >
185 {
186 tree = binary_op<real_t>(std::minus<real_t>{}, tree, rhs);
187 return *this;
188 }
189 template < typename real_t >
191 {
192 tree = binary_op<real_t>(std::multiplies<real_t>{}, tree, rhs);
193 return *this;
194 }
195 template < typename real_t >
197 {
198 tree = binary_op<real_t>(std::divides<real_t>{}, tree, rhs);
199 return *this;
200 }
201
207 template < typename real_t >
209 {
210 public:
212 using result_type = real_t;
213
215 using symbol_table_t = std::map<std::string, result_type>;
216
221 explicit eval_ast(symbol_table_t sym) : st(std::move(sym)) {}
222
224 result_type operator()(nil /*unused*/) const { return 0; }
225
228
230 result_type operator()(std::string const &c) const
231 {
232 auto it = st.find(c);
233 if (it == st.end()) {
234 throw std::invalid_argument("Unknown variable " + c); // NOLINT
235 }
236 return it->second;
237 }
238
241 {
242 return boost::apply_visitor(*this, ast.tree);
243 }
244
247 {
248 return tree.op(
249 boost::apply_visitor(*this, tree.lhs.tree),
250 boost::apply_visitor(*this, tree.rhs.tree)
251 );
252 }
253
256 {
257 return tree.op(
258 boost::apply_visitor(*this, tree.rhs.tree)
259 );
260 }
261
262 private:
264 };
265
266 template <typename T> struct holds_alternative_impl {
267 using result_type = bool;
268
269 template <typename U> bool operator()(U const & /*unused*/) const {
270 return std::is_same<U, T>::value;
271 }
272 };
273
274 template <typename T, typename... Ts>
275 bool holds_alternative(boost::variant<Ts...> const &v) {
276 return boost::apply_visitor(holds_alternative_impl<T>(), v);
277 }
278
279 template <typename real_t> struct ConstantFolder {
282
284 result_type operator()(nil /*unused*/) const { return 0; }
285
287 result_type operator()(real_t n) const { return n; }
288
290 result_type operator()(std::string const &c) const { return c; }
291
294 return boost::apply_visitor(*this, ast.tree);
295 }
296
299 auto lhs = boost::apply_visitor(*this, tree.lhs.tree);
300 auto rhs = boost::apply_visitor(*this, tree.rhs.tree);
301
302 /* If both operands are known, we can directly evaluate the function,
303 * else we just update the children with the new expressions. */
304 if (holds_alternative<real_t>(lhs) && holds_alternative<real_t>(rhs)) {
305 return tree.op(boost::get<real_t>(lhs), boost::get<real_t>(rhs));
306 }
307 return binary_op<real_t>(tree.op, lhs, rhs);
308 }
309
312 auto rhs = boost::apply_visitor(*this, tree.rhs.tree);
313 /* If the operand is known, we can directly evaluate the function. */
314 if (holds_alternative<real_t>(rhs)) {
315 return tree.op(boost::get<real_t>(rhs));
316 }
317 return unary_op<real_t>(tree.op, rhs);
318 }
319 };
320
321 // Expressions
322
324 template < typename real_t >
325 struct unary_expr_ {
327 template < typename T > struct result { using type = T; };
328
331 expr_ast<real_t> const &rhs) const {
332 return expr_ast<real_t>(unary_op<real_t>(op, rhs));
333 }
334 };
335
337 template < typename real_t >
340 template < typename T > struct result { using type = T; };
341
344 expr_ast<real_t> const &lhs,
345 expr_ast<real_t> const &rhs) const {
346 return expr_ast<real_t>(binary_op<real_t>(op, lhs, rhs));
347 }
348 };
349
353 template < typename Iterator >
354 void operator()(Iterator first, Iterator last,
355 boost::spirit::info const& info) const {
356 std::stringstream msg;
357 msg << "Expected "
358 << info
359 << " at \""
360 << std::string{first, last}
361 << "\"";
362
363 throw std::runtime_error(msg.str()); // NOLINT
364 }
365 };
366
367
368 // Grammar
369
371 template < typename real_t, typename Iterator >
372 struct grammar
373 : qi::grammar<
374 Iterator, expr_ast<real_t>(), ascii::space_type
375 >
376 {
377 private:
379 qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> expression;
380 qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> term;
381 qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> factor;
382 qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> primary;
383 qi::rule<Iterator, std::string()> variable;
384 public:
387 : boost::spirit::qi::symbols<
388 typename std::iterator_traits<Iterator>::value_type,
389 real_t
390 >
391 {
393 {
394 this->add
395 ("e" , boost::math::constants::e<real_t>() )
396 ("epsilon", std::numeric_limits<real_t>::epsilon())
397 ("phi" , boost::math::constants::phi<real_t>() )
398 ("pi" , boost::math::constants::pi<real_t>() )
399 ;
400 }
402
404 struct ufunc_
405 : boost::spirit::qi::symbols<
406 typename std::iterator_traits<Iterator>::value_type,
407 typename unary_op<real_t>::op_t
408 >
409 {
411 {
412 this->add
413 ("abs" , static_cast<real_t(*)(real_t)>(&std::abs ))
414 ("acos" , static_cast<real_t(*)(real_t)>(&std::acos ))
415 ("acosh" , static_cast<real_t(*)(real_t)>(&std::acosh ))
416 ("asin" , static_cast<real_t(*)(real_t)>(&std::asin ))
417 ("asinh" , static_cast<real_t(*)(real_t)>(&std::asinh ))
418 ("atan" , static_cast<real_t(*)(real_t)>(&std::atan ))
419 ("atanh" , static_cast<real_t(*)(real_t)>(&std::atanh ))
420 ("cbrt" , static_cast<real_t(*)(real_t)>(&std::cbrt ))
421 ("ceil" , static_cast<real_t(*)(real_t)>(&std::ceil ))
422 ("cos" , static_cast<real_t(*)(real_t)>(&std::cos ))
423 ("cosh" , static_cast<real_t(*)(real_t)>(&std::cosh ))
424 ("deg2rad", static_cast<real_t(*)(real_t)>(&math::deg ))
425 ("erf" , static_cast<real_t(*)(real_t)>(&std::erf ))
426 ("erfc" , static_cast<real_t(*)(real_t)>(&std::erfc ))
427 ("exp" , static_cast<real_t(*)(real_t)>(&std::exp ))
428 ("exp2" , static_cast<real_t(*)(real_t)>(&std::exp2 ))
429 ("floor" , static_cast<real_t(*)(real_t)>(&std::floor ))
430 ("isinf" , static_cast<real_t(*)(real_t)>(&math::isinf))
431 ("isnan" , static_cast<real_t(*)(real_t)>(&math::isnan))
432 ("log" , static_cast<real_t(*)(real_t)>(&std::log ))
433 ("log2" , static_cast<real_t(*)(real_t)>(&std::log2 ))
434 ("log10" , static_cast<real_t(*)(real_t)>(&std::log10 ))
435 ("rad2deg", static_cast<real_t(*)(real_t)>(&math::rad ))
436 ("round" , static_cast<real_t(*)(real_t)>(&std::round ))
437 ("sgn" , static_cast<real_t(*)(real_t)>(&math::sgn ))
438 ("sin" , static_cast<real_t(*)(real_t)>(&std::sin ))
439 ("sinh" , static_cast<real_t(*)(real_t)>(&std::sinh ))
440 ("sqrt" , static_cast<real_t(*)(real_t)>(&std::sqrt ))
441 ("tan" , static_cast<real_t(*)(real_t)>(&std::tan ))
442 ("tanh" , static_cast<real_t(*)(real_t)>(&std::tanh ))
443 ("tgamma" , static_cast<real_t(*)(real_t)>(&std::tgamma))
444 ;
445 }
447
449 struct bfunc_
450 : boost::spirit::qi::symbols<
451 typename std::iterator_traits<Iterator>::value_type,
452 typename binary_op<real_t>::op_t
453 >
454 {
456 {
457 this->add
458 ("atan2", static_cast<real_t(*)(real_t,real_t)>(&std::atan2))
459 ("max" , static_cast<real_t(*)(real_t,real_t)>(&std::fmax ))
460 ("min" , static_cast<real_t(*)(real_t,real_t)>(&std::fmin ))
461 ("pow" , static_cast<real_t(*)(real_t,real_t)>(&std::pow ))
462 ;
463 }
465
467 grammar() : grammar::base_type(expression)
468 {
469 using boost::spirit::qi::real_parser;
470 using boost::spirit::qi::real_policies;
471 real_parser<real_t,real_policies<real_t>> real;
472
473 using boost::spirit::lexeme;
474 using boost::spirit::qi::_1;
475 using boost::spirit::qi::_2;
476 using boost::spirit::qi::_3;
477 using boost::spirit::qi::_4;
478 using boost::spirit::qi::_val;
480 using boost::spirit::qi::alnum;
481 using boost::spirit::qi::raw;
482
483 boost::phoenix::function<unary_expr_<real_t>> unary_expr;
484 boost::phoenix::function<binary_expr_<real_t>> binary_expr;
485
486 auto fmod = static_cast<real_t(*)(real_t,real_t)>(&std::fmod);
487 auto pow = static_cast<real_t(*)(real_t,real_t)>(&std::pow);
488
489 expression =
490 term [_val = _1]
491 >> *( ('+' > term [_val += _1])
492 | ('-' > term [_val -= _1])
493 )
494 ;
495
496 term =
497 factor [_val = _1]
498 >> *( ('*' > factor [_val *= _1])
499 | ('/' > factor [_val /= _1])
500 | ('%' > factor [_val = binary_expr(fmod, _val, _1)])
501 )
502 ;
503
504 factor =
505 primary [_val = _1]
506 >> *( ("**" > factor [_val = binary_expr(pow, _val, _1)])
507 )
508 ;
509
510 variable =
511 raw[lexeme[alpha >> *(alnum | '_')]];
512
513 primary =
514 real [_val = _1]
515 | ('(' > expression [_val = _1] > ')')
516 | ('-' > primary [_val = unary_expr(std::negate<real_t>{}, _1)])
517 | ('+' > primary [_val = _1])
518 | (bfunc > '(' > expression > ',' > expression > ')')
519 [_val = binary_expr(_1, _2, _3)]
520 | (ufunc > '(' > expression > ')')
521 [_val = unary_expr(_1, _2)]
522 | constant [_val = _1]
523 | variable [_val = _1]
524 ;
525
526 expression.name("expression");
527 term.name("term");
528 factor.name("factor");
529 variable.name("variable");
530 primary.name("primary");
531
532 using boost::spirit::qi::fail;
533 using boost::spirit::qi::on_error;
534 using boost::phoenix::bind;
536
537 on_error<fail>
538 (
540 bind(ref(err_handler), _3, _2, _4)
541 );
542 }
543 };
544
553 template <typename real_t, typename Iterator>
554 detail::expr_ast<real_t> parse(Iterator first, Iterator last) {
556
557 auto ast = detail::expr_ast<real_t>{};
558
559 bool r = qi::phrase_parse(first, last, g, ascii::space, ast);
560
561 if (!r || first != last) {
562 std::string rest(first, last);
563 throw std::runtime_error("Parsing failed at " + rest); // NOLINT
564 }
565
566 return ast;
567 }
568
569 } // namespace detail
570
571
579 template < typename real_t >
580 class Parser
581 {
583 public:
592 template < typename Iterator >
593 void parse(Iterator first, Iterator last)
594 {
595 ast = detail::parse<real_t>(first, last);
596 }
597
599 void parse(std::string const &str)
600 {
601 parse(str.begin(), str.end());
602 }
603
604 void optimize() {
605 ast.tree = boost::apply_visitor(detail::ConstantFolder<real_t>{}, ast.tree);
606 }
607
613 {
614 detail::eval_ast<real_t> solver(st);
615 return solver(ast);
616 }
617 };
618
619
629 template < typename real_t, typename Iterator >
630 real_t parse(Iterator first, Iterator last,
632 {
633 Parser<real_t> parser;
634 parser.parse(first, last);
635 return parser.evaluate(st);
636 }
637
639 template < typename real_t >
640 real_t parse(std::string const &str,
642 {
643 return parse<real_t>(str.begin(), str.end(), st);
644 }
645
646} // namespace matheval
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
FTps< T, N > erf(const FTps< T, N > &x, int trunc=(FTps< T, N >::EXACT))
Error function.
Definition: FTpsMath.h:385
FTps< T, N > erfc(const FTps< T, N > &x, int trunc=(FTps< T, N >::EXACT))
Complementary error function.
Definition: FTpsMath.h:414
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Tps< T > cosh(const Tps< T > &x)
Hyperbolic cosine.
Definition: TpsMath.h:222
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
Tps< T > tan(const Tps< T > &x)
Tangent.
Definition: TpsMath.h:147
Tps< T > exp(const Tps< T > &x)
Exponential.
Definition: TpsMath.h:165
Tps< T > sinh(const Tps< T > &x)
Hyperbolic sine.
Definition: TpsMath.h:204
Tps< T > tanh(const Tps< T > &x)
Hyperbolic tangent.
Definition: TpsMath.h:240
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
PETE_TUTree< FnLog10, typename T::PETE_Expr_t > log10(const PETE_Expr< T > &l)
Definition: PETE.h:735
PETE_TUTree< FnCeil, typename T::PETE_Expr_t > ceil(const PETE_Expr< T > &l)
Definition: PETE.h:728
PETE_TUTree< FnArcCos, typename T::PETE_Expr_t > acos(const PETE_Expr< T > &l)
Definition: PETE.h:725
PETE_TUTree< FnArcSin, typename T::PETE_Expr_t > asin(const PETE_Expr< T > &l)
Definition: PETE.h:726
PETE_TUTree< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
Definition: PETE.h:727
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:733
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
py::list function(PolynomialPatch *patch, py::list point)
constexpr double alpha
The fine structure constant, no dimension.
Definition: Physics.h:72
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
real_t parse(Iterator first, Iterator last, typename detail::eval_ast< real_t >::symbol_table_t const &st)
Convenience function.
Definition: matheval.hpp:630
detail::expr_ast< real_t > parse(Iterator first, Iterator last)
Parse an expression.
Definition: matheval.hpp:554
bool holds_alternative(boost::variant< Ts... > const &v)
Definition: matheval.hpp:275
T isinf(T x)
isinf function with adjusted return type
Definition: matheval.hpp:70
T isnan(T x)
isnan function with adjusted return type
Definition: matheval.hpp:66
T rad(T x)
Convert degrees to radians.
Definition: matheval.hpp:78
T sgn(T x)
Sign function.
Definition: matheval.hpp:62
T deg(T x)
Convert radians to degrees.
Definition: matheval.hpp:74
bool info
Info flag.
Definition: Options.cpp:28
Store a unary operator and its argument tree.
Definition: matheval.hpp:142
op_t op
Stored operator.
Definition: matheval.hpp:152
expr_ast< real_t > rhs
Stored argument tree.
Definition: matheval.hpp:154
unary_op(op_t op, expr_ast< real_t > rhs)
Save the operator and the argument tree.
Definition: matheval.hpp:147
std::function< real_t(real_t)> op_t
Signature of a unary operator: op(x)
Definition: matheval.hpp:144
Store a binary operator and its argument trees.
Definition: matheval.hpp:160
expr_ast< real_t > lhs
Stored argument tree of first argument.
Definition: matheval.hpp:172
binary_op(op_t op, expr_ast< real_t > lhs, expr_ast< real_t > rhs)
Save the operator and the argument trees.
Definition: matheval.hpp:165
std::function< real_t(real_t, real_t)> op_t
Signature of a binary operator: op(x,y)
Definition: matheval.hpp:162
op_t op
Stored operator.
Definition: matheval.hpp:170
expr_ast< real_t > rhs
Stored argument tree of second argument.
Definition: matheval.hpp:174
Abstract Syntax Tree.
Definition: matheval.hpp:96
expr_ast & operator-=(expr_ast const &rhs)
subtract a tree
Definition: matheval.hpp:184
expr_ast()
Default constructor.
Definition: matheval.hpp:120
boost::variant< nil, real_t, std::string, boost::recursive_wrapper< expr_ast< real_t > >, boost::recursive_wrapper< binary_op< real_t > >, boost::recursive_wrapper< unary_op< real_t > > > tree_t
Definition: matheval.hpp:104
expr_ast & operator/=(expr_ast const &rhs)
Divide by a tree.
Definition: matheval.hpp:196
expr_ast & operator*=(expr_ast const &rhs)
Multiply by a tree.
Definition: matheval.hpp:190
expr_ast & operator+=(expr_ast const &rhs)
Add a tree.
Definition: matheval.hpp:178
expr_ast(Expr other)
Copy constructor.
Definition: matheval.hpp:127
tree_t tree
AST storage.
Definition: matheval.hpp:113
Evaluate the Abstract Syntax Tree.
Definition: matheval.hpp:209
real_t result_type
Necessary typedef for boost::apply_visitor
Definition: matheval.hpp:212
result_type operator()(binary_op< real_t > const &tree) const
Evaluate a binary operator and optionally recurse its operands.
Definition: matheval.hpp:246
result_type operator()(result_type n) const
Numbers evaluate to themselves.
Definition: matheval.hpp:227
result_type operator()(nil) const
Empty nodes in the tree evaluate to 0.
Definition: matheval.hpp:224
result_type operator()(expr_ast< real_t > const &ast) const
Recursively evaluate the AST.
Definition: matheval.hpp:240
std::map< std::string, result_type > symbol_table_t
Type of the symbol table.
Definition: matheval.hpp:215
result_type operator()(unary_op< real_t > const &tree) const
Evaluate a unary operator and optionally recurse its operand.
Definition: matheval.hpp:255
eval_ast(symbol_table_t sym)
Constructor.
Definition: matheval.hpp:221
result_type operator()(std::string const &c) const
Variables evaluate to their value in the symbol table.
Definition: matheval.hpp:230
result_type operator()(binary_op< real_t > const &tree) const
Evaluate a binary operator and optionally recurse its operands.
Definition: matheval.hpp:298
result_type operator()(nil) const
Empty nodes in the tree evaluate to 0.
Definition: matheval.hpp:284
result_type operator()(unary_op< real_t > const &tree) const
Evaluate a unary operator and optionally recurse its operand.
Definition: matheval.hpp:311
result_type operator()(real_t n) const
Numbers evaluate to themselves.
Definition: matheval.hpp:287
typename expr_ast< real_t >::tree_t result_type
Necessary typedef for boost::apply_visitor
Definition: matheval.hpp:281
result_type operator()(std::string const &c) const
Variables do not evaluate.
Definition: matheval.hpp:290
result_type operator()(expr_ast< real_t > const &ast) const
Recursively evaluate the AST.
Definition: matheval.hpp:293
Unary expression functor.
Definition: matheval.hpp:325
expr_ast< real_t > operator()(typename unary_op< real_t >::op_t op, expr_ast< real_t > const &rhs) const
Create a new AST containing the unary function.
Definition: matheval.hpp:330
Make boost::phoenix::function happy.
Definition: matheval.hpp:327
Binary expression functor.
Definition: matheval.hpp:338
expr_ast< real_t > operator()(typename binary_op< real_t >::op_t op, expr_ast< real_t > const &lhs, expr_ast< real_t > const &rhs) const
Create a new AST containing the binary function.
Definition: matheval.hpp:343
Make boost::phoenix::function happy.
Definition: matheval.hpp:340
Error handler for expectation errors.
Definition: matheval.hpp:351
void operator()(Iterator first, Iterator last, boost::spirit::info const &info) const
Throw an exception saying where and why parsing failed.
Definition: matheval.hpp:354
Expression Grammar.
Definition: matheval.hpp:376
grammar()
Constructor builds the grammar.
Definition: matheval.hpp:467
qi::rule< Iterator, expr_ast< real_t >(), ascii::space_type > expression
Definition: matheval.hpp:379
qi::rule< Iterator, expr_ast< real_t >(), ascii::space_type > factor
Definition: matheval.hpp:381
qi::rule< Iterator, expr_ast< real_t >(), ascii::space_type > primary
Definition: matheval.hpp:382
expectation_handler err_handler
Definition: matheval.hpp:378
qi::rule< Iterator, expr_ast< real_t >(), ascii::space_type > term
Definition: matheval.hpp:380
matheval::detail::grammar::ufunc_ ufunc
matheval::detail::grammar::bfunc_ bfunc
matheval::detail::grammar::constant_ constant
qi::rule< Iterator, std::string()> variable
Definition: matheval.hpp:383
symbol table for constants like "pi"
Definition: matheval.hpp:391
symbol table for unary functions like "abs"
Definition: matheval.hpp:409
symbol table for binary functions like "pow"
Definition: matheval.hpp:454
Class interface.
Definition: matheval.hpp:581
void parse(Iterator first, Iterator last)
Parse an expression.
Definition: matheval.hpp:593
detail::expr_ast< real_t > ast
Definition: matheval.hpp:582
void parse(std::string const &str)
Definition: matheval.hpp:599
real_t evaluate(typename detail::eval_ast< real_t >::symbol_table_t const &st)
Evaluate the AST with a given symbol table.
Definition: matheval.hpp:612