C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html

This commit is contained in:
Arash Partow 2016-08-30 11:00:17 +10:00
parent 379317db93
commit ed5eec1836
3 changed files with 60 additions and 335 deletions

View File

@ -9222,284 +9222,6 @@ namespace exprtk
bool initialised_;
};
template <typename T, typename Operation>
class eqineq_vecvec_node : public binary_node <T>,
public vector_interface<T>
{
public:
typedef expression_node<T>* expression_ptr;
typedef vector_node<T>* vector_node_ptr;
eqineq_vecvec_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
: binary_node<T>(opr,branch0,branch1),
vec0_node_ptr_(0),
vec1_node_ptr_(0),
vec_size_ (0),
initialised_(false)
{
if (is_vector_node(binary_node<T>::branch_[0].first))
{
vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
}
else if (is_ivector_node(binary_node<T>::branch_[0].first))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
{
vec0_node_ptr_ = vi->vec();
}
}
if (is_vector_node(binary_node<T>::branch_[1].first))
{
vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
}
else if (is_ivector_node(binary_node<T>::branch_[1].first))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
{
vec1_node_ptr_ = vi->vec();
}
}
if (vec0_node_ptr_ && vec1_node_ptr_)
{
vec_size_ = std::min(vec0_node_ptr_->ref().size(),
vec1_node_ptr_->ref().size());
initialised_ = true;
}
}
inline T value() const
{
if (initialised_)
{
binary_node<T>::branch_[0].first->value();
binary_node<T>::branch_[1].first->value();
T* vec0 = vec0_node_ptr_->ref().data();
T* vec1 = vec1_node_ptr_->ref().data();
for (std::size_t i = 0; i < vec_size_; ++i)
{
if (std::equal_to<T>()(T(0),Operation::process(vec0[i],vec1[i])))
{
return T(0);
}
}
return T(1);
}
else
return std::numeric_limits<T>::quiet_NaN();
}
vector_node_ptr vec() const
{
return vec0_node_ptr_;
}
vector_node_ptr vec()
{
return vec0_node_ptr_;
}
inline typename expression_node<T>::node_type type() const
{
return expression_node<T>::e_vecvecineq;
}
std::size_t size() const
{
return vec_size_;
}
private:
vector_node<T>* vec0_node_ptr_;
vector_node<T>* vec1_node_ptr_;
std::size_t vec_size_;
bool initialised_;
};
template <typename T, typename Operation>
class eqineq_vecval_node : public binary_node <T>,
public vector_interface<T>
{
public:
typedef expression_node<T>* expression_ptr;
typedef vector_node<T>* vector_node_ptr;
eqineq_vecval_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
: binary_node<T>(opr,branch0,branch1),
vec_node_ptr_(0),
vec_size_ (0)
{
if (is_vector_node(binary_node<T>::branch_[0].first))
{
vec_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
}
else if (is_ivector_node(binary_node<T>::branch_[0].first))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
{
vec_node_ptr_ = vi->vec();
}
}
if (vec_node_ptr_)
{
vec_size_ = vec_node_ptr_->ref().size();
}
}
inline T value() const
{
if (vec_node_ptr_)
{
binary_node<T>::branch_[0].first->value();
T v = binary_node<T>::branch_[1].first->value();
T* vec = vec_node_ptr_->ref().data();
for (std::size_t i = 0; i < vec_size_; ++i)
{
if (std::equal_to<T>()(T(0),Operation::process(vec[i],v)))
{
return T(0);
}
}
return T(1);
}
else
return std::numeric_limits<T>::quiet_NaN();
}
vector_node_ptr vec() const
{
return vec_node_ptr_;
}
vector_node_ptr vec()
{
return vec_node_ptr_;
}
inline typename expression_node<T>::node_type type() const
{
return expression_node<T>::e_vecvalineq;
}
std::size_t size() const
{
return vec_size_;
}
private:
vector_node<T>* vec_node_ptr_;
std::size_t vec_size_;
};
template <typename T, typename Operation>
class eqineq_valvec_node : public binary_node <T>,
public vector_interface<T>
{
public:
typedef expression_node<T>* expression_ptr;
typedef vector_node<T>* vector_node_ptr;
eqineq_valvec_node(const operator_type& opr,
expression_ptr branch0,
expression_ptr branch1)
: binary_node<T>(opr,branch0,branch1),
vec_node_ptr_(0),
vec_size_ (0)
{
if (is_vector_node(binary_node<T>::branch_[1].first))
{
vec_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
}
else if (is_ivector_node(binary_node<T>::branch_[1].first))
{
vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
{
vec_node_ptr_ = vi->vec();
}
}
if (vec_node_ptr_)
{
vec_size_ = vec_node_ptr_->ref().size();
}
}
inline T value() const
{
if (vec_node_ptr_)
{
T v = binary_node<T>::branch_[0].first->value();
binary_node<T>::branch_[1].first->value();
T* vec = vec_node_ptr_->ref().data();
for (std::size_t i = 0; i < vec_size_; ++i)
{
if (std::equal_to<T>()(T(0),Operation::process(v,vec[i])))
{
return T(0);
}
}
return T(1);
}
else
return std::numeric_limits<T>::quiet_NaN();
}
vector_node_ptr vec() const
{
return vec_node_ptr_;
}
vector_node_ptr vec()
{
return vec_node_ptr_;
}
inline typename expression_node<T>::node_type type() const
{
return expression_node<T>::e_valvecineq;
}
std::size_t size() const
{
return vec_size_;
}
private:
vector_node<T>* vec_node_ptr_;
std::size_t vec_size_;
};
template <typename T, typename Operation>
class vecarith_vecvec_node : public binary_node <T>,
public vector_interface<T>
@ -9772,7 +9494,7 @@ namespace exprtk
#undef exprtk_loop
#undef case_stmt
return (vec0_node_ptr_->ref().data())[0];
return ((*temp_).data())[0];
}
else
return std::numeric_limits<T>::quiet_NaN();
@ -11210,6 +10932,16 @@ namespace exprtk
static inline details::operator_type operation() { return details::e_eq; }
};
template <typename T>
struct equal_op : public opr_base<T>
{
typedef typename opr_base<T>::Type Type;
static inline T process(Type t1, Type t2) { return (numeric::equal<T>(t1,t2) ? T(1) : T(0)); }
static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; }
static inline details::operator_type operation() { return details::e_equal; }
};
template <typename T>
struct ne_op : public opr_base<T>
{
@ -22472,7 +22204,7 @@ namespace exprtk
if (scope_element::e_vector == se.type)
{
if ((initialiser = parse_expression()))
if (0 != (initialiser = parse_expression()))
vec_initilizer_list.push_back(initialiser);
else
return error_node();
@ -22482,7 +22214,7 @@ namespace exprtk
{
lodge_symbol(current_token().value,e_st_vector);
if ((initialiser = parse_expression()))
if (0 != (initialiser = parse_expression()))
vec_initilizer_list.push_back(initialiser);
else
return error_node();
@ -24561,7 +24293,8 @@ namespace exprtk
(details::e_gt == operation) ||
(details::e_gte == operation) ||
(details::e_eq == operation) ||
(details::e_ne == operation)
(details::e_ne == operation) ||
(details::e_equal == operation)
);
}
@ -26057,7 +25790,7 @@ namespace exprtk
{
#define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
template allocate_rrr<typename details::eqineq_vecvec_node<Type,op1<Type> > > \
template allocate_rrr<typename details::vecarith_vecvec_node<Type,op1<Type> > > \
(operation,branch[0],branch[1]); \
case_stmt(details:: e_lt,details:: lt_op)
@ -26066,6 +25799,7 @@ namespace exprtk
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
default : return error_node();
}
@ -26076,7 +25810,7 @@ namespace exprtk
{
#define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
template allocate_rrr<typename details::eqineq_vecval_node<Type,op1<Type> > > \
template allocate_rrr<typename details::vecarith_vecval_node<Type,op1<Type> > > \
(operation,branch[0],branch[1]); \
case_stmt(details:: e_lt,details:: lt_op)
@ -26085,6 +25819,7 @@ namespace exprtk
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
default : return error_node();
}
@ -26095,7 +25830,7 @@ namespace exprtk
{
#define case_stmt(op0,op1) \
case op0 : return node_allocator_-> \
template allocate_rrr<typename details::eqineq_valvec_node<Type,op1<Type> > > \
template allocate_rrr<typename details::vecarith_valvec_node<Type,op1<Type> > > \
(operation,branch[0],branch[1]); \
case_stmt(details:: e_lt,details:: lt_op)
@ -26104,6 +25839,7 @@ namespace exprtk
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
default : return error_node();
}
@ -34386,9 +34122,9 @@ namespace exprtk
namespace information
{
static const char* library = "Mathematical Expression Toolkit";
static const char* version = "2.7182818284590452353602874713526624"
"977572470936999595749669676277240766";
static const char* date = "20160606";
static const char* version = "2.718281828459045235360287471352662497"
"75724709369995957496696762772407663035";
static const char* date = "20160909";
static inline std::string data()
{

View File

@ -4199,9 +4199,9 @@ inline bool run_test10()
"var x[3] := {1,2,3}; var y := 5; y + 1 > x ",
"var x[3] := {1,1,1}; var y := 1; y == x ",
"var x[3] := {1,1,1}; var y := 2; y - 1 == x",
"var x[3] := {1,2,3}; var y := 5; (x += 1) < y ",
"var x[3] := {1,2,3}; var y := 3; (x -= 1) < y + 1 ",
"var x[3] := {1,2,3}; var y := 5; (x -= 1) <= y ",
"var x[3] := {1,2,3}; var y := 5; equal(true,(x += 1) < y) ",
"var x[3] := {1,2,3}; var y := 3; equal(true,(x -= 1) < y + 1)",
"var x[3] := {1,2,3}; var y := 5; equal(true,(x -= 1) <= y) ",
"var x[3] := {2,2,2}; var y := 1; (x -= 1) == y ",
"var x[3] := {1,2,3}; var y := 5; y > (x += 1) ",
"var x[3] := {1,2,3}; var y := 5; y + 1 > (x += 1) ",

View File

@ -1268,7 +1268,7 @@ with vectors:
(a) Arithmetic: +, -, *, /, %
(b) Exponentiation: vector ^ scalar
(c) Assignment: :=, +=, -=, *=, /=, %=, <=>
(d) Inequalities: <, <=, >, >=, ==, =
(d) Inequalities: <, <=, >, >=, ==, =, equal
(e) Unary operations:
abs, acos, acosh, asin, asinh, atan, atanh, ceil, cos, cosh,
cot, csc, deg2grad, deg2rad, erf, erfc, exp, expm1, floor,
@ -1304,17 +1304,6 @@ the previously mentioned dot-product computation expression:
}
Note: In the scenario of inequalities between two vectors, the result
is not a vector but rather a singular variable denoting a boolean
state of either 'true' or 'false' depending on the nature of the
inequality.
var x[3] := { 1, 1, 1 };
var y[3] := { 3, 2, 1 };
y > x == false
Note: When the aggregate operations denoted above are used in
conjunction with a vector or vector expression, the return value is
not a vector but rather a single value.