C++ Mathematical Expression Library (ExprTk) https://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
e0b0aa5130
commit
6c37419d62
12
.travis.yml
12
.travis.yml
|
@ -1,12 +0,0 @@
|
||||||
language: cpp
|
|
||||||
|
|
||||||
sudo: required
|
|
||||||
|
|
||||||
dist: trusty
|
|
||||||
|
|
||||||
compiler:
|
|
||||||
- gcc
|
|
||||||
|
|
||||||
script:
|
|
||||||
- make clean all
|
|
||||||
- ./exprtk_test
|
|
183
exprtk.hpp
183
exprtk.hpp
|
@ -1111,13 +1111,21 @@ namespace exprtk
|
||||||
return T(0);
|
return T(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
|
||||||
|
#define exprtk_define_erf(TT,impl) \
|
||||||
|
inline TT erf_impl(TT v) { return impl(v); } \
|
||||||
|
|
||||||
|
exprtk_define_erf( float,::erff)
|
||||||
|
exprtk_define_erf( double,::erf )
|
||||||
|
exprtk_define_erf(long double,::erfl)
|
||||||
|
#undef exprtk_define_erf
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T erf_impl(T v, real_type_tag)
|
inline T erf_impl(T v, real_type_tag)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||||
// Credits: Abramowitz & Stegun Equations 7.1.25-28
|
// Credits: Abramowitz & Stegun Equations 7.1.25-28
|
||||||
const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
|
|
||||||
|
|
||||||
static const T c[] = {
|
static const T c[] = {
|
||||||
T( 1.26551223), T(1.00002368),
|
T( 1.26551223), T(1.00002368),
|
||||||
T( 0.37409196), T(0.09678418),
|
T( 0.37409196), T(0.09678418),
|
||||||
|
@ -1126,6 +1134,8 @@ namespace exprtk
|
||||||
T(-0.82215223), T(0.17087277)
|
T(-0.82215223), T(0.17087277)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
|
||||||
|
|
||||||
T result = T(1) - t * std::exp((-v * v) -
|
T result = T(1) - t * std::exp((-v * v) -
|
||||||
c[0] + t * (c[1] + t *
|
c[0] + t * (c[1] + t *
|
||||||
(c[2] + t * (c[3] + t *
|
(c[2] + t * (c[3] + t *
|
||||||
|
@ -1135,7 +1145,7 @@ namespace exprtk
|
||||||
|
|
||||||
return (v >= T(0)) ? result : -result;
|
return (v >= T(0)) ? result : -result;
|
||||||
#else
|
#else
|
||||||
return ::erf(v);
|
return erf_impl(v);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1145,13 +1155,23 @@ namespace exprtk
|
||||||
return erf_impl(static_cast<double>(v),real_type_tag());
|
return erf_impl(static_cast<double>(v),real_type_tag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
|
||||||
|
#define exprtk_define_erfc(TT,impl) \
|
||||||
|
inline TT erfc_impl(TT v) { return impl(v); } \
|
||||||
|
|
||||||
|
exprtk_define_erfc( float,::erfcf)
|
||||||
|
exprtk_define_erfc( double,::erfc )
|
||||||
|
exprtk_define_erfc(long double,::erfcl)
|
||||||
|
#undef exprtk_define_erfc
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T erfc_impl(T v, real_type_tag)
|
inline T erfc_impl(T v, real_type_tag)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||||
return T(1) - erf_impl(v,real_type_tag());
|
return T(1) - erf_impl(v,real_type_tag());
|
||||||
#else
|
#else
|
||||||
return ::erfc(v);
|
return erfc_impl(v);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1196,7 +1216,7 @@ namespace exprtk
|
||||||
template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
|
template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
|
||||||
template <typename T> inline T asinh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) + T(1))); }
|
template <typename T> inline T asinh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) + T(1))); }
|
||||||
template <typename T> inline T atan_impl(const T v, real_type_tag) { return std::atan (v); }
|
template <typename T> inline T atan_impl(const T v, real_type_tag) { return std::atan (v); }
|
||||||
template <typename T> inline T atanh_impl(const T v, real_type_tag) { return (std::log(T(1) + v) - log(T(1) - v)) / T(2); }
|
template <typename T> inline T atanh_impl(const T v, real_type_tag) { return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2); }
|
||||||
template <typename T> inline T ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
|
template <typename T> inline T ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
|
||||||
template <typename T> inline T cos_impl(const T v, real_type_tag) { return std::cos (v); }
|
template <typename T> inline T cos_impl(const T v, real_type_tag) { return std::cos (v); }
|
||||||
template <typename T> inline T cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
|
template <typename T> inline T cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
|
||||||
|
@ -1269,7 +1289,7 @@ namespace exprtk
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
|
struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
|
||||||
|
|
||||||
template<> struct numeric_info<int> { enum { length = 10, size = 16, bound_length = 9}; };
|
template<> struct numeric_info<int> { enum { length = 10, size = 16, bound_length = 9}; };
|
||||||
template<> struct numeric_info<float> { enum { min_exp = -38, max_exp = +38}; };
|
template<> struct numeric_info<float> { enum { min_exp = -38, max_exp = +38}; };
|
||||||
template<> struct numeric_info<double> { enum { min_exp = -308, max_exp = +308}; };
|
template<> struct numeric_info<double> { enum { min_exp = -308, max_exp = +308}; };
|
||||||
template<> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308}; };
|
template<> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308}; };
|
||||||
|
@ -9223,8 +9243,8 @@ namespace exprtk
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Operation>
|
template <typename T, typename Operation>
|
||||||
class vecarith_vecvec_node : public binary_node <T>,
|
class vec_binop_vecvec_node : public binary_node <T>,
|
||||||
public vector_interface<T>
|
public vector_interface<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -9232,9 +9252,9 @@ namespace exprtk
|
||||||
typedef vector_node<T>* vector_node_ptr;
|
typedef vector_node<T>* vector_node_ptr;
|
||||||
typedef vector_holder<T>* vector_holder_ptr;
|
typedef vector_holder<T>* vector_holder_ptr;
|
||||||
|
|
||||||
vecarith_vecvec_node(const operator_type& opr,
|
vec_binop_vecvec_node(const operator_type& opr,
|
||||||
expression_ptr branch0,
|
expression_ptr branch0,
|
||||||
expression_ptr branch1)
|
expression_ptr branch1)
|
||||||
: binary_node<T>(opr,branch0,branch1),
|
: binary_node<T>(opr,branch0,branch1),
|
||||||
vec0_node_ptr_(0),
|
vec0_node_ptr_(0),
|
||||||
vec1_node_ptr_(0),
|
vec1_node_ptr_(0),
|
||||||
|
@ -9286,7 +9306,7 @@ namespace exprtk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~vecarith_vecvec_node()
|
~vec_binop_vecvec_node()
|
||||||
{
|
{
|
||||||
delete[] data_;
|
delete[] data_;
|
||||||
delete temp_;
|
delete temp_;
|
||||||
|
@ -9388,8 +9408,8 @@ namespace exprtk
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Operation>
|
template <typename T, typename Operation>
|
||||||
class vecarith_vecval_node : public binary_node <T>,
|
class vec_binop_vecval_node : public binary_node <T>,
|
||||||
public vector_interface<T>
|
public vector_interface<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -9397,9 +9417,9 @@ namespace exprtk
|
||||||
typedef vector_node<T>* vector_node_ptr;
|
typedef vector_node<T>* vector_node_ptr;
|
||||||
typedef vector_holder<T>* vector_holder_ptr;
|
typedef vector_holder<T>* vector_holder_ptr;
|
||||||
|
|
||||||
vecarith_vecval_node(const operator_type& opr,
|
vec_binop_vecval_node(const operator_type& opr,
|
||||||
expression_ptr branch0,
|
expression_ptr branch0,
|
||||||
expression_ptr branch1)
|
expression_ptr branch1)
|
||||||
: binary_node<T>(opr,branch0,branch1),
|
: binary_node<T>(opr,branch0,branch1),
|
||||||
vec0_node_ptr_(0),
|
vec0_node_ptr_(0),
|
||||||
vec_size_ (0),
|
vec_size_ (0),
|
||||||
|
@ -9432,7 +9452,7 @@ namespace exprtk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~vecarith_vecval_node()
|
~vec_binop_vecval_node()
|
||||||
{
|
{
|
||||||
delete[] data_;
|
delete[] data_;
|
||||||
delete temp_;
|
delete temp_;
|
||||||
|
@ -9530,8 +9550,8 @@ namespace exprtk
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Operation>
|
template <typename T, typename Operation>
|
||||||
class vecarith_valvec_node : public binary_node <T>,
|
class vec_binop_valvec_node : public binary_node <T>,
|
||||||
public vector_interface<T>
|
public vector_interface<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -9539,9 +9559,9 @@ namespace exprtk
|
||||||
typedef vector_node<T>* vector_node_ptr;
|
typedef vector_node<T>* vector_node_ptr;
|
||||||
typedef vector_holder<T>* vector_holder_ptr;
|
typedef vector_holder<T>* vector_holder_ptr;
|
||||||
|
|
||||||
vecarith_valvec_node(const operator_type& opr,
|
vec_binop_valvec_node(const operator_type& opr,
|
||||||
expression_ptr branch0,
|
expression_ptr branch0,
|
||||||
expression_ptr branch1)
|
expression_ptr branch1)
|
||||||
: binary_node<T>(opr,branch0,branch1),
|
: binary_node<T>(opr,branch0,branch1),
|
||||||
vec1_node_ptr_(0),
|
vec1_node_ptr_(0),
|
||||||
vec_size_ (0),
|
vec_size_ (0),
|
||||||
|
@ -9574,7 +9594,7 @@ namespace exprtk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~vecarith_valvec_node()
|
~vec_binop_valvec_node()
|
||||||
{
|
{
|
||||||
delete[] data_;
|
delete[] data_;
|
||||||
delete temp_;
|
delete temp_;
|
||||||
|
@ -21646,7 +21666,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
invalid_state_ = false;
|
invalid_state_ = false;
|
||||||
|
|
||||||
const std::string err_param_seq = s.substr(start,end - start);
|
const std::string err_param_seq = s.substr(start,end - start);
|
||||||
|
|
||||||
parser_.
|
parser_.
|
||||||
set_error(
|
set_error(
|
||||||
|
@ -21667,7 +21687,7 @@ namespace exprtk
|
||||||
param_seq_list_ = param_seq_list;
|
param_seq_list_ = param_seq_list;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const std::string err_param_seq = s.substr(start,s.size() - start);
|
const std::string err_param_seq = s.substr(start,s.size() - start);
|
||||||
|
|
||||||
parser_.
|
parser_.
|
||||||
set_error(
|
set_error(
|
||||||
|
@ -24282,7 +24302,7 @@ namespace exprtk
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_vector_eqineq_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2])
|
inline bool is_vector_eqineq_logic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2])
|
||||||
{
|
{
|
||||||
if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1]))
|
if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1]))
|
||||||
return false;
|
return false;
|
||||||
|
@ -24294,7 +24314,13 @@ namespace exprtk
|
||||||
(details::e_gte == operation) ||
|
(details::e_gte == operation) ||
|
||||||
(details::e_eq == operation) ||
|
(details::e_eq == operation) ||
|
||||||
(details::e_ne == operation) ||
|
(details::e_ne == operation) ||
|
||||||
(details::e_equal == operation)
|
(details::e_equal == operation) ||
|
||||||
|
(details::e_and == operation) ||
|
||||||
|
(details::e_nand == operation) ||
|
||||||
|
(details:: e_or == operation) ||
|
||||||
|
(details:: e_nor == operation) ||
|
||||||
|
(details:: e_xor == operation) ||
|
||||||
|
(details::e_xnor == operation)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24328,8 +24354,8 @@ namespace exprtk
|
||||||
return synthesize_swap_expression(branch);
|
return synthesize_swap_expression(branch);
|
||||||
else if (is_assignment_operation(operation))
|
else if (is_assignment_operation(operation))
|
||||||
return synthesize_assignment_operation_expression(operation,branch);
|
return synthesize_assignment_operation_expression(operation,branch);
|
||||||
else if (is_vector_eqineq_operation(operation,branch))
|
else if (is_vector_eqineq_logic_operation(operation,branch))
|
||||||
return synthesize_veceqineq_operation_expression(operation,branch);
|
return synthesize_veceqineqlogic_operation_expression(operation,branch);
|
||||||
else if (is_vector_arithmetic_operation(operation,branch))
|
else if (is_vector_arithmetic_operation(operation,branch))
|
||||||
return synthesize_vecarithmetic_operation_expression(operation,branch);
|
return synthesize_vecarithmetic_operation_expression(operation,branch);
|
||||||
else if (is_shortcircuit_expression(operation))
|
else if (is_shortcircuit_expression(operation))
|
||||||
|
@ -25778,28 +25804,37 @@ namespace exprtk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline expression_node_ptr synthesize_veceqineq_operation_expression(const details::operator_type& operation,
|
inline expression_node_ptr synthesize_veceqineqlogic_operation_expression(const details::operator_type& operation,
|
||||||
expression_node_ptr (&branch)[2])
|
expression_node_ptr (&branch)[2])
|
||||||
{
|
{
|
||||||
const bool is_b0_ivec = details::is_ivector_node(branch[0]);
|
const bool is_b0_ivec = details::is_ivector_node(branch[0]);
|
||||||
const bool is_b1_ivec = details::is_ivector_node(branch[1]);
|
const bool is_b1_ivec = details::is_ivector_node(branch[1]);
|
||||||
|
|
||||||
|
#define batch_eqineq_logic_case \
|
||||||
|
case_stmt(details:: e_lt,details:: lt_op) \
|
||||||
|
case_stmt(details:: e_lte,details:: lte_op) \
|
||||||
|
case_stmt(details:: e_gt,details:: gt_op) \
|
||||||
|
case_stmt(details:: e_gte,details:: gte_op) \
|
||||||
|
case_stmt(details:: e_eq,details:: eq_op) \
|
||||||
|
case_stmt(details:: e_ne,details:: ne_op) \
|
||||||
|
case_stmt(details::e_equal,details::equal_op) \
|
||||||
|
case_stmt(details:: e_and, details::and_op) \
|
||||||
|
case_stmt(details:: e_nand, details::nand_op) \
|
||||||
|
case_stmt(details:: e_or, details:: or_op) \
|
||||||
|
case_stmt(details:: e_nor, details:: nor_op) \
|
||||||
|
case_stmt(details:: e_xor, details:: xor_op) \
|
||||||
|
case_stmt(details:: e_xnor, details::xnor_op) \
|
||||||
|
|
||||||
if (is_b0_ivec && is_b1_ivec)
|
if (is_b0_ivec && is_b1_ivec)
|
||||||
{
|
{
|
||||||
switch (operation)
|
switch (operation)
|
||||||
{
|
{
|
||||||
#define case_stmt(op0,op1) \
|
#define case_stmt(op0,op1) \
|
||||||
case op0 : return node_allocator_-> \
|
case op0 : return node_allocator_-> \
|
||||||
template allocate_rrr<typename details::vecarith_vecvec_node<Type,op1<Type> > > \
|
template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
|
||||||
(operation,branch[0],branch[1]); \
|
(operation,branch[0],branch[1]); \
|
||||||
|
|
||||||
case_stmt(details:: e_lt,details:: lt_op)
|
batch_eqineq_logic_case
|
||||||
case_stmt(details:: e_lte,details:: lte_op)
|
|
||||||
case_stmt(details:: e_gt,details:: gt_op)
|
|
||||||
case_stmt(details:: e_gte,details:: gte_op)
|
|
||||||
case_stmt(details:: e_eq,details:: eq_op)
|
|
||||||
case_stmt(details:: e_ne,details:: ne_op)
|
|
||||||
case_stmt(details::e_equal,details::equal_op)
|
|
||||||
#undef case_stmt
|
#undef case_stmt
|
||||||
default : return error_node();
|
default : return error_node();
|
||||||
}
|
}
|
||||||
|
@ -25808,18 +25843,12 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
switch (operation)
|
switch (operation)
|
||||||
{
|
{
|
||||||
#define case_stmt(op0,op1) \
|
#define case_stmt(op0,op1) \
|
||||||
case op0 : return node_allocator_-> \
|
case op0 : return node_allocator_-> \
|
||||||
template allocate_rrr<typename details::vecarith_vecval_node<Type,op1<Type> > > \
|
template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
|
||||||
(operation,branch[0],branch[1]); \
|
(operation,branch[0],branch[1]); \
|
||||||
|
|
||||||
case_stmt(details:: e_lt,details:: lt_op)
|
batch_eqineq_logic_case
|
||||||
case_stmt(details:: e_lte,details:: lte_op)
|
|
||||||
case_stmt(details:: e_gt,details:: gt_op)
|
|
||||||
case_stmt(details:: e_gte,details:: gte_op)
|
|
||||||
case_stmt(details:: e_eq,details:: eq_op)
|
|
||||||
case_stmt(details:: e_ne,details:: ne_op)
|
|
||||||
case_stmt(details::e_equal,details::equal_op)
|
|
||||||
#undef case_stmt
|
#undef case_stmt
|
||||||
default : return error_node();
|
default : return error_node();
|
||||||
}
|
}
|
||||||
|
@ -25828,24 +25857,20 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
switch (operation)
|
switch (operation)
|
||||||
{
|
{
|
||||||
#define case_stmt(op0,op1) \
|
#define case_stmt(op0,op1) \
|
||||||
case op0 : return node_allocator_-> \
|
case op0 : return node_allocator_-> \
|
||||||
template allocate_rrr<typename details::vecarith_valvec_node<Type,op1<Type> > > \
|
template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
|
||||||
(operation,branch[0],branch[1]); \
|
(operation,branch[0],branch[1]); \
|
||||||
|
|
||||||
case_stmt(details:: e_lt,details:: lt_op)
|
batch_eqineq_logic_case
|
||||||
case_stmt(details:: e_lte,details:: lte_op)
|
|
||||||
case_stmt(details:: e_gt,details:: gt_op)
|
|
||||||
case_stmt(details:: e_gte,details:: gte_op)
|
|
||||||
case_stmt(details:: e_eq,details:: eq_op)
|
|
||||||
case_stmt(details:: e_ne,details:: ne_op)
|
|
||||||
case_stmt(details::e_equal,details::equal_op)
|
|
||||||
#undef case_stmt
|
#undef case_stmt
|
||||||
default : return error_node();
|
default : return error_node();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return error_node();
|
return error_node();
|
||||||
|
|
||||||
|
#undef batch_eqineq_logic_case
|
||||||
}
|
}
|
||||||
|
|
||||||
inline expression_node_ptr synthesize_vecarithmetic_operation_expression(const details::operator_type& operation,
|
inline expression_node_ptr synthesize_vecarithmetic_operation_expression(const details::operator_type& operation,
|
||||||
|
@ -25865,10 +25890,10 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
switch (operation)
|
switch (operation)
|
||||||
{
|
{
|
||||||
#define case_stmt(op0,op1) \
|
#define case_stmt(op0,op1) \
|
||||||
case op0 : return node_allocator_-> \
|
case op0 : return node_allocator_-> \
|
||||||
template allocate_rrr<typename details::vecarith_vecvec_node<Type,op1<Type> > > \
|
template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
|
||||||
(operation,branch[0],branch[1]); \
|
(operation,branch[0],branch[1]); \
|
||||||
|
|
||||||
vector_ops
|
vector_ops
|
||||||
case_stmt(details::e_pow,details:: pow_op)
|
case_stmt(details::e_pow,details:: pow_op)
|
||||||
|
@ -25880,10 +25905,10 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
switch (operation)
|
switch (operation)
|
||||||
{
|
{
|
||||||
#define case_stmt(op0,op1) \
|
#define case_stmt(op0,op1) \
|
||||||
case op0 : return node_allocator_-> \
|
case op0 : return node_allocator_-> \
|
||||||
template allocate_rrr<typename details::vecarith_vecval_node<Type,op1<Type> > > \
|
template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
|
||||||
(operation,branch[0],branch[1]); \
|
(operation,branch[0],branch[1]); \
|
||||||
|
|
||||||
vector_ops
|
vector_ops
|
||||||
case_stmt(details::e_pow,details:: pow_op)
|
case_stmt(details::e_pow,details:: pow_op)
|
||||||
|
@ -25895,10 +25920,10 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
switch (operation)
|
switch (operation)
|
||||||
{
|
{
|
||||||
#define case_stmt(op0,op1) \
|
#define case_stmt(op0,op1) \
|
||||||
case op0 : return node_allocator_-> \
|
case op0 : return node_allocator_-> \
|
||||||
template allocate_rrr<typename details::vecarith_valvec_node<Type,op1<Type> > > \
|
template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
|
||||||
(operation,branch[0],branch[1]); \
|
(operation,branch[0],branch[1]); \
|
||||||
|
|
||||||
vector_ops
|
vector_ops
|
||||||
#undef case_stmt
|
#undef case_stmt
|
||||||
|
|
|
@ -183,7 +183,7 @@ bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const double pi = 3.14159265358979323846;
|
const double pi = 3.141592653589793238462643383279502;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct native
|
struct native
|
||||||
|
|
|
@ -37,7 +37,7 @@ void square_wave()
|
||||||
" (1/21)*sin(42*pi*f*t)+(1/23)*sin(46*pi*f*t)+"
|
" (1/21)*sin(42*pi*f*t)+(1/23)*sin(46*pi*f*t)+"
|
||||||
" (1/25)*sin(50*pi*f*t)+(1/27)*sin(54*pi*f*t))";
|
" (1/25)*sin(50*pi*f*t)+(1/27)*sin(54*pi*f*t))";
|
||||||
|
|
||||||
static const T pi = T(3.14159265358979323846);
|
static const T pi = T(3.141592653589793238462643383279502);
|
||||||
|
|
||||||
T f = pi / T(10);
|
T f = pi / T(10);
|
||||||
T t = T(0);
|
T t = T(0);
|
||||||
|
|
|
@ -36,7 +36,7 @@ void square_wave2()
|
||||||
" }; "
|
" }; "
|
||||||
" r *= a * (4 / pi); ";
|
" r *= a * (4 / pi); ";
|
||||||
|
|
||||||
static const T pi = T(3.14159265358979323846);
|
static const T pi = T(3.141592653589793238462643383279502);
|
||||||
|
|
||||||
T f = pi / T(10);
|
T f = pi / T(10);
|
||||||
T t = T(0);
|
T t = T(0);
|
||||||
|
|
|
@ -61,7 +61,7 @@ void savitzky_golay_filter()
|
||||||
std::vector<T> v_in;
|
std::vector<T> v_in;
|
||||||
std::vector<T> v_out;
|
std::vector<T> v_out;
|
||||||
|
|
||||||
const T pi = T(3.141592653589793238462);
|
const T pi = T(3.141592653589793238462643383279502);
|
||||||
|
|
||||||
srand(static_cast<unsigned int>(time(0)));
|
srand(static_cast<unsigned int>(time(0)));
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ struct rnd_01 : public exprtk::ifunction<T>
|
||||||
inline T operator()()
|
inline T operator()()
|
||||||
{
|
{
|
||||||
// Note: Do not use this in production
|
// Note: Do not use this in production
|
||||||
return T(::rand() / T(RAND_MAX + 1));
|
// Result is in the interval [0,1)
|
||||||
|
return T(::rand() / T(RAND_MAX + 1.0));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ void monte_carlo_pi()
|
||||||
|
|
||||||
const T approximate_pi = expression.value();
|
const T approximate_pi = expression.value();
|
||||||
|
|
||||||
const T real_pi = T(3.141592653589793238462);
|
const T real_pi = T(3.141592653589793238462643383279502); // or close enough...
|
||||||
|
|
||||||
printf("pi ~ %20.17f\terror: %20.17f\n",
|
printf("pi ~ %20.17f\terror: %20.17f\n",
|
||||||
approximate_pi,
|
approximate_pi,
|
||||||
|
|
|
@ -29,7 +29,12 @@
|
||||||
#include "exprtk.hpp"
|
#include "exprtk.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef exprtk_test_float32_type
|
||||||
|
typedef float numeric_type;
|
||||||
|
#else
|
||||||
typedef double numeric_type;
|
typedef double numeric_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef std::pair<std::string,numeric_type> test_t;
|
typedef std::pair<std::string,numeric_type> test_t;
|
||||||
|
|
||||||
static const test_t global_test_list[] =
|
static const test_t global_test_list[] =
|
||||||
|
@ -2750,7 +2755,7 @@ inline bool run_test04()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const T pi = T(3.14159265358979323846);
|
const T pi = T(3.141592653589793238462643383279502);
|
||||||
const T increment = T(0.0001);
|
const T increment = T(0.0001);
|
||||||
|
|
||||||
while ((x <= T(+1000)) && (y <= T(+1000)))
|
while ((x <= T(+1000)) && (y <= T(+1000)))
|
||||||
|
@ -2815,7 +2820,7 @@ inline bool run_test05()
|
||||||
expression_list.push_back(e);
|
expression_list.push_back(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T pi = T(3.14159265358979323846);
|
const T pi = T(3.141592653589793238462643383279502);
|
||||||
const T increment = T(0.001);
|
const T increment = T(0.001);
|
||||||
|
|
||||||
while ((x <= T(+1000)) && (y <= T(+1000)))
|
while ((x <= T(+1000)) && (y <= T(+1000)))
|
||||||
|
@ -2878,7 +2883,7 @@ inline bool run_test06()
|
||||||
|
|
||||||
T total_area1 = exprtk::integrate(expression,x,T(-1),T(1));
|
T total_area1 = exprtk::integrate(expression,x,T(-1),T(1));
|
||||||
T total_area2 = exprtk::integrate(expression,"x",T(-1),T(1));
|
T total_area2 = exprtk::integrate(expression,"x",T(-1),T(1));
|
||||||
const T pi = T(3.14159265358979323846);
|
const T pi = T(3.141592653589793238462643383279502);
|
||||||
|
|
||||||
if (not_equal(total_area1,total_area2,T(0.000001)))
|
if (not_equal(total_area1,total_area2,T(0.000001)))
|
||||||
{
|
{
|
||||||
|
@ -3196,12 +3201,16 @@ struct myfunc : public exprtk::ifunction<T>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
double foo1(double v0) { return v0; }
|
#define define_free_functions(Type) \
|
||||||
double foo2(double v0, double v1) { return v0 + v1; }
|
Type foo1(Type v0) { return v0; } \
|
||||||
double foo3(double v0, double v1, double v2) { return v0 + v1 + v2; }
|
Type foo2(Type v0, Type v1) { return v0 + v1; } \
|
||||||
double foo4(double v0, double v1, double v2, double v3) { return v0 + v1 + v2 + v3; }
|
Type foo3(Type v0, Type v1, Type v2) { return v0 + v1 + v2; } \
|
||||||
double foo5(double v0, double v1, double v2, double v3, double v4) { return v0 + v1 + v2 + v3 + v4; }
|
Type foo4(Type v0, Type v1, Type v2, Type v3) { return v0 + v1 + v2 + v3; } \
|
||||||
double foo6(double v0, double v1, double v2, double v3, double v4, double v5) { return v0 + v1 + v2 + v3 + v4 + v5; }
|
Type foo5(Type v0, Type v1, Type v2, Type v3, Type v4) { return v0 + v1 + v2 + v3 + v4; } \
|
||||||
|
Type foo6(Type v0, Type v1, Type v2, Type v3, Type v4, Type v5) { return v0 + v1 + v2 + v3 + v4 + v5; } \
|
||||||
|
|
||||||
|
define_free_functions(numeric_type)
|
||||||
|
#undef define_free_functions
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool run_test09()
|
inline bool run_test09()
|
||||||
|
@ -3267,7 +3276,7 @@ inline bool run_test09()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const T pi = T(3.141592653589793238462);
|
const T pi = T(3.141592653589793238462643383279502);
|
||||||
|
|
||||||
T result = expression.value();
|
T result = expression.value();
|
||||||
|
|
||||||
|
|
47
readme.txt
47
readme.txt
|
@ -1269,12 +1269,13 @@ with vectors:
|
||||||
(b) Exponentiation: vector ^ scalar
|
(b) Exponentiation: vector ^ scalar
|
||||||
(c) Assignment: :=, +=, -=, *=, /=, %=, <=>
|
(c) Assignment: :=, +=, -=, *=, /=, %=, <=>
|
||||||
(d) Inequalities: <, <=, >, >=, ==, =, equal
|
(d) Inequalities: <, <=, >, >=, ==, =, equal
|
||||||
(e) Unary operations:
|
(e) Boolean logic: and, nand, nor, or, xnor, xor
|
||||||
|
(f) Unary operations:
|
||||||
abs, acos, acosh, asin, asinh, atan, atanh, ceil, cos, cosh,
|
abs, acos, acosh, asin, asinh, atan, atanh, ceil, cos, cosh,
|
||||||
cot, csc, deg2grad, deg2rad, erf, erfc, exp, expm1, floor,
|
cot, csc, deg2grad, deg2rad, erf, erfc, exp, expm1, floor,
|
||||||
frac, grad2deg, log, log10, log1p, log2, rad2deg, round, sec,
|
frac, grad2deg, log, log10, log1p, log2, rad2deg, round, sec,
|
||||||
sgn, sin, sinc, sinh, sqrt, swap, tan, tanh, trunc
|
sgn, sin, sinc, sinh, sqrt, swap, tan, tanh, trunc
|
||||||
(f) Aggregate and Reduce operations:
|
(g) Aggregate and Reduce operations:
|
||||||
avg, max, min, mul, sum
|
avg, max, min, mul, sum
|
||||||
|
|
||||||
Note: When one of the above described operations is being performed
|
Note: When one of the above described operations is being performed
|
||||||
|
@ -1315,6 +1316,7 @@ not a vector but rather a single value.
|
||||||
avg(3x + 1) == 7
|
avg(3x + 1) == 7
|
||||||
min(1 / x) == (1 / 3)
|
min(1 / x) == (1 / 3)
|
||||||
max(x / 2) == (3 / 2)
|
max(x / 2) == (3 / 2)
|
||||||
|
sum(x > 0 and x < 5) == x[]
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -2487,6 +2489,16 @@ in the event of a failed compilation.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Assuming the following expression '2 + (3 / log(1 + x))' which uses a
|
||||||
|
variable named 'x' that has not been registered with the appropriate
|
||||||
|
symbol_table instance and is not a locally defined variable, once
|
||||||
|
compiled the above denoted post compilation error handling code shall
|
||||||
|
produce the following output:
|
||||||
|
|
||||||
|
Error: ERR184 - Undefined symbol: 'x'
|
||||||
|
Err No.:00 Pos:17 Type:[Syntax] Msg: ERR184 - Undefined symbol: 'x'
|
||||||
|
|
||||||
|
|
||||||
For expressions comprised of multiple lines, the error position
|
For expressions comprised of multiple lines, the error position
|
||||||
provided in the parser_error object can be converted into a pair of
|
provided in the parser_error object can be converted into a pair of
|
||||||
line and column numbers by invoking the 'update_error' function as is
|
line and column numbers by invoking the 'update_error' function as is
|
||||||
|
@ -2730,9 +2742,40 @@ into account when using ExprTk:
|
||||||
(x + y) / (x - y);
|
(x + y) / (x - y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(30) For performance considerations, one should assume the actions
|
||||||
|
of expression, symbol table and parser instance instantiation
|
||||||
|
and destruction, and the expression compilation process itself
|
||||||
|
to be of high latency. Hence none of them should be part of any
|
||||||
|
performance critical code paths, and should instead occur
|
||||||
|
entirely either before or after such code paths.
|
||||||
|
|
||||||
|
(31) Before jumping in and using ExprTk, do take the time to peruse
|
||||||
|
the documentation and all of the examples, both in the main and
|
||||||
|
the extras distributions. Having an informed general view of
|
||||||
|
what can and can't be done, and how something should be done
|
||||||
|
with ExprTk, will likely result in a far more productive and
|
||||||
|
enjoyable programming experience.
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
[21 - SIMPLE EXPRTK EXAMPLE]
|
[21 - SIMPLE EXPRTK EXAMPLE]
|
||||||
|
The following is a simple yet complete example demonstrating typical
|
||||||
|
usage of the ExprTk Library. The example instantiates a symbol table
|
||||||
|
object, adding to it three variables named x, y and z, and a custom
|
||||||
|
user defined function, that accepts only two parameters, named myfunc.
|
||||||
|
The example then proceeds to instantiate an expression object and
|
||||||
|
register to it the symbol table instance.
|
||||||
|
|
||||||
|
A parser is then instantiated, and the string representation of the
|
||||||
|
expression and the expression object are passed to the parser's
|
||||||
|
compile method for compilation. If an error occurred during
|
||||||
|
compilation, the compile method will return false, leading to a series
|
||||||
|
of error diagnostics being printed to stdout. Otherwise the newly
|
||||||
|
compiled expression is evaluated by invoking the expression object's
|
||||||
|
value method, and subsequently printing the result of the computation
|
||||||
|
to stdout.
|
||||||
|
|
||||||
|
|
||||||
--- snip ---
|
--- snip ---
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
Loading…
Reference in New Issue