OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
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 #if defined __clang__
18 # pragma clang diagnostic push
19 # pragma clang diagnostic ignored "-Wunsequenced"
20 #elif defined __GNUC__
21 # pragma GCC diagnostic push
22 # pragma GCC diagnostic ignored "-Wsequence-point"
23 #endif
24 
25 #include <algorithm>
26 #include <cmath>
27 #include <functional>
28 #include <iterator>
29 #include <limits>
30 #include <map>
31 #include <sstream>
32 #include <stdexcept>
33 #include <string>
34 
35 #define BOOST_RESULT_OF_USE_DECLTYPE
36 #define BOOST_SPIRIT_USE_PHOENIX_V3
37 #include <boost/math/constants/constants.hpp>
38 #include <boost/spirit/include/phoenix.hpp>
39 #include <boost/spirit/include/qi.hpp>
40 #include <boost/variant.hpp>
41 
42 
43 namespace matheval {
44 
45  namespace detail {
46 
47  namespace qi = boost::spirit::qi;
48  namespace ascii = boost::spirit::ascii;
49 
50  namespace math {
51 
69  template < typename T >
70  T sgn(T x) { return (T{0} < x) - (x < T{0}); }
71 
73  template < typename T >
74  T isnan(T x) { return std::isnan(x); }
75 
77  template < typename T >
78  T isinf(T x) { return std::isinf(x); }
79 
81  template < typename T >
82  T deg(T x) { return x*boost::math::constants::radian<T>(); }
83 
85  template < typename T >
86  T rad(T x) { return x*boost::math::constants::degree<T>(); }
87 
88  }
89 
90  // AST
91 
92  template < typename real_t > struct unary_op;
93  template < typename real_t > struct binary_op;
94 
95  struct nil {};
96 
102  template < typename real_t >
103  struct expr_ast
104  {
105  using tree_t = boost::variant<
106  nil // can't happen!
107  , real_t
108  , std::string
109  , boost::recursive_wrapper<expr_ast<real_t>>
110  , boost::recursive_wrapper<binary_op<real_t>>
111  , boost::recursive_wrapper<unary_op<real_t>>
112  >;
113  public:
122 
128  expr_ast() : tree(nil{}) {}
129 
134  template <typename Expr>
135  expr_ast(Expr other) : tree(std::move(other)) {} // NOLINT
136 
138  expr_ast& operator+=(expr_ast const &rhs);
140  expr_ast& operator-=(expr_ast const &rhs);
142  expr_ast& operator*=(expr_ast const &rhs);
144  expr_ast& operator/=(expr_ast const &rhs);
145  };
146 
148  template < typename real_t >
149  struct unary_op
150  {
152  using op_t = std::function<real_t(real_t)>;
153 
156  : op(std::move(op)), rhs(std::move(rhs))
157  {}
158 
163  };
164 
166  template < typename real_t >
167  struct binary_op
168  {
170  using op_t = std::function<real_t(real_t,real_t)>;
171 
174  : op(std::move(op)), lhs(std::move(lhs)), rhs(std::move(rhs))
175  {}
176 
183  };
184 
185  template < typename real_t >
187  {
188  tree = binary_op<real_t>(std::plus<real_t>{}, tree, rhs);
189  return *this;
190  }
191  template < typename real_t >
193  {
194  tree = binary_op<real_t>(std::minus<real_t>{}, tree, rhs);
195  return *this;
196  }
197  template < typename real_t >
199  {
200  tree = binary_op<real_t>(std::multiplies<real_t>{}, tree, rhs);
201  return *this;
202  }
203  template < typename real_t >
205  {
206  tree = binary_op<real_t>(std::divides<real_t>{}, tree, rhs);
207  return *this;
208  }
209 
215  template < typename real_t >
216  class eval_ast
217  {
218  public:
220  using result_type = real_t;
221 
223  using symbol_table_t = std::map<std::string, result_type>;
224 
229  explicit eval_ast(symbol_table_t sym) : st(std::move(sym)) {}
230 
232  result_type operator()(nil /*unused*/) const { return 0; }
233 
235  result_type operator()(result_type n) const { return n; }
236 
238  result_type operator()(std::string const &c) const
239  {
240  auto it = st.find(c);
241  if (it == st.end()) {
242  throw std::invalid_argument("Unknown variable " + c); // NOLINT
243  }
244  return it->second;
245  }
246 
249  {
250  return boost::apply_visitor(*this, ast.tree);
251  }
252 
255  {
256  return tree.op(
257  boost::apply_visitor(*this, tree.lhs.tree),
258  boost::apply_visitor(*this, tree.rhs.tree)
259  );
260  }
261 
264  {
265  return tree.op(
266  boost::apply_visitor(*this, tree.rhs.tree)
267  );
268  }
269 
270  private:
272  };
273 
274  template <typename T> struct holds_alternative_impl {
275  using result_type = bool;
276 
277  template <typename U> bool operator()(U const & /*unused*/) const {
278  return std::is_same<U, T>::value;
279  }
280  };
281 
282  template <typename T, typename... Ts>
283  bool holds_alternative(boost::variant<Ts...> const &v) {
284  return boost::apply_visitor(holds_alternative_impl<T>(), v);
285  }
286 
287  template <typename real_t> struct ConstantFolder {
290 
292  result_type operator()(nil /*unused*/) const { return 0; }
293 
295  result_type operator()(real_t n) const { return n; }
296 
298  result_type operator()(std::string const &c) const { return c; }
299 
302  return boost::apply_visitor(*this, ast.tree);
303  }
304 
307  auto lhs = boost::apply_visitor(*this, tree.lhs.tree);
308  auto rhs = boost::apply_visitor(*this, tree.rhs.tree);
309 
310  /* If both operands are known, we can directly evaluate the function,
311  * else we just update the children with the new expressions. */
312  if (holds_alternative<real_t>(lhs) && holds_alternative<real_t>(rhs)) {
313  return tree.op(boost::get<real_t>(lhs), boost::get<real_t>(rhs));
314  }
315  return binary_op<real_t>(tree.op, lhs, rhs);
316  }
317 
320  auto rhs = boost::apply_visitor(*this, tree.rhs.tree);
321  /* If the operand is known, we can directly evaluate the function. */
322  if (holds_alternative<real_t>(rhs)) {
323  return tree.op(boost::get<real_t>(rhs));
324  }
325  return unary_op<real_t>(tree.op, rhs);
326  }
327  };
328 
329  // Expressions
330 
332  template < typename real_t >
333  struct unary_expr_ {
335  template < typename T > struct result { using type = T; };
336 
339  expr_ast<real_t> const &rhs) const {
340  return expr_ast<real_t>(unary_op<real_t>(op, rhs));
341  }
342  };
343 
345  template < typename real_t >
346  struct binary_expr_ {
348  template < typename T > struct result { using type = T; };
349 
352  expr_ast<real_t> const &lhs,
353  expr_ast<real_t> const &rhs) const {
354  return expr_ast<real_t>(binary_op<real_t>(op, lhs, rhs));
355  }
356  };
357 
361  template < typename Iterator >
362  void operator()(Iterator first, Iterator last,
363  boost::spirit::info const& info) const {
364  std::stringstream msg;
365  msg << "Expected "
366  << info
367  << " at \""
368  << std::string{first, last}
369  << "\"";
370 
371  throw std::runtime_error(msg.str()); // NOLINT
372  }
373  };
374 
375 
376  // Grammar
377 
379  template < typename real_t, typename Iterator >
380  struct grammar
381  : qi::grammar<
382  Iterator, expr_ast<real_t>(), ascii::space_type
383  >
384  {
385  private:
387  qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> expression;
388  qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> term;
389  qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> factor;
390  qi::rule<Iterator, expr_ast<real_t>(), ascii::space_type> primary;
391  qi::rule<Iterator, std::string()> variable;
392  public:
394  struct constant_
395  : boost::spirit::qi::symbols<
396  typename std::iterator_traits<Iterator>::value_type,
397  real_t
398  >
399  {
401  {
402  this->add
403  ("e" , boost::math::constants::e<real_t>() )
404  ("epsilon", std::numeric_limits<real_t>::epsilon())
405  ("phi" , boost::math::constants::phi<real_t>() )
406  ("pi" , boost::math::constants::pi<real_t>() )
407  ;
408  }
409  } constant;
410 
412  struct ufunc_
413  : boost::spirit::qi::symbols<
414  typename std::iterator_traits<Iterator>::value_type,
415  typename unary_op<real_t>::op_t
416  >
417  {
419  {
420  this->add
421  ("abs" , static_cast<real_t(*)(real_t)>(&std::abs ))
422  ("acos" , static_cast<real_t(*)(real_t)>(&std::acos ))
423  ("acosh" , static_cast<real_t(*)(real_t)>(&std::acosh ))
424  ("asin" , static_cast<real_t(*)(real_t)>(&std::asin ))
425  ("asinh" , static_cast<real_t(*)(real_t)>(&std::asinh ))
426  ("atan" , static_cast<real_t(*)(real_t)>(&std::atan ))
427  ("atanh" , static_cast<real_t(*)(real_t)>(&std::atanh ))
428  ("cbrt" , static_cast<real_t(*)(real_t)>(&std::cbrt ))
429  ("ceil" , static_cast<real_t(*)(real_t)>(&std::ceil ))
430  ("cos" , static_cast<real_t(*)(real_t)>(&std::cos ))
431  ("cosh" , static_cast<real_t(*)(real_t)>(&std::cosh ))
432  ("deg2rad", static_cast<real_t(*)(real_t)>(&math::deg ))
433  ("erf" , static_cast<real_t(*)(real_t)>(&std::erf ))
434  ("erfc" , static_cast<real_t(*)(real_t)>(&std::erfc ))
435  ("exp" , static_cast<real_t(*)(real_t)>(&std::exp ))
436  ("exp2" , static_cast<real_t(*)(real_t)>(&std::exp2 ))
437  ("floor" , static_cast<real_t(*)(real_t)>(&std::floor ))
438  ("isinf" , static_cast<real_t(*)(real_t)>(&math::isinf))
439  ("isnan" , static_cast<real_t(*)(real_t)>(&math::isnan))
440  ("log" , static_cast<real_t(*)(real_t)>(&std::log ))
441  ("log2" , static_cast<real_t(*)(real_t)>(&std::log2 ))
442  ("log10" , static_cast<real_t(*)(real_t)>(&std::log10 ))
443  ("rad2deg", static_cast<real_t(*)(real_t)>(&math::rad ))
444  ("round" , static_cast<real_t(*)(real_t)>(&std::round ))
445  ("sgn" , static_cast<real_t(*)(real_t)>(&math::sgn ))
446  ("sin" , static_cast<real_t(*)(real_t)>(&std::sin ))
447  ("sinh" , static_cast<real_t(*)(real_t)>(&std::sinh ))
448  ("sqrt" , static_cast<real_t(*)(real_t)>(&std::sqrt ))
449  ("tan" , static_cast<real_t(*)(real_t)>(&std::tan ))
450  ("tanh" , static_cast<real_t(*)(real_t)>(&std::tanh ))
451  ("tgamma" , static_cast<real_t(*)(real_t)>(&std::tgamma))
452  ;
453  }
454  } ufunc;
455 
457  struct bfunc_
458  : boost::spirit::qi::symbols<
459  typename std::iterator_traits<Iterator>::value_type,
460  typename binary_op<real_t>::op_t
461  >
462  {
464  {
465  this->add
466  ("atan2", static_cast<real_t(*)(real_t,real_t)>(&std::atan2))
467  ("max" , static_cast<real_t(*)(real_t,real_t)>(&std::fmax ))
468  ("min" , static_cast<real_t(*)(real_t,real_t)>(&std::fmin ))
469  ("pow" , static_cast<real_t(*)(real_t,real_t)>(&std::pow ))
470  ;
471  }
472  } bfunc;
473 
475  grammar() : grammar::base_type(expression)
476  {
477  using boost::spirit::qi::real_parser;
478  using boost::spirit::qi::real_policies;
479  real_parser<real_t,real_policies<real_t>> real;
480 
481  using boost::spirit::lexeme;
482  using boost::spirit::qi::_1;
483  using boost::spirit::qi::_2;
484  using boost::spirit::qi::_3;
485  using boost::spirit::qi::_4;
486  using boost::spirit::qi::_val;
488  using boost::spirit::qi::alnum;
489  using boost::spirit::qi::raw;
490 
491  boost::phoenix::function<unary_expr_<real_t>> unary_expr;
492  boost::phoenix::function<binary_expr_<real_t>> binary_expr;
493 
494  auto fmod = static_cast<real_t(*)(real_t,real_t)>(&std::fmod);
495  auto pow = static_cast<real_t(*)(real_t,real_t)>(&std::pow);
496 
497  expression =
498  term [_val = _1]
499  >> *( ('+' > term [_val += _1])
500  | ('-' > term [_val -= _1])
501  )
502  ;
503 
504  term =
505  factor [_val = _1]
506  >> *( ('*' > factor [_val *= _1])
507  | ('/' > factor [_val /= _1])
508  | ('%' > factor [_val = binary_expr(fmod, _val, _1)])
509  )
510  ;
511 
512  factor =
513  primary [_val = _1]
514  >> *( ("**" > factor [_val = binary_expr(pow, _val, _1)])
515  )
516  ;
517 
518  variable =
519  raw[lexeme[alpha >> *(alnum | '_')]];
520 
521  primary =
522  real [_val = _1]
523  | ('(' > expression [_val = _1] > ')')
524  | ('-' > primary [_val = unary_expr(std::negate<real_t>{}, _1)])
525  | ('+' > primary [_val = _1])
526  | (bfunc > '(' > expression > ',' > expression > ')')
527  [_val = binary_expr(_1, _2, _3)]
528  | (ufunc > '(' > expression > ')')
529  [_val = unary_expr(_1, _2)]
530  | constant [_val = _1]
531  | variable [_val = _1]
532  ;
533 
534  expression.name("expression");
535  term.name("term");
536  factor.name("factor");
537  variable.name("variable");
538  primary.name("primary");
539 
540  using boost::spirit::qi::fail;
541  using boost::spirit::qi::on_error;
542  using boost::phoenix::bind;
543  using boost::phoenix::ref;
544 
545  on_error<fail>
546  (
547  expression,
548  bind(ref(err_handler), _3, _2, _4)
549  );
550  }
551  };
552 
561  template <typename real_t, typename Iterator>
562  detail::expr_ast<real_t> parse(Iterator first, Iterator last) {
563  static detail::grammar<real_t, Iterator> const g;
564 
565  auto ast = detail::expr_ast<real_t>{};
566 
567  bool r = qi::phrase_parse(first, last, g, ascii::space, ast);
568 
569  if (!r || first != last) {
570  std::string rest(first, last);
571  throw std::runtime_error("Parsing failed at " + rest); // NOLINT
572  }
573 
574  return ast;
575  }
576 
577  } // namespace detail
578 
579 
587  template < typename real_t >
588  class Parser
589  {
591  public:
600  template < typename Iterator >
601  void parse(Iterator first, Iterator last)
602  {
603  ast = detail::parse<real_t>(first, last);
604  }
605 
607  void parse(std::string const &str)
608  {
609  parse(str.begin(), str.end());
610  }
611 
612  void optimize() {
613  ast.tree = boost::apply_visitor(detail::ConstantFolder<real_t>{}, ast.tree);
614  }
615 
621  {
622  detail::eval_ast<real_t> solver(st);
623  return solver(ast);
624  }
625  };
626 
627 
637  template < typename real_t, typename Iterator >
638  real_t parse(Iterator first, Iterator last,
639  typename detail::eval_ast<real_t>::symbol_table_t const &st)
640  {
641  Parser<real_t> parser;
642  parser.parse(first, last);
643  return parser.evaluate(st);
644  }
645 
647  template < typename real_t >
648  real_t parse(std::string const &str,
649  typename detail::eval_ast<real_t>::symbol_table_t const &st)
650  {
651  return parse<real_t>(str.begin(), str.end(), st);
652  }
653 
654 } // namespace matheval
655 
656 #if defined __clang__
657 # pragma clang diagnostic pop
658 #elif defined __GNUC__
659 # pragma GCC diagnostic pop
660 #endif
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
PETE_TUTree< FnArcCos, typename T::PETE_Expr_t > acos(const PETE_Expr< T > &l)
Definition: PETE.h:808
expr_ast & operator+=(expr_ast const &rhs)
Add a tree.
Definition: matheval.hpp:186
void parse(Iterator first, Iterator last)
Parse an expression.
Definition: matheval.hpp:601
std::function< real_t(real_t, real_t)> op_t
Signature of a binary operator: op(x,y)
Definition: matheval.hpp:170
Definition: rbendmap.h:8
qi::rule< Iterator, expr_ast< real_t >), ascii::space_type > primary
Definition: matheval.hpp:390
detail::expr_ast< real_t > ast
Definition: matheval.hpp:590
qi::rule< Iterator, expr_ast< real_t >), ascii::space_type > factor
Definition: matheval.hpp:389
eval_ast(symbol_table_t sym)
Constructor.
Definition: matheval.hpp:229
op_t op
Stored operator.
Definition: matheval.hpp:178
result_type operator()(expr_ast< real_t > const &ast) const
Recursively evaluate the AST.
Definition: matheval.hpp:248
FTps< T, N > erf(const FTps< T, N > &x, int trunc=(FTps< T, N >::EXACT))
Error function.
Definition: FTpsMath.h:385
Unary expression functor.
Definition: matheval.hpp:333
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
Make boost::phoenix::function happy.
Definition: matheval.hpp:348
void operator()(Iterator first, Iterator last, boost::spirit::info const &info) const
Throw an exception saying where and why parsing failed.
Definition: matheval.hpp:362
PETE_TUTree< FnCeil, typename T::PETE_Expr_t > ceil(const PETE_Expr< T > &l)
Definition: PETE.h:811
Tps< T > exp(const Tps< T > &x)
Exponential.
Definition: TpsMath.h:165
Binary expression functor.
Definition: matheval.hpp:346
FTps< T, N > erfc(const FTps< T, N > &x, int trunc=(FTps< T, N >::EXACT))
Complementary error function.
Definition: FTpsMath.h:414
symbol table for binary functions like &quot;pow&quot;
Definition: matheval.hpp:457
Tps< T > tan(const Tps< T > &x)
Tangent.
Definition: TpsMath.h:147
std::function< real_t(real_t)> op_t
Signature of a unary operator: op(x)
Definition: matheval.hpp:152
result_type operator()(expr_ast< real_t > const &ast) const
Recursively evaluate the AST.
Definition: matheval.hpp:301
tree_t tree
AST storage.
Definition: matheval.hpp:121
expr_ast & operator/=(expr_ast const &rhs)
Divide by a tree.
Definition: matheval.hpp:204
bool info
Info flag.
Definition: Options.cpp:8
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:112
real_t parse(Iterator first, Iterator last, typename detail::eval_ast< real_t >::symbol_table_t const &st)
Convenience function.
Definition: matheval.hpp:638
qi::rule< Iterator, std::string()> variable
Definition: matheval.hpp:391
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:338
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
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:351
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
expr_ast< real_t > lhs
Stored argument tree of first argument.
Definition: matheval.hpp:180
T sgn(T x)
Sign function.
Definition: matheval.hpp:70
T deg(T x)
Convert radians to degrees.
Definition: matheval.hpp:82
Tps< T > cosh(const Tps< T > &x)
Hyperbolic cosine.
Definition: TpsMath.h:222
constexpr double alpha
The fine structure constant, no dimension.
Definition: Physics.h:79
expr_ast & operator-=(expr_ast const &rhs)
subtract a tree
Definition: matheval.hpp:192
Abstract Syntax Tree.
Definition: matheval.hpp:103
result_type operator()(std::string const &c) const
Variables do not evaluate.
Definition: matheval.hpp:298
result_type operator()(real_t n) const
Numbers evaluate to themselves.
Definition: matheval.hpp:295
matheval::detail::grammar::bfunc_ bfunc
PETE_TUTree< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
Definition: PETE.h:810
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
detail::expr_ast< real_t > parse(Iterator first, Iterator last)
Parse an expression.
Definition: matheval.hpp:562
matheval::detail::grammar::constant_ constant
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
op_t op
Stored operator.
Definition: matheval.hpp:160
real_t result_type
Necessary typedef for boost::apply_visitor
Definition: matheval.hpp:220
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
expr_ast< real_t > rhs
Stored argument tree.
Definition: matheval.hpp:162
void parse(std::string const &str)
Definition: matheval.hpp:607
expr_ast(Expr other)
Copy constructor.
Definition: matheval.hpp:135
grammar()
Constructor builds the grammar.
Definition: matheval.hpp:475
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
unary_op(op_t op, expr_ast< real_t > rhs)
Save the operator and the argument tree.
Definition: matheval.hpp:155
Evaluate the Abstract Syntax Tree.
Definition: matheval.hpp:216
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
T rad(T x)
Convert degrees to radians.
Definition: matheval.hpp:86
Expression Grammar.
Definition: matheval.hpp:380
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:620
bool holds_alternative(boost::variant< Ts...> const &v)
Definition: matheval.hpp:283
matheval::detail::grammar::ufunc_ ufunc
Class interface.
Definition: matheval.hpp:588
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Make boost::phoenix::function happy.
Definition: matheval.hpp:335
expr_ast & operator*=(expr_ast const &rhs)
Multiply by a tree.
Definition: matheval.hpp:198
T isnan(T x)
isnan function with adjusted return type
Definition: matheval.hpp:74
Error handler for expectation errors.
Definition: matheval.hpp:359
std::map< std::string, result_type > symbol_table_t
Type of the symbol table.
Definition: matheval.hpp:223
result_type operator()(result_type n) const
Numbers evaluate to themselves.
Definition: matheval.hpp:235
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:173
Store a unary operator and its argument tree.
Definition: matheval.hpp:92
expr_ast< real_t > rhs
Stored argument tree of second argument.
Definition: matheval.hpp:182
expectation_handler err_handler
Definition: matheval.hpp:386
PETE_TUTree< FnArcSin, typename T::PETE_Expr_t > asin(const PETE_Expr< T > &l)
Definition: PETE.h:809
Store a binary operator and its argument trees.
Definition: matheval.hpp:93
result_type operator()(unary_op< real_t > const &tree) const
Evaluate a unary operator and optionally recurse its operand.
Definition: matheval.hpp:263
result_type operator()(binary_op< real_t > const &tree) const
Evaluate a binary operator and optionally recurse its operands.
Definition: matheval.hpp:254
result_type operator()(nil) const
Empty nodes in the tree evaluate to 0.
Definition: matheval.hpp:232
symbol table for unary functions like &quot;abs&quot;
Definition: matheval.hpp:412
qi::rule< Iterator, expr_ast< real_t >), ascii::space_type > term
Definition: matheval.hpp:388
result_type operator()(unary_op< real_t > const &tree) const
Evaluate a unary operator and optionally recurse its operand.
Definition: matheval.hpp:319
expr_ast()
Default constructor.
Definition: matheval.hpp:128
Tps< T > tanh(const Tps< T > &x)
Hyperbolic tangent.
Definition: TpsMath.h:240
result_type operator()(std::string const &c) const
Variables evaluate to their value in the symbol table.
Definition: matheval.hpp:238
symbol table for constants like &quot;pi&quot;
Definition: matheval.hpp:394
result_type operator()(nil) const
Empty nodes in the tree evaluate to 0.
Definition: matheval.hpp:292
qi::rule< Iterator, expr_ast< real_t >), ascii::space_type > expression
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:306
typename expr_ast< real_t >::tree_t result_type
Necessary typedef for boost::apply_visitor
Definition: matheval.hpp:289
Tps< T > sinh(const Tps< T > &x)
Hyperbolic sine.
Definition: TpsMath.h:204
PETE_TUTree< FnLog10, typename T::PETE_Expr_t > log10(const PETE_Expr< T > &l)
Definition: PETE.h:818
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:816
T isinf(T x)
isinf function with adjusted return type
Definition: matheval.hpp:78