OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 
35 namespace 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 >
159  struct binary_op
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 >
208  class eval_ast
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 
227  result_type operator()(result_type n) const { return n; }
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 >
338  struct binary_expr_ {
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:
386  struct constant_
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  }
446  } ufunc;
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  }
464  } bfunc;
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;
535  using boost::phoenix::ref;
536 
537  on_error<fail>
538  (
539  expression,
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) {
555  static detail::grammar<real_t, Iterator> const g;
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,
631  typename detail::eval_ast<real_t>::symbol_table_t const &st)
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,
641  typename detail::eval_ast<real_t>::symbol_table_t const &st)
642  {
643  return parse<real_t>(str.begin(), str.end(), st);
644  }
645 
646 } // namespace matheval
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
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
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)
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< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
Definition: PETE.h:727
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< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:733
constexpr double alpha
The fine structure constant, no dimension.
Definition: Physics.h:78
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:51
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 > primary
Definition: matheval.hpp:382
qi::rule< Iterator, expr_ast< real_t >), ascii::space_type > factor
Definition: matheval.hpp:381
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, expr_ast< real_t >), ascii::space_type > expression
Definition: matheval.hpp:379
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