C++ Mathematical Expression Library (ExprTk) https://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
1a27b9e394
commit
4bae39ed67
154
exprtk.hpp
154
exprtk.hpp
|
@ -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())
|
||||
|
|
139
exprtk_test.cpp
139
exprtk_test.cpp
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue