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

This commit is contained in:
Arash Partow 2016-09-29 08:53:05 +10:00
parent 1a27b9e394
commit 4bae39ed67
2 changed files with 292 additions and 1 deletions

View File

@ -3919,6 +3919,81 @@ namespace exprtk
};
}
template <typename T>
class vector_view
{
public:
typedef T* data_ptr_t;
vector_view(data_ptr_t data, const std::size_t& size)
: size_(size),
data_(data),
data_ref_(0)
{}
vector_view(const vector_view<T>& vv)
: size_(vv.size_),
data_(vv.data_),
data_ref_(0)
{}
inline void rebase(data_ptr_t data)
{
data_ = data;
if (data_ref_)
{
(*data_ref_) = data;
}
}
inline data_ptr_t data() const
{
return data_;
}
inline std::size_t size() const
{
return size_;
}
inline const T& operator[](const std::size_t index) const
{
return data_[index];
}
inline T& operator[](const std::size_t index)
{
return data_[index];
}
void set_ref(data_ptr_t* data_ref)
{
data_ref_ = data_ref;
}
private:
std::size_t size_;
data_ptr_t data_;
data_ptr_t* data_ref_;
};
template <typename T>
inline vector_view<T> make_vector_view(T* data,
const std::size_t size, const std::size_t offset = 0)
{
return vector_view<T>(data + offset,size);
}
template <typename T>
inline vector_view<T> make_vector_view(std::vector<T>& v,
const std::size_t size, const std::size_t offset = 0)
{
return vector_view<T>(v.data() + offset,size);
}
template <typename T> class results_context;
template <typename T>
@ -4442,6 +4517,11 @@ namespace exprtk
return control_block_->size;
}
inline data_t& ref()
{
return control_block_->data;
}
inline void dump() const
{
#ifdef exprtk_enable_debugging
@ -4983,6 +5063,8 @@ namespace exprtk
return value_at(0);
}
virtual void set_ref(value_ptr*) {}
protected:
virtual value_ptr value_at(const std::size_t&) const = 0;
@ -5052,6 +5134,40 @@ namespace exprtk
sequence_t& sequence_;
};
class vector_view_impl : public vector_holder_base
{
public:
typedef exprtk::vector_view<Type> vector_view_t;
vector_view_impl(vector_view_t& vec_view)
: vec_view_(vec_view)
{}
void set_ref(value_ptr* ref)
{
vec_view_.set_ref(ref);
}
protected:
value_ptr value_at(const std::size_t& index) const
{
return (index < vec_view_.size()) ? (&vec_view_[index]) : const_value_ptr(0);
}
std::size_t vector_size() const
{
return vec_view_.size();
}
private:
vector_view_impl operator=(const vector_view_impl&);
vector_view_t& vec_view_;
};
public:
typedef typename details::vec_data_store<Type> vds_t;
@ -5069,6 +5185,10 @@ namespace exprtk
: vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec))
{}
vector_holder(exprtk::vector_view<Type>& vec)
: vector_holder_base_(new(buffer)vector_view_impl(vec))
{}
inline value_ptr operator[](const std::size_t& index) const
{
return (*vector_holder_base_)[index];
@ -5084,6 +5204,11 @@ namespace exprtk
return vector_holder_base_->data();
}
void set_ref(value_ptr* ref)
{
return vector_holder_base_->set_ref(ref);
}
private:
mutable vector_holder_base* vector_holder_base_;
@ -6666,7 +6791,9 @@ namespace exprtk
vector_node(vector_holder_t* vh)
: vector_holder_(vh),
vds_((*vector_holder_).size(),(*vector_holder_)[0])
{}
{
vector_holder_->set_ref(&vds_.ref());
}
vector_node(const vds_t& vds, vector_holder_t* vh)
: vector_holder_(vh),
@ -15382,6 +15509,14 @@ namespace exprtk
}
};
struct tie_vecview
{
static inline std::pair<bool,vector_t*> make(exprtk::vector_view<T>& v, const bool is_const = false)
{
return std::make_pair(is_const,new vector_t(v));
}
};
struct tie_stddeq
{
template <typename Allocator>
@ -15408,6 +15543,11 @@ namespace exprtk
return add_impl<tie_stdvec,std::vector<T,Allocator>&>(symbol_name,v,is_const);
}
inline bool add(const std::string& symbol_name, exprtk::vector_view<T>& v, const bool is_const = false)
{
return add_impl<tie_vecview,exprtk::vector_view<T>&>(symbol_name,v,is_const);
}
template <typename Allocator>
inline bool add(const std::string& symbol_name, std::deque<T,Allocator>& v, const bool is_const = false)
{
@ -16268,6 +16408,18 @@ namespace exprtk
return local_data().vector_store.add(vector_name,v);
}
inline bool add_vector(const std::string& vector_name, exprtk::vector_view<T>& v)
{
if (!valid())
return false;
else if (!valid_symbol(vector_name))
return false;
else if (symbol_exists(vector_name))
return false;
else
return local_data().vector_store.add(vector_name,v);
}
inline bool remove_variable(const std::string& variable_name, const bool delete_node = true)
{
if (!valid())

View File

@ -1796,6 +1796,7 @@ inline bool run_test01()
for (std::size_t r = 0; r < rounds; ++r)
{
bool loop_result = true;
for (std::size_t i = 0; i < expr_list_size; ++i)
{
T v[] = { T(0.0), T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) };
@ -1832,6 +1833,66 @@ inline bool run_test01()
T result = expression.value();
if (not_equal(result,T(1)))
{
printf("run_test01() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
expr_list[i].c_str(),
(double)1.0,
(double)result);
loop_result = false;
}
}
if (!loop_result)
{
return false;
}
}
for (std::size_t r = 0; r < rounds; ++r)
{
bool loop_result = true;
for (std::size_t i = 0; i < expr_list_size; ++i)
{
T v_[] = { T(0.0), T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) };
T index_[] = { T(0) , T(1) , T(2) , T(3) , T(4) , T(5) };
T x = T(6.6);
T y = T(7.7);
T z = T(8.8);
exprtk::vector_view<T> v = exprtk::make_vector_view(v_ ,6);
exprtk::vector_view<T> index = exprtk::make_vector_view(index_,6);
exprtk::symbol_table<T> symbol_table;
symbol_table.add_variable("x",x);
symbol_table.add_variable("y",y);
symbol_table.add_variable("z",z);
symbol_table.add_vector ("v",v);
symbol_table.add_vector ("i",index);
exprtk::expression<T> expression;
expression.register_symbol_table(symbol_table);
{
exprtk::parser<T> parser;
if (!parser.compile(expr_list[i],expression))
{
printf("run_test01() - Error: %s Expression: %s\n",
parser.error().c_str(),
expr_list[i].c_str());
loop_result = false;
continue;
}
}
T result = expression.value();
if (not_equal(result,T(1)))
{
printf("run_test01() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
@ -6125,6 +6186,84 @@ inline bool run_test18()
return false;
}
{
bool failure = false;
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::vector<T> v0 { 0, 0, 0, 0, 0, 0, 0 };
std::vector<T> v1 { 0, 2, 4, 6, 8, 10, 12 };
std::vector<T> v2 { 1, 3, 5, 7, 9, 11, 13 };
std::vector<T> v3 { 0, 1, 2, 3, 4, 5, 6 };
const std::string expr_string = "sum(v + 1)";
exprtk::vector_view<T> v = exprtk::make_vector_view(v0,v0.size());
symbol_table_t symbol_table;
symbol_table.add_vector("v",v);
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
if (!parser.compile(expr_string,expression))
{
printf("run_test18() - Error: %s\tExpression: %s\n",
parser.error().c_str(),
expr_string.c_str());
failure = true;
}
T sum = { T(0) };
sum = expression.value();
if (not_equal(sum,T(7)))
{
printf("run_test18() - Error in evaluation! (6) Expression: %s\n",
expr_string.c_str());
failure = true;
}
v.rebase(v1.data());
sum = expression.value();
if (not_equal(sum,T(49)))
{
printf("run_test18() - Error in evaluation! (7) Expression: %s\n",
expr_string.c_str());
failure = true;
}
v.rebase(v2.data());
sum = expression.value();
if (not_equal(sum,T(56)))
{
printf("run_test18() - Error in evaluation! (8) Expression: %s\n",
expr_string.c_str());
failure = true;
}
v.rebase(v3.data());
sum = expression.value();
if (not_equal(sum,T(28)))
{
printf("run_test18() - Error in evaluation! (9) Expression: %s\n",
expr_string.c_str());
failure = true;
}
if (failure)
return false;
}
return true;
}