C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
ab7c1677e5
commit
baa1feb6d2
131
exprtk.hpp
131
exprtk.hpp
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
*******************************************************************
|
||||
******************************************************************
|
||||
* C++ Mathematical Expression Toolkit Library *
|
||||
* *
|
||||
* Author: Arash Partow (1999-2014) *
|
||||
|
@ -26,7 +26,7 @@
|
|||
* (11) (2sin(x)cos(2y)7 + 1) == (2 * sin(x) * cos(2*y) * 7 + 1) *
|
||||
* (12) (x ilike 's*ri?g') and [y < (3 z^7 + w)] *
|
||||
* *
|
||||
*******************************************************************
|
||||
******************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
@ -288,8 +288,9 @@ namespace exprtk
|
|||
"for", "frac", "grad2deg", "hypot", "iclamp", "if", "else", "ilike", "in", "inrange",
|
||||
"like", "log", "log10", "log2", "logn", "log1p", "mand", "max", "min", "mod", "mor",
|
||||
"mul", "nand", "nor", "not", "not_equal", "null", "or", "pow", "rad2deg", "repeat",
|
||||
"root", "round", "roundn", "sec", "sgn", "shl", "shr", "sin", "sinh", "sqrt", "sum",
|
||||
"switch", "tan", "tanh", "true", "trunc", "until", "while", "xnor", "xor", "&", "|"
|
||||
"root", "round", "roundn", "sec", "sgn", "shl", "shr", "sin", "sinc", "sinh", "sqrt",
|
||||
"sum", "switch", "tan", "tanh", "true", "trunc", "until", "while", "xnor", "xor",
|
||||
"&", "|"
|
||||
};
|
||||
|
||||
static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
|
||||
|
@ -851,6 +852,21 @@ namespace exprtk
|
|||
return erfc_impl(static_cast<double>(v),real_type_tag());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T sinc_impl(T v, real_type_tag)
|
||||
{
|
||||
if(std::abs(v) >= std::numeric_limits<T>::epsilon())
|
||||
return(std::sin(v) / v);
|
||||
else
|
||||
return T(1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T sinc_impl(T v, int_type_tag)
|
||||
{
|
||||
return erfc_impl(static_cast<double>(v),real_type_tag());
|
||||
}
|
||||
|
||||
template <typename T> inline T acos_impl(const T v, real_type_tag) { return std::acos (v); }
|
||||
template <typename T> inline T acosh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) - T(1))); }
|
||||
template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
|
||||
|
@ -1123,6 +1139,7 @@ namespace exprtk
|
|||
exprtk_define_unary_function(pos )
|
||||
exprtk_define_unary_function(round)
|
||||
exprtk_define_unary_function(sin )
|
||||
exprtk_define_unary_function(sinc )
|
||||
exprtk_define_unary_function(sinh )
|
||||
exprtk_define_unary_function(sqrt )
|
||||
exprtk_define_unary_function(tan )
|
||||
|
@ -3129,14 +3146,15 @@ namespace exprtk
|
|||
e_exp , e_expm1 , e_floor , e_log ,
|
||||
e_log10 , e_log2 , e_log1p , e_logn ,
|
||||
e_neg , e_pos , e_round , e_roundn ,
|
||||
e_root , e_sqrt , e_sin , e_sinh ,
|
||||
e_sec , e_csc , e_tan , e_tanh ,
|
||||
e_cot , e_clamp , e_iclamp , e_inrange ,
|
||||
e_sgn , e_r2d , e_d2r , e_d2g ,
|
||||
e_g2d , e_hypot , e_notl , e_erf ,
|
||||
e_erfc , e_frac , e_trunc , e_assign ,
|
||||
e_addass , e_subass , e_mulass , e_divass ,
|
||||
e_in , e_like , e_ilike , e_multi ,
|
||||
e_root , e_sqrt , e_sin , e_sinc ,
|
||||
e_sinh , e_sec , e_csc , e_tan ,
|
||||
e_tanh , e_cot , e_clamp , e_iclamp ,
|
||||
e_inrange , e_sgn , e_r2d , e_d2r ,
|
||||
e_d2g , e_g2d , e_hypot , e_notl ,
|
||||
e_erf , e_erfc , e_frac , e_trunc ,
|
||||
e_assign , e_addass , e_subass , e_mulass ,
|
||||
e_divass , e_in , e_like , e_ilike ,
|
||||
e_multi ,
|
||||
|
||||
// Do not add new functions/operators after this point.
|
||||
e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003,
|
||||
|
@ -3220,6 +3238,7 @@ namespace exprtk
|
|||
case e_pos : return numeric::pos (arg);
|
||||
case e_round : return numeric::round(arg);
|
||||
case e_sin : return numeric::sin (arg);
|
||||
case e_sinc : return numeric::sinc (arg);
|
||||
case e_sinh : return numeric::sinh (arg);
|
||||
case e_sqrt : return numeric::sqrt (arg);
|
||||
case e_tan : return numeric::tan (arg);
|
||||
|
@ -3376,18 +3395,18 @@ namespace exprtk
|
|||
e_cos , e_cosh , e_exp , e_expm1 ,
|
||||
e_floor , e_log , e_log10 , e_log2 ,
|
||||
e_log1p , e_neg , e_pos , e_round ,
|
||||
e_sin , e_sinh , e_sqrt , e_tan ,
|
||||
e_tanh , e_cot , e_sec , e_csc ,
|
||||
e_r2d , e_d2r , e_d2g , e_g2d ,
|
||||
e_notl , e_sgn , e_erf , e_erfc ,
|
||||
e_frac , e_trunc , e_uvouv , e_vov ,
|
||||
e_cov , e_voc , e_vob , e_bov ,
|
||||
e_cob , e_boc , e_vovov , e_vovoc ,
|
||||
e_vocov , e_covov , e_covoc , e_vovovov ,
|
||||
e_vovovoc , e_vovocov , e_vocovov , e_covovov ,
|
||||
e_covocov , e_vocovoc , e_covovoc , e_vococov ,
|
||||
e_sf3ext , e_sf4ext , e_nulleq , e_vecelem ,
|
||||
e_break , e_continue
|
||||
e_sin , e_sinc , e_sinh , e_sqrt ,
|
||||
e_tan , e_tanh , e_cot , e_sec ,
|
||||
e_csc , e_r2d , e_d2r , e_d2g ,
|
||||
e_g2d , e_notl , e_sgn , e_erf ,
|
||||
e_erfc , e_frac , e_trunc , e_uvouv ,
|
||||
e_vov , e_cov , e_voc , e_vob ,
|
||||
e_bov , e_cob , e_boc , e_vovov ,
|
||||
e_vovoc , e_vocov , e_covov , e_covoc ,
|
||||
e_vovovov , e_vovovoc , e_vovocov , e_vocovov ,
|
||||
e_covovov , e_covocov , e_vocovoc , e_covovoc ,
|
||||
e_vococov , e_sf3ext , e_sf4ext , e_nulleq ,
|
||||
e_vecelem , e_break , e_continue
|
||||
};
|
||||
|
||||
typedef T value_type;
|
||||
|
@ -6199,6 +6218,7 @@ namespace exprtk
|
|||
exprtk_define_unary_op(sec )
|
||||
exprtk_define_unary_op(sgn )
|
||||
exprtk_define_unary_op(sin )
|
||||
exprtk_define_unary_op(sinc )
|
||||
exprtk_define_unary_op(sinh )
|
||||
exprtk_define_unary_op(sqrt )
|
||||
exprtk_define_unary_op(tan )
|
||||
|
@ -7398,7 +7418,9 @@ namespace exprtk
|
|||
|
||||
struct mode0
|
||||
{
|
||||
static inline T process(const T& t0, const T& t1, const T& t2, const T& t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
|
||||
static inline T process(const T& t0, const T& t1,
|
||||
const T& t2, const T& t3,
|
||||
const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
|
||||
{
|
||||
// (T0 o0 T1) o1 (T2 o2 T3)
|
||||
return bf1(bf0(t0,t1),bf2(t2,t3));
|
||||
|
@ -7417,7 +7439,9 @@ namespace exprtk
|
|||
|
||||
struct mode1
|
||||
{
|
||||
static inline T process(const T& t0, const T& t1, const T& t2, const T& t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
|
||||
static inline T process(const T& t0, const T& t1,
|
||||
const T& t2, const T& t3,
|
||||
const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
|
||||
{
|
||||
// (T0 o0 (T1 o1 (T2 o2 T3))
|
||||
return bf0(t0,bf1(t1,bf2(t2,t3)));
|
||||
|
@ -7435,7 +7459,9 @@ namespace exprtk
|
|||
|
||||
struct mode2
|
||||
{
|
||||
static inline T process(const T& t0, const T& t1, const T& t2, const T& t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
|
||||
static inline T process(const T& t0, const T& t1,
|
||||
const T& t2, const T& t3,
|
||||
const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
|
||||
{
|
||||
// (T0 o0 ((T1 o1 T2) o2 T3)
|
||||
return bf0(t0,bf2(bf1(t1,t2),t3));
|
||||
|
@ -7454,7 +7480,9 @@ namespace exprtk
|
|||
|
||||
struct mode3
|
||||
{
|
||||
static inline T process(const T& t0, const T& t1, const T& t2, const T& t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
|
||||
static inline T process(const T& t0, const T& t1,
|
||||
const T& t2, const T& t3,
|
||||
const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
|
||||
{
|
||||
// (((T0 o0 T1) o1 T2) o2 T3)
|
||||
return bf2(bf1(bf0(t0,t1),t2),t3);
|
||||
|
@ -7473,7 +7501,9 @@ namespace exprtk
|
|||
|
||||
struct mode4
|
||||
{
|
||||
static inline T process(const T& t0, const T& t1, const T& t2, const T& t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
|
||||
static inline T process(const T& t0, const T& t1,
|
||||
const T& t2, const T& t3,
|
||||
const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
|
||||
{
|
||||
// ((T0 o0 (T1 o1 T2)) o2 T3
|
||||
return bf2(bf0(t0,bf1(t1,t2)),t3);
|
||||
|
@ -9306,6 +9336,7 @@ namespace exprtk
|
|||
register_op( "log1p",e_log1p , 1)
|
||||
register_op( "round",e_round , 1)
|
||||
register_op( "sin",e_sin , 1)
|
||||
register_op( "sinc",e_sinc , 1)
|
||||
register_op( "sinh",e_sinh , 1)
|
||||
register_op( "sec",e_sec , 1)
|
||||
register_op( "csc",e_csc , 1)
|
||||
|
@ -9347,14 +9378,16 @@ namespace exprtk
|
|||
{
|
||||
public:
|
||||
|
||||
explicit ifunction(const std::size_t& pc)
|
||||
: param_count(pc)
|
||||
explicit ifunction(const std::size_t& pc, const bool hse = true)
|
||||
: param_count(pc),
|
||||
has_side_effects(hse)
|
||||
{}
|
||||
|
||||
virtual ~ifunction()
|
||||
{}
|
||||
|
||||
std::size_t param_count;
|
||||
bool has_side_effects;
|
||||
|
||||
inline virtual T operator()()
|
||||
{
|
||||
|
@ -10855,7 +10888,7 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
|
||||
bool update_error(type& error, const std::string& expression)
|
||||
inline bool update_error(type& error, const std::string& expression)
|
||||
{
|
||||
if (
|
||||
expression.empty() ||
|
||||
|
@ -11930,7 +11963,10 @@ namespace exprtk
|
|||
{
|
||||
expression_node_ptr result = expression_generator_.function(function);
|
||||
next_token();
|
||||
if (token_is(token_t::e_lbracket) && (!token_is(token_t::e_rbracket)))
|
||||
if (
|
||||
token_is(token_t::e_lbracket) &&
|
||||
!token_is(token_t::e_rbracket)
|
||||
)
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
|
@ -13373,7 +13409,7 @@ namespace exprtk
|
|||
}
|
||||
else if (token_is(token_t::e_rsqrbracket))
|
||||
{
|
||||
return expression_generator_(vec->size());
|
||||
return expression_generator_(T(vec->size()));
|
||||
}
|
||||
else if (0 == (index_expr = parse_expression()))
|
||||
{
|
||||
|
@ -14161,15 +14197,16 @@ namespace exprtk
|
|||
(details::e_log10 == operation) || (details::e_log2 == operation) ||
|
||||
(details::e_log1p == operation) || (details::e_neg == operation) ||
|
||||
(details::e_pos == operation) || (details::e_round == operation) ||
|
||||
(details::e_sin == operation) || (details::e_sinh == operation) ||
|
||||
(details::e_sqrt == operation) || (details::e_tan == operation) ||
|
||||
(details::e_tanh == operation) || (details::e_cot == operation) ||
|
||||
(details::e_sec == operation) || (details::e_csc == operation) ||
|
||||
(details::e_r2d == operation) || (details::e_d2r == operation) ||
|
||||
(details::e_d2g == operation) || (details::e_g2d == operation) ||
|
||||
(details::e_notl == operation) || (details::e_sgn == operation) ||
|
||||
(details::e_erf == operation) || (details::e_erfc == operation) ||
|
||||
(details::e_frac == operation) || (details::e_trunc == operation);
|
||||
(details::e_sin == operation) || (details::e_sinc == operation) ||
|
||||
(details::e_sinh == operation) || (details::e_sqrt == operation) ||
|
||||
(details::e_tan == operation) || (details::e_tanh == operation) ||
|
||||
(details::e_cot == operation) || (details::e_sec == operation) ||
|
||||
(details::e_csc == operation) || (details::e_r2d == operation) ||
|
||||
(details::e_d2r == operation) || (details::e_d2g == operation) ||
|
||||
(details::e_g2d == operation) || (details::e_notl == operation) ||
|
||||
(details::e_sgn == operation) || (details::e_erf == operation) ||
|
||||
(details::e_erfc == operation) || (details::e_frac == operation) ||
|
||||
(details::e_trunc == operation);
|
||||
}
|
||||
|
||||
inline bool sf3_optimizable(const std::string& sf3id, trinary_functor_t& tfunc)
|
||||
|
@ -14881,6 +14918,7 @@ namespace exprtk
|
|||
case_stmt(details:: e_pos,details:: pos_op) \
|
||||
case_stmt(details::e_round,details::round_op) \
|
||||
case_stmt(details:: e_sin,details:: sin_op) \
|
||||
case_stmt(details:: e_sinc,details:: sinc_op) \
|
||||
case_stmt(details:: e_sinh,details:: sinh_op) \
|
||||
case_stmt(details:: e_sqrt,details:: sqrt_op) \
|
||||
case_stmt(details:: e_tan,details:: tan_op) \
|
||||
|
@ -19822,7 +19860,7 @@ namespace exprtk
|
|||
// Attempt simple constant folding optimization.
|
||||
expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f);
|
||||
dynamic_cast<function_N_node_t*>(expression_point)->init_branches(branch);
|
||||
if (is_constant_foldable<N>(branch))
|
||||
if (is_constant_foldable<N>(branch) && !f->has_side_effects)
|
||||
{
|
||||
Type v = expression_point->value();
|
||||
details::free_node(*node_allocator_,expression_point);
|
||||
|
@ -19924,6 +19962,7 @@ namespace exprtk
|
|||
register_unary_op(details:: e_pos,details:: pos_op)
|
||||
register_unary_op(details::e_round,details::round_op)
|
||||
register_unary_op(details:: e_sin,details:: sin_op)
|
||||
register_unary_op(details:: e_sinc,details:: sinc_op)
|
||||
register_unary_op(details:: e_sinh,details:: sinh_op)
|
||||
register_unary_op(details:: e_sqrt,details:: sqrt_op)
|
||||
register_unary_op(details:: e_tan,details:: tan_op)
|
||||
|
@ -20496,7 +20535,9 @@ namespace exprtk
|
|||
|
||||
public:
|
||||
|
||||
polynomial() : exprtk::ifunction<T>((N+2 <= 20) ? (N + 2) : std::numeric_limits<std::size_t>::max()) {}
|
||||
polynomial()
|
||||
: exprtk::ifunction<T>((N+2 <= 20) ? (N + 2) : std::numeric_limits<std::size_t>::max(),false)
|
||||
{}
|
||||
|
||||
inline virtual T operator()(const T& x, const T& c1, const T& c0)
|
||||
{
|
||||
|
|
48
readme.txt
48
readme.txt
|
@ -13,36 +13,37 @@ easily extendible.
|
|||
The ExprTk expression evaluator supports the following fundamental
|
||||
arithmetic operations, functions and processes:
|
||||
|
||||
(0) Basic operators: +, -, *, /, %, ^
|
||||
(00) Basic operators: +, -, *, /, %, ^
|
||||
|
||||
(1) Functions: abs, avg, ceil, clamp, equal, erf, erfc, exp,
|
||||
(01) Functions: abs, avg, ceil, clamp, equal, erf, erfc, exp,
|
||||
expm1, floor, frac, log, log10, log1p, log2,
|
||||
logn, max, min, mul, nequal, root, round,
|
||||
roundn, sgn, sqrt, sum, trunc
|
||||
|
||||
(2) Trigonometry: acos, acosh, asin, asinh, atan, atanh, atan2,
|
||||
cos, cosh, cot, csc, sec, sin, sinh, tan, tanh,
|
||||
hypot, rad2deg, deg2grad, deg2rad, grad2deg
|
||||
(02) Trigonometry: acos, acosh, asin, asinh, atan, atanh, atan2,
|
||||
cos, cosh, cot, csc, sec, sin, sinc, sinh, tan,
|
||||
tanh, hypot, rad2deg, deg2grad, deg2rad,
|
||||
grad2deg
|
||||
|
||||
(3) Equalities &
|
||||
(03) Equalities &
|
||||
Inequalities: =, ==, <>, !=, <, <=, >, >=
|
||||
|
||||
(4) Boolean logic: and, mand, mor, nand, nor, not, or, shl, shr,
|
||||
(04) Boolean logic: and, mand, mor, nand, nor, not, or, shl, shr,
|
||||
xnor, xor, true, false
|
||||
|
||||
(5) Conditional,
|
||||
Switch &
|
||||
Loop statements: if-then-else, ternary conditional, switch-case,
|
||||
while, for, repeat-until, break, continue
|
||||
(05) Control
|
||||
structures: if-then-else, ternary conditional, switch-case
|
||||
|
||||
(6) Assignment: :=, +=, -=, *=, /=
|
||||
(06) Loop statements: while, for, repeat-until, break, continue
|
||||
|
||||
(7) String
|
||||
(07) Assignment: :=, +=, -=, *=, /=
|
||||
|
||||
(08) String
|
||||
processing: in, like, ilike
|
||||
|
||||
(8) Optimisations: constant-folding and simple strength reduction
|
||||
(09) Optimisations: constant-folding and simple strength reduction
|
||||
|
||||
(9) Calculus: numerical integration and differentiation
|
||||
(10) Calculus: numerical integration and differentiation
|
||||
|
||||
|
||||
|
||||
|
@ -331,6 +332,8 @@ include path (e.g: /usr/include/).
|
|||
+----------+---------------------------------------------------------+
|
||||
| sin | Sine of x. (eg: sin(x)) |
|
||||
+----------+---------------------------------------------------------+
|
||||
| sinc | Sine cardinal of x. (eg: sinc(x)) |
|
||||
+----------+---------------------------------------------------------+
|
||||
| sinh | Hyperbolic sine of x. (eg: sinh(x)) |
|
||||
+----------+---------------------------------------------------------+
|
||||
| tan | Tangent of x. (eg: tan(x)) |
|
||||
|
@ -891,25 +894,32 @@ correctly optimize such expressions for a given architecture.
|
|||
(19) Recursive calls made from within composited functions will have
|
||||
a stack size bound by the stack of the executing architecture.
|
||||
|
||||
(20) The entity relationship between symbol_table and an expression
|
||||
(20) User defined functions by default are assumed to have side
|
||||
effects. As such an "all constant parameter" invocation of such
|
||||
functions wont result in constant folding. If the function has
|
||||
no side effects then that can be noted during the constructor
|
||||
of the ifunction allowing it to be constant folded where
|
||||
appropriate.
|
||||
|
||||
(21) The entity relationship between symbol_table and an expression
|
||||
is one-to-many. Hence the intended use case is to have a single
|
||||
symbol table manage the variable and function requirements of
|
||||
multiple expressions.
|
||||
|
||||
(21) The common use-case for an expression is to have it compiled
|
||||
(22) The common use-case for an expression is to have it compiled
|
||||
only ONCE and then subsequently have it evaluated multiple
|
||||
times. An extremely inefficient and suboptimal approach would
|
||||
be to recompile an expression from its string form every time
|
||||
it requires evaluating.
|
||||
|
||||
(22) The following are examples of compliant floating point value
|
||||
(23) The following are examples of compliant floating point value
|
||||
representations:
|
||||
(a) 12345 (b) -123.456
|
||||
(c) +123.456e+12 (d) 123.456E-12
|
||||
(e) +012.045e+07 (f) .1234
|
||||
(g) 123.456f (h) -321.654E+3L
|
||||
|
||||
(23) Expressions may contain any of the following comment styles:
|
||||
(24) Expressions may contain any of the following comment styles:
|
||||
1. // .... \n
|
||||
2. # .... \n
|
||||
3. /* .... */
|
||||
|
|
Loading…
Reference in New Issue