OPAL (Object Oriented Parallel Accelerator Library)  2024.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_PHOENIX_STL_TUPLE_H_
28 #define BOOST_RESULT_OF_USE_DECLTYPE
29 
30 #include <boost/math/constants/constants.hpp>
31 #include <boost/phoenix.hpp>
32 #include <boost/spirit/include/qi.hpp>
33 #include <boost/variant.hpp>
34 
35 
36 namespace matheval {
37 
38  namespace detail {
39 
40  namespace qi = boost::spirit::qi;
41  namespace ascii = boost::spirit::ascii;
42 
43  namespace math {
44 
62  template < typename T >
63  T sgn(T x) { return (T{0} < x) - (x < T{0}); }
64 
66  template < typename T >
67  T isnan(T x) { return std::isnan(x); }
68 
70  template < typename T >
71  T isinf(T x) { return std::isinf(x); }
72 
74  template < typename T >
75  T deg(T x) { return x*boost::math::constants::radian<T>(); }
76 
78  template < typename T >
79  T rad(T x) { return x*boost::math::constants::degree<T>(); }
80 
81  }
82 
83  // AST
84 
85  template < typename real_t > struct unary_op;
86  template < typename real_t > struct binary_op;
87 
88  struct nil {};
89 
95  template < typename real_t >
96  struct expr_ast
97  {
98  using tree_t = boost::variant<
99  nil // can't happen!
100  , real_t
101  , std::string
102  , boost::recursive_wrapper<expr_ast<real_t>>
103  , boost::recursive_wrapper<binary_op<real_t>>
104  , boost::recursive_wrapper<unary_op<real_t>>
105  >;
106  public:
115 
121  expr_ast() : tree(nil{}) {}
122 
127  template <typename Expr>
128  expr_ast(Expr other) : tree(std::move(other)) {} // NOLINT
129 
131  expr_ast& operator+=(expr_ast const &rhs);
133  expr_ast& operator-=(expr_ast const &rhs);
135  expr_ast& operator*=(expr_ast const &rhs);
137  expr_ast& operator/=(expr_ast const &rhs);
138  };
139 
141  template < typename real_t >
142  struct unary_op
143  {
145  using op_t = std::function<real_t(real_t)>;
146 
149  : op(std::move(op)), rhs(std::move(rhs))
150  {}
151 
156  };
157 
159  template < typename real_t >
160  struct binary_op
161  {
163  using op_t = std::function<real_t(real_t,real_t)>;
164 
167  : op(std::move(op)), lhs(std::move(lhs)), rhs(std::move(rhs))
168  {}
169 
176  };
177 
178  template < typename real_t >
180  {
181  tree = binary_op<real_t>(std::plus<real_t>{}, tree, rhs);
182  return *this;
183  }
184  template < typename real_t >
186  {
187  tree = binary_op<real_t>(std::minus<real_t>{}, tree, rhs);
188  return *this;
189  }
190  template < typename real_t >
192  {
193  tree = binary_op<real_t>(std::multiplies<real_t>{}, tree, rhs);
194  return *this;
195  }
196  template < typename real_t >
198  {
199  tree = binary_op<real_t>(std::divides<real_t>{}, tree, rhs);
200  return *this;
201  }
202 
208  template < typename real_t >
209  class eval_ast
210  {
211  public:
213  using result_type = real_t;
214 
216  using symbol_table_t = std::map<std::string, result_type>;
217 
222  explicit eval_ast(symbol_table_t sym) : st(std::move(sym)) {}
223 
225  result_type operator()(nil /*unused*/) const { return 0; }
226 
228  result_type operator()(result_type n) const { return n; }
229 
231  result_type operator()(std::string const &c) const
232  {
233  auto it = st.find(c);
234  if (it == st.end()) {
235  throw std::invalid_argument("Unknown variable " + c); // NOLINT
236  }
237  return it->second;
238  }
239 
242  {
243  return boost::apply_visitor(*this, ast.tree);
244  }
245 
248  {
249  return tree.op(
250  boost::apply_visitor(*this, tree.lhs.tree),
251  boost::apply_visitor(*this, tree.rhs.tree)
252  );
253  }
254 
257  {
258  return tree.op(
259  boost::apply_visitor(*this, tree.rhs.tree)
260  );
261  }
262 
263  private:
265  };
266 
267  template <typename T> struct holds_alternative_impl {
268  using result_type = bool;
269 
270  template <typename U> bool operator()(U const & /*unused*/) const {
271  return std::is_same<U, T>::value;
272  }
273  };
274 
275  template <typename T, typename... Ts>
276  bool holds_alternative(boost::variant<Ts...> const &v) {
277  return boost::apply_visitor(holds_alternative_impl<T>(), v);
278  }
279 
280  template <typename real_t> struct ConstantFolder {
283 
285  result_type operator()(nil /*unused*/) const { return 0; }
286 
288  result_type operator()(real_t n) const { return n; }
289 
291  result_type operator()(std::string const &c) const { return c; }
292 
295  return boost::apply_visitor(*this, ast.tree);
296  }
297 
300  auto lhs = boost::apply_visitor(*this, tree.lhs.tree);
301  auto rhs = boost::apply_visitor(*this, tree.rhs.tree);
302 
303  /* If both operands are known, we can directly evaluate the function,
304  * else we just update the children with the new expressions. */
305  if (holds_alternative<real_t>(lhs) && holds_alternative<real_t>(rhs)) {
306  return tree.op(boost::get<real_t>(lhs), boost::get<real_t>(rhs));
307  }
308  return binary_op<real_t>(tree.op, lhs, rhs);
309  }
310 
313  auto rhs = boost::apply_visitor(*this, tree.rhs.tree);
314  /* If the operand is known, we can directly evaluate the function. */
315  if (holds_alternative<real_t>(rhs)) {
316  return tree.op(boost::get<real_t>(rhs));
317  }
318  return unary_op<real_t>(tree.op, rhs);
319  }
320  };
321 
322  // Expressions
323 
325  template < typename real_t >
326  struct unary_expr_ {
328  template < typename T > struct result { using type = T; };
329 
332  expr_ast<real_t> const &rhs) const {
333  return expr_ast<real_t>(unary_op<real_t>(op, rhs));
334  }
335  };
336 
338  template < typename real_t >
339  struct binary_expr_ {
341  template < typename T > struct result { using type = T; };
342 
345  expr_ast<real_t> const &lhs,
346  expr_ast<real_t> const &rhs) const {
347  return expr_ast<real_t>(binary_op<real_t>(op, lhs, rhs));
348  }
349  };
350 
354  template < typename Iterator >
355  void operator()(Iterator first, Iterator last,
356  boost::spirit::info const& info) const {
357  std::stringstream msg;
358  msg << "Expected "
359  << info
360  << " at \""
361  << std::string{first, last}
362  << "\"";
363 
364  throw std::runtime_error(msg.str()); // NOLINT
365  }
366  };
367 
368 
369  // Grammar
370 
372  template < typename real_t, typename Iterator >
373  struct grammar
374  : qi::grammar<
375  Iterator, expr_ast<real_t>(), ascii::space_type
376  >
377  {
378  private:
380  qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> expression;
381  qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> term;
382  qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> factor;
383  qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> primary;
384  qi::rule<Iterator, std::string()> variable;
385  public:
387  struct constant_
388  : boost::spirit::qi::symbols<
389  typename std::iterator_traits<Iterator>::value_type,
390  real_t
391  >
392  {
394  {
395  this->add
396  ("e" , boost::math::constants::e<real_t>() )
397  ("epsilon", std::numeric_limits<real_t>::epsilon())
398  ("phi" , boost::math::constants::phi<real_t>() )
399  ("pi" , boost::math::constants::pi<real_t>() )
400  ;
401  }
402  } constant;
403 
405  struct ufunc_
406  : boost::spirit::qi::symbols<
407  typename std::iterator_traits<Iterator>::value_type,
408  typename unary_op<real_t>::op_t
409  >
410  {
412  {
413  this->add
414  ("abs" , static_cast<real_t(*)(real_t)>(&std::abs ))
415  ("acos" , static_cast<real_t(*)(real_t)>(&std::acos ))
416  ("acosh" , static_cast<real_t(*)(real_t)>(&std::acosh ))
417  ("asin" , static_cast<real_t(*)(real_t)>(&std::asin ))
418  ("asinh" , static_cast<real_t(*)(real_t)>(&std::asinh ))
419  ("atan" , static_cast<real_t(*)(real_t)>(&std::atan ))
420  ("atanh" , static_cast<real_t(*)(real_t)>(&std::atanh ))
421  ("cbrt" , static_cast<real_t(*)(real_t)>(&std::cbrt ))
422  ("ceil" , static_cast<real_t(*)(real_t)>(&std::ceil ))
423  ("cos" , static_cast<real_t(*)(real_t)>(&std::cos ))
424  ("cosh" , static_cast<real_t(*)(real_t)>(&std::cosh ))
425  ("deg2rad", static_cast<real_t(*)(real_t)>(&math::deg ))
426  ("erf" , static_cast<real_t(*)(real_t)>(&std::erf ))
427  ("erfc" , static_cast<real_t(*)(real_t)>(&std::erfc ))
428  ("exp" , static_cast<real_t(*)(real_t)>(&std::exp ))
429  ("exp2" , static_cast<real_t(*)(real_t)>(&std::exp2 ))
430  ("floor" , static_cast<real_t(*)(real_t)>(&std::floor ))
431  ("isinf" , static_cast<real_t(*)(real_t)>(&math::isinf))
432  ("isnan" , static_cast<real_t(*)(real_t)>(&math::isnan))
433  ("log" , static_cast<real_t(*)(real_t)>(&std::log ))
434  ("log2" , static_cast<real_t(*)(real_t)>(&std::log2 ))
435  ("log10" , static_cast<real_t(*)(real_t)>(&std::log10 ))
436  ("rad2deg", static_cast<real_t(*)(real_t)>(&math::rad ))
437  ("round" , static_cast<real_t(*)(real_t)>(&std::round ))
438  ("sgn" , static_cast<real_t(*)(real_t)>(&math::sgn ))
439  ("sin" , static_cast<real_t(*)(real_t)>(&std::sin ))
440  ("sinh" , static_cast<real_t(*)(real_t)>(&std::sinh ))
441  ("sqrt" , static_cast<real_t(*)(real_t)>(&std::sqrt ))
442  ("tan" , static_cast<real_t(*)(real_t)>(&std::tan ))
443  ("tanh" , static_cast<real_t(*)(real_t)>(&std::tanh ))
444  ("tgamma" , static_cast<real_t(*)(real_t)>(&std::tgamma))
445  ;
446  }
447  } ufunc;
448 
450  struct bfunc_
451  : boost::spirit::qi::symbols<
452  typename std::iterator_traits<Iterator>::value_type,
453  typename binary_op<real_t>::op_t
454  >
455  {
457  {
458  this->add
459  ("atan2", static_cast<real_t(*)(real_t,real_t)>(&std::atan2))
460  ("max" , static_cast<real_t(*)(real_t,real_t)>(&std::fmax ))
461  ("min" , static_cast<real_t(*)(real_t,real_t)>(&std::fmin ))
462  ("pow" , static_cast<real_t(*)(real_t,real_t)>(&std::pow ))
463  ;
464  }
465  } bfunc;
466 
468  grammar() : grammar::base_type(expression)
469  {
470  using boost::spirit::qi::real_parser;
471  using boost::spirit::qi::real_policies;
472  real_parser<real_t,real_policies<real_t>> real;
473 
474  using boost::spirit::lexeme;
475  using boost::spirit::qi::_1;
476  using boost::spirit::qi::_2;
477  using boost::spirit::qi::_3;
478  using boost::spirit::qi::_4;
479  using boost::spirit::qi::_val;
481  using boost::spirit::qi::alnum;
482  using boost::spirit::qi::raw;
483 
484  boost::phoenix::function<unary_expr_<real_t>> unary_expr;
485  boost::phoenix::function<binary_expr_<real_t>> binary_expr;
486 
487  auto fmod = static_cast<real_t(*)(real_t,real_t)>(&std::fmod);
488  auto pow = static_cast<real_t(*)(real_t,real_t)>(&std::pow);
489 
490  expression =
491  term [_val = _1]
492  >> *( ('+' > term [_val += _1])
493  | ('-' > term [_val -= _1])
494  )
495  ;
496 
497  term =
498  factor [_val = _1]
499  >> *( ('*' > factor [_val *= _1])
500  | ('/' > factor [_val /= _1])
501  | ('%' > factor [_val = binary_expr(fmod, _val, _1)])
502  )
503  ;
504 
505  factor =
506  primary [_val = _1]
507  >> *( ("**" > factor [_val = binary_expr(pow, _val, _1)])
508  )
509  ;
510 
511  variable =
512  raw[lexeme[alpha >> *(alnum | '_')]];
513 
514  primary =
515  real [_val = _1]
516  | ('(' > expression [_val = _1] > ')')
517  | ('-' > primary [_val = unary_expr(std::negate<real_t>{}, _1)])
518  | ('+' > primary [_val = _1])
519  | (bfunc > '(' > expression > ',' > expression > ')')
520  [_val = binary_expr(_1, _2, _3)]
521  | (ufunc > '(' > expression > ')')
522  [_val = unary_expr(_1, _2)]
523  | constant [_val = _1]
524  | variable [_val = _1]
525  ;
526 
527  expression.name("expression");
528  term.name("term");
529  factor.name("factor");
530  variable.name("variable");
531  primary.name("primary");
532 
533  using boost::spirit::qi::fail;
534  using boost::spirit::qi::on_error;
535  using boost::phoenix::bind;
536  using boost::phoenix::ref;
537 
538  on_error<fail>
539  (
540  expression,
541  bind(ref(err_handler), _3, _2, _4)
542  );
543  }
544  };
545 
554  template <typename real_t, typename Iterator>
555  detail::expr_ast<real_t> parse(Iterator first, Iterator last) {
556  static detail::grammar<real_t, Iterator> const g;
557 
558  auto ast = detail::expr_ast<real_t>{};
559 
560  bool r = qi::phrase_parse(first, last, g, ascii::space, ast);
561 
562  if (!r || first != last) {
563  std::string rest(first, last);
564  throw std::runtime_error("Parsing failed at " + rest); // NOLINT
565  }
566 
567  return ast;
568  }
569 
570  } // namespace detail
571 
572 
580  template < typename real_t >
581  class Parser
582  {
584  public:
593  template < typename Iterator >
594  void parse(Iterator first, Iterator last)
595  {
596  ast = detail::parse<real_t>(first, last);
597  }
598 
600  void parse(std::string const &str)
601  {
602  parse(str.begin(), str.end());
603  }
604 
605  void optimize() {
606  ast.tree = boost::apply_visitor(detail::ConstantFolder<real_t>{}, ast.tree);
607  }
608 
614  {
615  detail::eval_ast<real_t> solver(st);
616  return solver(ast);
617  }
618  };
619 
620 
630  template < typename real_t, typename Iterator >
631  real_t parse(Iterator first, Iterator last,
632  typename detail::eval_ast<real_t>::symbol_table_t const &st)
633  {
634  Parser<real_t> parser;
635  parser.parse(first, last);
636  return parser.evaluate(st);
637  }
638 
640  template < typename real_t >
641  real_t parse(std::string const &str,
642  typename detail::eval_ast<real_t>::symbol_table_t const &st)
643  {
644  return parse<real_t>(str.begin(), str.end(), st);
645  }
646 
647 } // namespace matheval
Tps< T > sinh(const Tps< T > &x)
Hyperbolic sine.
Definition: TpsMath.h:204
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
Error handler for expectation errors.
Definition: matheval.hpp:352
std::map< std::string, result_type > symbol_table_t
Type of the symbol table.
Definition: matheval.hpp:216
Binary expression functor.
Definition: matheval.hpp:339
expr_ast & operator+=(expr_ast const &rhs)
Add a tree.
Definition: matheval.hpp:179
matheval::detail::grammar::constant_ constant
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR DISTRIBUTION AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The refers to any such program or and a work based on the Program means either the Program or any derivative work under copyright a work containing the Program or a portion of it
Definition: LICENSE:43
Tps< T > tan(const Tps< T > &x)
Tangent.
Definition: TpsMath.h:147
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:613
T sgn(T x)
Sign function.
Definition: matheval.hpp:63
T rad(T x)
Convert degrees to radians.
Definition: matheval.hpp:79
result_type operator()(expr_ast< real_t > const &ast) const
Recursively evaluate the AST.
Definition: matheval.hpp:241
result_type operator()(result_type n) const
Numbers evaluate to themselves.
Definition: matheval.hpp:228
qi::rule< Iterator, expr_ast< real_t >), ascii::space_type > factor
Definition: matheval.hpp:382
op_t op
Stored operator.
Definition: matheval.hpp:153
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
matheval::detail::grammar::ufunc_ ufunc
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:105
FTps< T, N > erf(const FTps< T, N > &x, int trunc=(FTps< T, N >::EXACT))
Error function.
Definition: FTpsMath.h:385
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:166
result_type operator()(unary_op< real_t > const &tree) const
Evaluate a unary operator and optionally recurse its operand.
Definition: matheval.hpp:256
result_type operator()(nil) const
Empty nodes in the tree evaluate to 0.
Definition: matheval.hpp:225
expr_ast< real_t > rhs
Stored argument tree of second argument.
Definition: matheval.hpp:175
expr_ast()
Default constructor.
Definition: matheval.hpp:121
tree_t tree
AST storage.
Definition: matheval.hpp:114
Abstract Syntax Tree.
Definition: matheval.hpp:96
result_type operator()(unary_op< real_t > const &tree) const
Evaluate a unary operator and optionally recurse its operand.
Definition: matheval.hpp:312
detail::expr_ast< real_t > ast
Definition: matheval.hpp:583
result_type operator()(std::string const &c) const
Variables evaluate to their value in the symbol table.
Definition: matheval.hpp:231
bool holds_alternative(boost::variant< Ts...> const &v)
Definition: matheval.hpp:276
symbol table for unary functions like &quot;abs&quot;
Definition: matheval.hpp:405
Tps< T > exp(const Tps< T > &x)
Exponential.
Definition: TpsMath.h:165
qi::rule< Iterator, expr_ast< real_t >), ascii::space_type > term
Definition: matheval.hpp:381
bool info
Info flag.
Definition: Options.cpp:28
expectation_handler err_handler
Definition: matheval.hpp:379
Store a unary operator and its argument tree.
Definition: matheval.hpp:85
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< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
Definition: PETE.h:727
detail::expr_ast< real_t > parse(Iterator first, Iterator last)
Parse an expression.
Definition: matheval.hpp:555
result_type operator()(binary_op< real_t > const &tree) const
Evaluate a binary operator and optionally recurse its operands.
Definition: matheval.hpp:299
expr_ast & operator-=(expr_ast const &rhs)
subtract a tree
Definition: matheval.hpp:185
Tps< T > tanh(const Tps< T > &x)
Hyperbolic tangent.
Definition: TpsMath.h:240
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:344
eval_ast(symbol_table_t sym)
Constructor.
Definition: matheval.hpp:222
std::function< real_t(real_t)> op_t
Signature of a unary operator: op(x)
Definition: matheval.hpp:145
expr_ast(Expr other)
Copy constructor.
Definition: matheval.hpp:128
op_t op
Stored operator.
Definition: matheval.hpp:171
void parse(std::string const &str)
Definition: matheval.hpp:600
result_type operator()(std::string const &c) const
Variables do not evaluate.
Definition: matheval.hpp:291
PETE_TUTree< FnLog10, typename T::PETE_Expr_t > log10(const PETE_Expr< T > &l)
Definition: PETE.h:735
Unary expression functor.
Definition: matheval.hpp:326
symbol table for binary functions like &quot;pow&quot;
Definition: matheval.hpp:450
result_type operator()(real_t n) const
Numbers evaluate to themselves.
Definition: matheval.hpp:288
Class interface.
Definition: matheval.hpp:581
expr_ast & operator/=(expr_ast const &rhs)
Divide by a tree.
Definition: matheval.hpp:197
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
FTps< T, N > erfc(const FTps< T, N > &x, int trunc=(FTps< T, N >::EXACT))
Complementary error function.
Definition: FTpsMath.h:414
PETE_TUTree< FnArcCos, typename T::PETE_Expr_t > acos(const PETE_Expr< T > &l)
Definition: PETE.h:725
real_t result_type
Necessary typedef for boost::apply_visitor
Definition: matheval.hpp:213
constexpr double alpha
The fine structure constant, no dimension.
Definition: Physics.h:72
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
Make boost::phoenix::function happy.
Definition: matheval.hpp:341
Store a binary operator and its argument trees.
Definition: matheval.hpp:86
T deg(T x)
Convert radians to degrees.
Definition: matheval.hpp:75
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:331
grammar()
Constructor builds the grammar.
Definition: matheval.hpp:468
std::function< real_t(real_t, real_t)> op_t
Signature of a binary operator: op(x,y)
Definition: matheval.hpp:163
typename expr_ast< real_t >::tree_t result_type
Necessary typedef for boost::apply_visitor
Definition: matheval.hpp:282
Expression Grammar.
Definition: matheval.hpp:373
qi::rule< Iterator, std::string()> variable
Definition: matheval.hpp:384
T isnan(T x)
isnan function with adjusted return type
Definition: matheval.hpp:67
qi::rule< Iterator, expr_ast< real_t >), ascii::space_type > primary
Definition: matheval.hpp:383
PETE_TUTree< FnCeil, typename T::PETE_Expr_t > ceil(const PETE_Expr< T > &l)
Definition: PETE.h:728
matheval::detail::grammar::bfunc_ bfunc
expr_ast< real_t > rhs
Stored argument tree.
Definition: matheval.hpp:155
real_t parse(Iterator first, Iterator last, typename detail::eval_ast< real_t >::symbol_table_t const &st)
Convenience function.
Definition: matheval.hpp:631
PETE_TUTree< FnArcSin, typename T::PETE_Expr_t > asin(const PETE_Expr< T > &l)
Definition: PETE.h:726
result_type operator()(nil) const
Empty nodes in the tree evaluate to 0.
Definition: matheval.hpp:285
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
Tps< T > cosh(const Tps< T > &x)
Hyperbolic cosine.
Definition: TpsMath.h:222
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:733
Evaluate the Abstract Syntax Tree.
Definition: matheval.hpp:209
unary_op(op_t op, expr_ast< real_t > rhs)
Save the operator and the argument tree.
Definition: matheval.hpp:148
Make boost::phoenix::function happy.
Definition: matheval.hpp:328
expr_ast & operator*=(expr_ast const &rhs)
Multiply by a tree.
Definition: matheval.hpp:191
void parse(Iterator first, Iterator last)
Parse an expression.
Definition: matheval.hpp:594
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
qi::rule< Iterator, expr_ast< real_t >), ascii::space_type > expression
Definition: matheval.hpp:380
result_type operator()(expr_ast< real_t > const &ast) const
Recursively evaluate the AST.
Definition: matheval.hpp:294
symbol table for constants like &quot;pi&quot;
Definition: matheval.hpp:387
result_type operator()(binary_op< real_t > const &tree) const
Evaluate a binary operator and optionally recurse its operands.
Definition: matheval.hpp:247
void operator()(Iterator first, Iterator last, boost::spirit::info const &info) const
Throw an exception saying where and why parsing failed.
Definition: matheval.hpp:355
T isinf(T x)
isinf function with adjusted return type
Definition: matheval.hpp:71
expr_ast< real_t > lhs
Stored argument tree of first argument.
Definition: matheval.hpp:173