C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
4351c7b0a1
commit
b1a89fc96a
548
exprtk.hpp
548
exprtk.hpp
|
@ -1562,7 +1562,24 @@ namespace exprtk
|
||||||
e_sf39 = 1039,
|
e_sf39 = 1039,
|
||||||
e_sf40 = 1040,
|
e_sf40 = 1040,
|
||||||
e_sf41 = 1041,
|
e_sf41 = 1041,
|
||||||
e_sf42 = 1042
|
e_sf42 = 1042,
|
||||||
|
e_sf43 = 1043,
|
||||||
|
e_sf44 = 1044,
|
||||||
|
e_sf45 = 1045,
|
||||||
|
e_sf46 = 1046,
|
||||||
|
e_sf47 = 1047,
|
||||||
|
e_sf48 = 1048,
|
||||||
|
e_sf49 = 1049,
|
||||||
|
e_sf50 = 1050,
|
||||||
|
e_sf51 = 1051,
|
||||||
|
e_sf52 = 1052,
|
||||||
|
e_sf53 = 1053,
|
||||||
|
e_sf54 = 1054,
|
||||||
|
e_sf55 = 1055,
|
||||||
|
e_sf56 = 1056,
|
||||||
|
e_sf57 = 1057,
|
||||||
|
e_sf58 = 1058
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace numeric
|
namespace numeric
|
||||||
|
@ -1983,18 +2000,21 @@ namespace exprtk
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N, typename T>
|
template <typename T, std::size_t N>
|
||||||
inline void cleanup_branches(std::pair<expression_node<T>*,bool> (&branch)[N])
|
struct cleanup_branches
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < N; ++i)
|
static inline void execute(std::pair<expression_node<T>*,bool> (&branch)[N])
|
||||||
{
|
{
|
||||||
if (branch[i].first && branch[i].second)
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
delete branch[i].first;
|
if (branch[i].first && branch[i].second)
|
||||||
branch[i].first = 0;
|
{
|
||||||
|
delete branch[i].first;
|
||||||
|
branch[i].first = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class binary_node : public expression_node<T>
|
class binary_node : public expression_node<T>
|
||||||
|
@ -2014,7 +2034,7 @@ namespace exprtk
|
||||||
|
|
||||||
~binary_node()
|
~binary_node()
|
||||||
{
|
{
|
||||||
cleanup_branches<2>(branch_);
|
cleanup_branches<T,2>::execute(branch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T value() const
|
inline T value() const
|
||||||
|
@ -2069,7 +2089,7 @@ namespace exprtk
|
||||||
|
|
||||||
~trinary_node()
|
~trinary_node()
|
||||||
{
|
{
|
||||||
cleanup_branches<3>(branch_);
|
cleanup_branches<T,3>::execute(branch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T value() const
|
inline T value() const
|
||||||
|
@ -2121,7 +2141,7 @@ namespace exprtk
|
||||||
|
|
||||||
~quaternary_node()
|
~quaternary_node()
|
||||||
{
|
{
|
||||||
cleanup_branches<4>(branch_);
|
cleanup_branches<T,4>::execute(branch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T value() const
|
inline T value() const
|
||||||
|
@ -2173,7 +2193,7 @@ namespace exprtk
|
||||||
|
|
||||||
~quinary_node()
|
~quinary_node()
|
||||||
{
|
{
|
||||||
cleanup_branches<5>(branch_);
|
cleanup_branches<T,5>::execute(branch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T value() const
|
inline T value() const
|
||||||
|
@ -2227,7 +2247,7 @@ namespace exprtk
|
||||||
|
|
||||||
~senary_node()
|
~senary_node()
|
||||||
{
|
{
|
||||||
cleanup_branches<6>(branch_);
|
cleanup_branches<T,6>::execute(branch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T value() const
|
inline T value() const
|
||||||
|
@ -2456,6 +2476,9 @@ namespace exprtk
|
||||||
std::string stringvar_node<T>::null_value = std::string("");
|
std::string stringvar_node<T>::null_value = std::string("");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <typename T, std::size_t N> inline T axn(T a, T x) { return a * exprtk::details::numeric::fast_exp<T,N>::result(x); } // a*x^n
|
||||||
|
template <typename T, std::size_t N> inline T axnb(T a, T x, T b) { return a * exprtk::details::numeric::fast_exp<T,N>::result(x) + b; } // a*x^n+b
|
||||||
|
|
||||||
template <typename T> struct sf00_op { static inline T process(const T& x, const T& y, const T& z) { return (x + y) / z; } };
|
template <typename T> struct sf00_op { static inline T process(const T& x, const T& y, const T& z) { return (x + y) / z; } };
|
||||||
template <typename T> struct sf01_op { static inline T process(const T& x, const T& y, const T& z) { return (x + y) * z; } };
|
template <typename T> struct sf01_op { static inline T process(const T& x, const T& y, const T& z) { return (x + y) * z; } };
|
||||||
template <typename T> struct sf02_op { static inline T process(const T& x, const T& y, const T& z) { return (x - y) / z; } };
|
template <typename T> struct sf02_op { static inline T process(const T& x, const T& y, const T& z) { return (x - y) / z; } };
|
||||||
|
@ -2474,31 +2497,47 @@ namespace exprtk
|
||||||
template <typename T> struct sf15_op { static inline T process(const T& x, const T& y, const T& z) { return z / (x / y); } };
|
template <typename T> struct sf15_op { static inline T process(const T& x, const T& y, const T& z) { return z / (x / y); } };
|
||||||
template <typename T> struct sf16_op { static inline T process(const T& x, const T& y, const T& z) { return z - (x / y); } };
|
template <typename T> struct sf16_op { static inline T process(const T& x, const T& y, const T& z) { return z - (x / y); } };
|
||||||
template <typename T> struct sf17_op { static inline T process(const T& x, const T& y, const T& z) { return z - (x / y); } };
|
template <typename T> struct sf17_op { static inline T process(const T& x, const T& y, const T& z) { return z - (x / y); } };
|
||||||
template <typename T> struct sf18_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x + y) / z); } };
|
template <typename T> struct sf18_op { static inline T process(const T& x, const T& y, const T& z) { return axnb<T,2>(x,y,z); } }; //x * y^2 + z
|
||||||
template <typename T> struct sf19_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x + y) * z); } };
|
template <typename T> struct sf19_op { static inline T process(const T& x, const T& y, const T& z) { return axnb<T,3>(x,y,z); } }; //x * y^3 + z
|
||||||
template <typename T> struct sf20_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x - y) / z); } };
|
template <typename T> struct sf20_op { static inline T process(const T& x, const T& y, const T& z) { return axnb<T,4>(x,y,z); } }; //x * y^4 + z
|
||||||
template <typename T> struct sf21_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x - y) * z); } };
|
template <typename T> struct sf21_op { static inline T process(const T& x, const T& y, const T& z) { return axnb<T,5>(x,y,z); } }; //x * y^5 + z
|
||||||
template <typename T> struct sf22_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x * y) / z); } };
|
template <typename T> struct sf22_op { static inline T process(const T& x, const T& y, const T& z) { return axnb<T,6>(x,y,z); } }; //x * y^6 + z
|
||||||
template <typename T> struct sf23_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x * y) * z); } };
|
template <typename T> struct sf23_op { static inline T process(const T& x, const T& y, const T& z) { return axnb<T,7>(x,y,z); } }; //x * y^7 + z
|
||||||
template <typename T> struct sf24_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x / y) + z); } };
|
template <typename T> struct sf24_op { static inline T process(const T& x, const T& y, const T& z) { return axnb<T,8>(x,y,z); } }; //x * y^8 + z
|
||||||
template <typename T> struct sf25_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x / y) / z); } };
|
template <typename T> struct sf25_op { static inline T process(const T& x, const T& y, const T& z) { return axnb<T,9>(x,y,z); } }; //x * y^9 + z
|
||||||
template <typename T> struct sf26_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x / y) * z); } };
|
template <typename T> struct sf26_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x + y) / z); } };
|
||||||
template <typename T> struct sf27_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x + y) / z); } };
|
template <typename T> struct sf27_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x + y) * z); } };
|
||||||
template <typename T> struct sf28_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x + y) * z); } };
|
template <typename T> struct sf28_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x - y) / z); } };
|
||||||
template <typename T> struct sf29_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x - y) / z); } };
|
template <typename T> struct sf29_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x - y) * z); } };
|
||||||
template <typename T> struct sf30_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x - y) * z); } };
|
template <typename T> struct sf30_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x * y) / z); } };
|
||||||
template <typename T> struct sf31_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x * y) / z); } };
|
template <typename T> struct sf31_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x * y) * z); } };
|
||||||
template <typename T> struct sf32_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x * y) * z); } };
|
template <typename T> struct sf32_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x / y) + z); } };
|
||||||
template <typename T> struct sf33_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x / y) / z); } };
|
template <typename T> struct sf33_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x / y) / z); } };
|
||||||
template <typename T> struct sf34_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x / y) * z); } };
|
template <typename T> struct sf34_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x / y) * z); } };
|
||||||
template <typename T> struct sf35_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x + y) * z) - w; } };
|
template <typename T> struct sf35_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x + y) / z); } };
|
||||||
template <typename T> struct sf36_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x - y) * z) - w; } };
|
template <typename T> struct sf36_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x + y) * z); } };
|
||||||
template <typename T> struct sf37_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x * y) * z) - w; } };
|
template <typename T> struct sf37_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x - y) / z); } };
|
||||||
template <typename T> struct sf38_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x / y) * z) - w; } };
|
template <typename T> struct sf38_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x - y) * z); } };
|
||||||
template <typename T> struct sf39_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x + y) / z) - w; } };
|
template <typename T> struct sf39_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x * y) / z); } };
|
||||||
template <typename T> struct sf40_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x - y) / z) - w; } };
|
template <typename T> struct sf40_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x * y) * z); } };
|
||||||
template <typename T> struct sf41_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x * y) / z) - w; } };
|
template <typename T> struct sf41_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x / y) / z); } };
|
||||||
template <typename T> struct sf42_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x / y) / z) - w; } };
|
template <typename T> struct sf42_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x / y) * z); } };
|
||||||
|
template <typename T> struct sf43_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x + y) * z) - w; } };
|
||||||
|
template <typename T> struct sf44_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x - y) * z) - w; } };
|
||||||
|
template <typename T> struct sf45_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x * y) * z) - w; } };
|
||||||
|
template <typename T> struct sf46_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x / y) * z) - w; } };
|
||||||
|
template <typename T> struct sf47_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x + y) / z) - w; } };
|
||||||
|
template <typename T> struct sf48_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x - y) / z) - w; } };
|
||||||
|
template <typename T> struct sf49_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x * y) / z) - w; } };
|
||||||
|
template <typename T> struct sf50_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x / y) / z) - w; } };
|
||||||
|
template <typename T> struct sf51_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn<T,2>(x,y) + axn<T,2>(z,w); } }; //x*y^2+z*w^2
|
||||||
|
template <typename T> struct sf52_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn<T,3>(x,y) + axn<T,3>(z,w); } }; //x*y^3+z*w^3
|
||||||
|
template <typename T> struct sf53_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn<T,4>(x,y) + axn<T,4>(z,w); } }; //x*y^4+z*w^4
|
||||||
|
template <typename T> struct sf54_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn<T,5>(x,y) + axn<T,5>(z,w); } }; //x*y^5+z*w^5
|
||||||
|
template <typename T> struct sf55_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn<T,6>(x,y) + axn<T,6>(z,w); } }; //x*y^6+z*w^6
|
||||||
|
template <typename T> struct sf56_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn<T,7>(x,y) + axn<T,7>(z,w); } }; //x*y^7+z*w^7
|
||||||
|
template <typename T> struct sf57_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn<T,8>(x,y) + axn<T,8>(z,w); } }; //x*y^8+z*w^8
|
||||||
|
template <typename T> struct sf58_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn<T,9>(x,y) + axn<T,9>(z,w); } }; //x*y^9+z*w^9
|
||||||
|
|
||||||
template <typename T, typename SpecialFunction>
|
template <typename T, typename SpecialFunction>
|
||||||
class sf3_node : public trinary_node<T>
|
class sf3_node : public trinary_node<T>
|
||||||
|
@ -2577,70 +2616,192 @@ namespace exprtk
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename IFunction>
|
template <typename T, typename IFunction, std::size_t N>
|
||||||
class function_node : public expression_node<T>
|
class function_N_node : public expression_node<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
//function of N paramters.
|
||||||
typedef expression_node<T>* expression_ptr;
|
typedef expression_node<T>* expression_ptr;
|
||||||
typedef std::pair<expression_ptr,bool> branch_t;
|
typedef std::pair<expression_ptr,bool> branch_t;
|
||||||
typedef IFunction ifunction;
|
typedef IFunction ifunction;
|
||||||
|
|
||||||
static const std::size_t N = 10;
|
function_N_node(ifunction* func)
|
||||||
|
: function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0)),
|
||||||
function_node(ifunction* func)
|
parameter_count_(func->param_count)
|
||||||
: function(func)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~function_node()
|
~function_N_node()
|
||||||
{
|
{
|
||||||
cleanup_branches<N>(branch_);
|
cleanup_branches<T,N>::execute(branch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t NumBranches>
|
template <std::size_t NumBranches>
|
||||||
bool init_branches(expression_ptr (&b)[NumBranches])
|
bool init_branches(expression_ptr (&b)[NumBranches])
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < NumBranches; ++i)
|
//Needed for incompetent and broken msvc compiler versions
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4127)
|
||||||
|
#endif
|
||||||
|
if (N != NumBranches)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (b[i])
|
for (std::size_t i = 0; i < NumBranches; ++i)
|
||||||
branch_[i] = std::make_pair(b[i],branch_deletable(b[i]));
|
{
|
||||||
else
|
if (b[i])
|
||||||
return false;
|
branch_[i] = std::make_pair(b[i],branch_deletable(b[i]));
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator <(const function_node<T,IFunction>& fn) const
|
inline bool operator <(const function_N_node<T,IFunction,N>& fn) const
|
||||||
{
|
{
|
||||||
return this < (&fn);
|
return this < (&fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T value() const
|
inline T value() const
|
||||||
{
|
{
|
||||||
T v[N];
|
//Needed for incompetent and broken msvc compiler versions
|
||||||
if (function->param_count)
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4127)
|
||||||
|
#endif
|
||||||
|
if ((0 == function_) || (0 == N))
|
||||||
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
else
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < function->param_count; ++i)
|
T v[N];
|
||||||
|
evaluate_branches<T,N>::execute(v,branch_);
|
||||||
|
return invoke<T,N>::execute(*function_,v);
|
||||||
|
}
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T_, std::size_t BranchCount>
|
||||||
|
struct evaluate_branches
|
||||||
|
{
|
||||||
|
static inline void execute(T_ (&v)[BranchCount], const branch_t (&b)[BranchCount])
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < BranchCount; ++i)
|
||||||
{
|
{
|
||||||
v[i] = branch_[i].first->value();
|
v[i] = b[i].first->value();
|
||||||
}
|
|
||||||
switch (function->param_count)
|
|
||||||
{
|
|
||||||
case 1 : return (*function)(v[0]);
|
|
||||||
case 2 : return (*function)(v[0],v[1]);
|
|
||||||
case 3 : return (*function)(v[0],v[1],v[2]);
|
|
||||||
case 4 : return (*function)(v[0],v[1],v[2],v[3]);
|
|
||||||
case 5 : return (*function)(v[0],v[1],v[2],v[3],v[4]);
|
|
||||||
case 6 : return (*function)(v[0],v[1],v[2],v[3],v[4],v[5]);
|
|
||||||
case 7 : return (*function)(v[0],v[1],v[2],v[3],v[4],v[5],v[6]);
|
|
||||||
case 8 : return (*function)(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]);
|
|
||||||
case 9 : return (*function)(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]);
|
|
||||||
case 10 : return (*function)(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9]);
|
|
||||||
default : return std::numeric_limits<T>::quiet_NaN();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T_>
|
||||||
|
struct evaluate_branches <T_,5>
|
||||||
|
{
|
||||||
|
static inline void execute(T_ (&v)[5], const branch_t (&b)[5])
|
||||||
|
{
|
||||||
|
v[0] = b[0].first->value();
|
||||||
|
v[1] = b[1].first->value();
|
||||||
|
v[2] = b[2].first->value();
|
||||||
|
v[3] = b[3].first->value();
|
||||||
|
v[4] = b[4].first->value();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T_>
|
||||||
|
struct evaluate_branches <T_,4>
|
||||||
|
{
|
||||||
|
static inline void execute(T_ (&v)[4], const branch_t (&b)[4])
|
||||||
|
{
|
||||||
|
v[0] = b[0].first->value();
|
||||||
|
v[1] = b[1].first->value();
|
||||||
|
v[2] = b[2].first->value();
|
||||||
|
v[3] = b[3].first->value();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T_>
|
||||||
|
struct evaluate_branches <T_,3>
|
||||||
|
{
|
||||||
|
static inline void execute(T_ (&v)[3], const branch_t (&b)[3])
|
||||||
|
{
|
||||||
|
v[0] = b[0].first->value();
|
||||||
|
v[1] = b[1].first->value();
|
||||||
|
v[2] = b[2].first->value();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T_>
|
||||||
|
struct evaluate_branches <T_,2>
|
||||||
|
{
|
||||||
|
static inline void execute(T_ (&v)[2], const branch_t (&b)[2])
|
||||||
|
{
|
||||||
|
v[0] = b[0].first->value();
|
||||||
|
v[1] = b[1].first->value();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T_>
|
||||||
|
struct evaluate_branches <T_,1>
|
||||||
|
{
|
||||||
|
static inline void execute(T_ (&v)[1], const branch_t (&b)[1])
|
||||||
|
{
|
||||||
|
v[0] = b[0].first->value();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T_, std::size_t ParamCount>
|
||||||
|
struct invoke { static inline T execute(ifunction*, branch_t (&)[ParamCount]) { return std::numeric_limits<T_>::quiet_NaN(); } };
|
||||||
|
|
||||||
|
template <typename T_> struct invoke<T_,10> { static inline T_ execute(ifunction& f, T_ (&v)[10]) { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9]); } };
|
||||||
|
template <typename T_> struct invoke<T_, 9> { static inline T_ execute(ifunction& f, T_ (&v)[ 9]) { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]); } };
|
||||||
|
template <typename T_> struct invoke<T_, 8> { static inline T_ execute(ifunction& f, T_ (&v)[ 8]) { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]); } };
|
||||||
|
template <typename T_> struct invoke<T_, 7> { static inline T_ execute(ifunction& f, T_ (&v)[ 7]) { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6]); } };
|
||||||
|
template <typename T_> struct invoke<T_, 6> { static inline T_ execute(ifunction& f, T_ (&v)[ 6]) { return f(v[0],v[1],v[2],v[3],v[4],v[5]); } };
|
||||||
|
template <typename T_> struct invoke<T_, 5> { static inline T_ execute(ifunction& f, T_ (&v)[ 5]) { return f(v[0],v[1],v[2],v[3],v[4]); } };
|
||||||
|
template <typename T_> struct invoke<T_, 4> { static inline T_ execute(ifunction& f, T_ (&v)[ 4]) { return f(v[0],v[1],v[2],v[3]); } };
|
||||||
|
template <typename T_> struct invoke<T_, 3> { static inline T_ execute(ifunction& f, T_ (&v)[ 3]) { return f(v[0],v[1],v[2]); } };
|
||||||
|
template <typename T_> struct invoke<T_, 2> { static inline T_ execute(ifunction& f, T_ (&v)[ 2]) { return f(v[0],v[1]); } };
|
||||||
|
template <typename T_> struct invoke<T_, 1> { static inline T_ execute(ifunction& f, T_ (&v)[ 1]) { return f(v[0]); } };
|
||||||
|
|
||||||
|
inline typename expression_node<T>::node_type type() const
|
||||||
|
{
|
||||||
|
return expression_node<T>::e_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ifunction* function_;
|
||||||
|
std::size_t parameter_count_;
|
||||||
|
branch_t branch_[N];
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename IFunction>
|
||||||
|
class function_N_node<T,IFunction,0> : public expression_node<T>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef expression_node<T>* expression_ptr;
|
||||||
|
typedef IFunction ifunction;
|
||||||
|
|
||||||
|
function_N_node(ifunction* func)
|
||||||
|
: function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline bool operator <(const function_N_node<T,IFunction,0>& fn) const
|
||||||
|
{
|
||||||
|
return this < (&fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T value() const
|
||||||
|
{
|
||||||
|
if (0 == function_)
|
||||||
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
else
|
else
|
||||||
return (*function)();
|
return (*function_)();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline typename expression_node<T>::node_type type() const
|
inline typename expression_node<T>::node_type type() const
|
||||||
|
@ -2650,8 +2811,8 @@ namespace exprtk
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ifunction* function;
|
ifunction* function_;
|
||||||
branch_t branch_[N];
|
std::size_t parameter_count_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -3843,7 +4004,7 @@ namespace exprtk
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Type, typename RawType>
|
template <typename Type, typename RawType>
|
||||||
struct type_store
|
struct type_store
|
||||||
{
|
{
|
||||||
typedef typename details::variable_node<T> variable_node_t;
|
typedef typename details::variable_node<T> variable_node_t;
|
||||||
|
@ -4745,6 +4906,7 @@ namespace exprtk
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ifunction <T> F;
|
typedef ifunction <T> F;
|
||||||
|
typedef ifunction <T> ifunction_t;
|
||||||
typedef details::expression_node <T> expression_node_t;
|
typedef details::expression_node <T> expression_node_t;
|
||||||
typedef details::literal_node <T> literal_node_t;
|
typedef details::literal_node <T> literal_node_t;
|
||||||
typedef details::string_literal_node<T> string_literal_node_t;
|
typedef details::string_literal_node<T> string_literal_node_t;
|
||||||
|
@ -4761,7 +4923,6 @@ namespace exprtk
|
||||||
typedef details::stringvar_node <T> stringvar_node_t;
|
typedef details::stringvar_node <T> stringvar_node_t;
|
||||||
#endif
|
#endif
|
||||||
typedef details::assignment_node <T> assignment_node_t;
|
typedef details::assignment_node <T> assignment_node_t;
|
||||||
typedef details::function_node <T,F> function_node_t;
|
|
||||||
typedef details::token <T> token_t;
|
typedef details::token <T> token_t;
|
||||||
typedef expression_node_t* expression_node_ptr;
|
typedef expression_node_t* expression_node_ptr;
|
||||||
|
|
||||||
|
@ -5139,10 +5300,10 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
//Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3)
|
//Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3)
|
||||||
const details::operator_type opt_type = details::operator_type(id + 1000);
|
const details::operator_type opt_type = details::operator_type(id + 1000);
|
||||||
const std::size_t NumberOfParameters = (id < (details::e_sf18 - 1000)) ? 3 : 4;
|
const std::size_t NumberOfParameters = (id < (details::e_sf26 - 1000)) ? 3 : 4;
|
||||||
expression_node_ptr branch3[3];
|
expression_node_ptr branch3[3];
|
||||||
expression_node_ptr branch4[4];
|
expression_node_ptr branch4[4];
|
||||||
expression_node_ptr* branch = (id < (details::e_sf18 - 1000)) ? &branch3[0] : &branch4[0];
|
expression_node_ptr* branch = (id < (details::e_sf26 - 1000)) ? &branch3[0] : &branch4[0];
|
||||||
expression_node_ptr result = 0;
|
expression_node_ptr result = 0;
|
||||||
std::fill_n(branch3,3,reinterpret_cast<expression_node_ptr>(0));
|
std::fill_n(branch3,3,reinterpret_cast<expression_node_ptr>(0));
|
||||||
std::fill_n(branch4,4,reinterpret_cast<expression_node_ptr>(0));
|
std::fill_n(branch4,4,reinterpret_cast<expression_node_ptr>(0));
|
||||||
|
@ -5772,6 +5933,14 @@ namespace exprtk
|
||||||
case_stmt(details::e_sf15,details::sf15_op)
|
case_stmt(details::e_sf15,details::sf15_op)
|
||||||
case_stmt(details::e_sf16,details::sf16_op)
|
case_stmt(details::e_sf16,details::sf16_op)
|
||||||
case_stmt(details::e_sf17,details::sf17_op)
|
case_stmt(details::e_sf17,details::sf17_op)
|
||||||
|
case_stmt(details::e_sf18,details::sf18_op)
|
||||||
|
case_stmt(details::e_sf19,details::sf19_op)
|
||||||
|
case_stmt(details::e_sf20,details::sf20_op)
|
||||||
|
case_stmt(details::e_sf21,details::sf21_op)
|
||||||
|
case_stmt(details::e_sf22,details::sf22_op)
|
||||||
|
case_stmt(details::e_sf23,details::sf23_op)
|
||||||
|
case_stmt(details::e_sf24,details::sf24_op)
|
||||||
|
case_stmt(details::e_sf25,details::sf25_op)
|
||||||
default : return error_node();
|
default : return error_node();
|
||||||
#undef case_stmt
|
#undef case_stmt
|
||||||
}
|
}
|
||||||
|
@ -5784,14 +5953,6 @@ namespace exprtk
|
||||||
switch (operation)
|
switch (operation)
|
||||||
{
|
{
|
||||||
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<details::sf4_node<Type,op1<Type> > >(operation,branch);
|
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<details::sf4_node<Type,op1<Type> > >(operation,branch);
|
||||||
case_stmt(details::e_sf18,details::sf18_op)
|
|
||||||
case_stmt(details::e_sf19,details::sf19_op)
|
|
||||||
case_stmt(details::e_sf20,details::sf20_op)
|
|
||||||
case_stmt(details::e_sf21,details::sf21_op)
|
|
||||||
case_stmt(details::e_sf22,details::sf22_op)
|
|
||||||
case_stmt(details::e_sf23,details::sf23_op)
|
|
||||||
case_stmt(details::e_sf24,details::sf24_op)
|
|
||||||
case_stmt(details::e_sf25,details::sf25_op)
|
|
||||||
case_stmt(details::e_sf26,details::sf26_op)
|
case_stmt(details::e_sf26,details::sf26_op)
|
||||||
case_stmt(details::e_sf27,details::sf27_op)
|
case_stmt(details::e_sf27,details::sf27_op)
|
||||||
case_stmt(details::e_sf28,details::sf28_op)
|
case_stmt(details::e_sf28,details::sf28_op)
|
||||||
|
@ -5809,15 +5970,33 @@ namespace exprtk
|
||||||
case_stmt(details::e_sf40,details::sf40_op)
|
case_stmt(details::e_sf40,details::sf40_op)
|
||||||
case_stmt(details::e_sf41,details::sf41_op)
|
case_stmt(details::e_sf41,details::sf41_op)
|
||||||
case_stmt(details::e_sf42,details::sf42_op)
|
case_stmt(details::e_sf42,details::sf42_op)
|
||||||
|
case_stmt(details::e_sf43,details::sf43_op)
|
||||||
|
case_stmt(details::e_sf44,details::sf44_op)
|
||||||
|
case_stmt(details::e_sf45,details::sf45_op)
|
||||||
|
case_stmt(details::e_sf46,details::sf46_op)
|
||||||
|
case_stmt(details::e_sf47,details::sf47_op)
|
||||||
|
case_stmt(details::e_sf48,details::sf48_op)
|
||||||
|
case_stmt(details::e_sf49,details::sf49_op)
|
||||||
|
case_stmt(details::e_sf50,details::sf50_op)
|
||||||
|
case_stmt(details::e_sf51,details::sf51_op)
|
||||||
|
case_stmt(details::e_sf52,details::sf52_op)
|
||||||
|
case_stmt(details::e_sf53,details::sf53_op)
|
||||||
|
case_stmt(details::e_sf54,details::sf54_op)
|
||||||
|
case_stmt(details::e_sf55,details::sf55_op)
|
||||||
|
case_stmt(details::e_sf56,details::sf56_op)
|
||||||
|
case_stmt(details::e_sf57,details::sf57_op)
|
||||||
|
case_stmt(details::e_sf58,details::sf58_op)
|
||||||
default : return error_node();
|
default : return error_node();
|
||||||
#undef case_stmt
|
#undef case_stmt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
inline expression_node_ptr function(typename function_node_t::ifunction* f, expression_node_ptr (&b)[N])
|
inline expression_node_ptr function(ifunction_t* f, expression_node_ptr (&b)[N])
|
||||||
{
|
{
|
||||||
expression_node_ptr result = synthesize_expression<function_node_t,N>(f,b);
|
typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
|
||||||
|
|
||||||
|
expression_node_ptr result = synthesize_expression<function_N_node_t,N>(f,b);
|
||||||
if (0 == result)
|
if (0 == result)
|
||||||
return error_node();
|
return error_node();
|
||||||
else
|
else
|
||||||
|
@ -5829,7 +6008,7 @@ namespace exprtk
|
||||||
return error_node();
|
return error_node();
|
||||||
else if (N != f->param_count)
|
else if (N != f->param_count)
|
||||||
return error_node();
|
return error_node();
|
||||||
function_node_t* func_node_ptr = dynamic_cast<function_node_t*>(result);
|
function_N_node_t* func_node_ptr = dynamic_cast<function_N_node_t*>(result);
|
||||||
if (func_node_ptr)
|
if (func_node_ptr)
|
||||||
{
|
{
|
||||||
if (func_node_ptr->init_branches(b))
|
if (func_node_ptr->init_branches(b))
|
||||||
|
@ -5842,9 +6021,10 @@ namespace exprtk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline expression_node_ptr function(typename function_node_t::ifunction* f)
|
inline expression_node_ptr function(ifunction_t* f)
|
||||||
{
|
{
|
||||||
return node_allocator_->allocate<function_node_t>(f);
|
typedef typename details::function_N_node<T,ifunction_t,0> function_N_node_t;
|
||||||
|
return node_allocator_->allocate<function_N_node_t>(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -6616,9 +6796,10 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
if (all_nodes_valid<N>(branch))
|
if (all_nodes_valid<N>(branch))
|
||||||
{
|
{
|
||||||
|
typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
|
||||||
//Attempt simple constant folding optimization.
|
//Attempt simple constant folding optimization.
|
||||||
expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f);
|
expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f);
|
||||||
dynamic_cast<function_node_t*>(expression_point)->init_branches(branch);
|
dynamic_cast<function_N_node_t*>(expression_point)->init_branches(branch);
|
||||||
if (is_constant_foldable<N>(branch))
|
if (is_constant_foldable<N>(branch))
|
||||||
{
|
{
|
||||||
Type v = expression_point->value();
|
Type v = expression_point->value();
|
||||||
|
@ -6743,11 +6924,19 @@ namespace exprtk
|
||||||
|
|
||||||
//Check for certain illegal sequences of characters.
|
//Check for certain illegal sequences of characters.
|
||||||
std::stack<char> bracket_stack;
|
std::stack<char> bracket_stack;
|
||||||
|
bool in_string = false;
|
||||||
for (std::size_t i = 0; i < (expression_string.size() - 1); ++i)
|
for (std::size_t i = 0; i < (expression_string.size() - 1); ++i)
|
||||||
{
|
{
|
||||||
char c0 = expression_string[i];
|
char c0 = expression_string[i];
|
||||||
char c1 = expression_string[i + 1];
|
char c1 = expression_string[i + 1];
|
||||||
if (details::is_invalid(c0))
|
if ('\'' == c0)
|
||||||
|
{
|
||||||
|
in_string = !in_string;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (in_string)
|
||||||
|
continue;
|
||||||
|
else if (details::is_invalid(c0))
|
||||||
{
|
{
|
||||||
set_error(std::string("parser::validate_expression() - invalid character: ") + c0);
|
set_error(std::string("parser::validate_expression() - invalid character: ") + c0);
|
||||||
return false;
|
return false;
|
||||||
|
@ -7022,6 +7211,175 @@ namespace exprtk
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
class polynomial : public ifunction<T>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
template <typename Type, std::size_t NumberOfCoefficients>
|
||||||
|
struct poly_impl { };
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct poly_impl <Type,9>
|
||||||
|
{
|
||||||
|
static inline T evaluate(const Type x,
|
||||||
|
const Type c9, const Type c8, const Type c7, const Type c6, const Type c5,
|
||||||
|
const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
|
||||||
|
{
|
||||||
|
//p(x) = c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0
|
||||||
|
return (((((((((c9 * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct poly_impl <Type,8>
|
||||||
|
{
|
||||||
|
static inline T evaluate(const Type x,
|
||||||
|
const Type c8, const Type c7, const Type c6, const Type c5, const Type c4,
|
||||||
|
const Type c3, const Type c2, const Type c1, const Type c0)
|
||||||
|
{
|
||||||
|
//p(x) = c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0
|
||||||
|
return ((((((((c8 * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct poly_impl <Type,7>
|
||||||
|
{
|
||||||
|
static inline T evaluate(const Type x,
|
||||||
|
const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
|
||||||
|
const Type c2, const Type c1, const Type c0)
|
||||||
|
{
|
||||||
|
//p(x) = c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0
|
||||||
|
return (((((((c7 * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct poly_impl <Type,6>
|
||||||
|
{
|
||||||
|
static inline T evaluate(const Type x,
|
||||||
|
const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
|
||||||
|
const Type c1, const Type c0)
|
||||||
|
{
|
||||||
|
//p(x) = c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0
|
||||||
|
return ((((((c6 * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct poly_impl <Type,5>
|
||||||
|
{
|
||||||
|
static inline T evaluate(const Type x,
|
||||||
|
const Type c5, const Type c4, const Type c3, const Type c2,
|
||||||
|
const Type c1, const Type c0)
|
||||||
|
{
|
||||||
|
//p(x) = c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0
|
||||||
|
return (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct poly_impl <Type,4>
|
||||||
|
{
|
||||||
|
static inline T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
|
||||||
|
{
|
||||||
|
//p(x) = c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0
|
||||||
|
return ((((c4 * x + c3) * x + c2) * x + c1) * x + c0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct poly_impl <Type,3>
|
||||||
|
{
|
||||||
|
static inline T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
|
||||||
|
{
|
||||||
|
//p(x) = c_3x^3 + c_2x^2 + c_1x^1 + c_0
|
||||||
|
return (((c3 * x + c2) * x + c1) * x + c0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct poly_impl <Type,2>
|
||||||
|
{
|
||||||
|
static inline T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
|
||||||
|
{
|
||||||
|
//p(x) = c_2x^2 + c_1x^1 + c_0
|
||||||
|
return ((c2 * x + c1) * x + c0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct poly_impl <Type,1>
|
||||||
|
{
|
||||||
|
static inline T evaluate(const Type x, const Type c1, const Type c0)
|
||||||
|
{
|
||||||
|
//p(x) = c_1x^1 + c_0
|
||||||
|
return (c1 * x + c0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
polynomial() : exprtk::ifunction<T>(N) {}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T& x, const T& c1, const T& c0)
|
||||||
|
{
|
||||||
|
return ((1 == N) ? poly_impl<T,1>::evaluate(x,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T& x, const T& c2, const T& c1, const T& c0)
|
||||||
|
{
|
||||||
|
return ((2 == N) ? poly_impl<T,2>::evaluate(x,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T& x, const T& c3, const T& c2, const T& c1, const T& c0)
|
||||||
|
{
|
||||||
|
return ((3 == N) ? poly_impl<T,3>::evaluate(x,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T& x, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
|
||||||
|
{
|
||||||
|
return ((4 == N) ? poly_impl<T,4>::evaluate(x,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T& x, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
|
||||||
|
{
|
||||||
|
return ((5 == N) ? poly_impl<T,5>::evaluate(x,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T& x, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
|
||||||
|
{
|
||||||
|
return ((6 == N) ? poly_impl<T,6>::evaluate(x,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T& x, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
|
||||||
|
{
|
||||||
|
return ((7 == N) ? poly_impl<T,7>::evaluate(x,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T& x, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
|
||||||
|
{
|
||||||
|
return ((8 == N) ? poly_impl<T,8>::evaluate(x,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()()
|
||||||
|
{
|
||||||
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T&)
|
||||||
|
{
|
||||||
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T&, const T&)
|
||||||
|
{
|
||||||
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool pgo_primer()
|
inline bool pgo_primer()
|
||||||
{
|
{
|
||||||
|
@ -7326,7 +7684,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
static const char* library = "Mathematical Expression Toolkit";
|
static const char* library = "Mathematical Expression Toolkit";
|
||||||
static const char* version = "2.71828182845904523536028";
|
static const char* version = "2.71828182845904523536028";
|
||||||
static const char* date = "20120408";
|
static const char* date = "20120505";
|
||||||
|
|
||||||
static inline std::string data()
|
static inline std::string data()
|
||||||
{
|
{
|
||||||
|
|
212
exprtk_test.cpp
212
exprtk_test.cpp
|
@ -635,31 +635,47 @@ static const test_t test_list[] =
|
||||||
test_t("equal($f15(1.1,2.2,3.3),(3.3/(1.1/2.2)))",1.0),
|
test_t("equal($f15(1.1,2.2,3.3),(3.3/(1.1/2.2)))",1.0),
|
||||||
test_t("equal($f16(1.1,2.2,3.3),(3.3-(1.1/2.2)))",1.0),
|
test_t("equal($f16(1.1,2.2,3.3),(3.3-(1.1/2.2)))",1.0),
|
||||||
test_t("equal($f17(1.1,2.2,3.3),(3.3-(1.1/2.2)))",1.0),
|
test_t("equal($f17(1.1,2.2,3.3),(3.3-(1.1/2.2)))",1.0),
|
||||||
test_t("equal($f18(1.1,2.2,3.3,4.4),(4.4+((1.1+2.2)/3.3)))",1.0),
|
test_t("equal($f18(1.1,2.2,3.3),(1.1*2.2^2+3.3))",1.0),
|
||||||
test_t("equal($f19(1.1,2.2,3.3,4.4),(4.4+((1.1+2.2)*3.3)))",1.0),
|
test_t("equal($f19(1.1,2.2,3.3),(1.1*2.2^3+3.3))",1.0),
|
||||||
test_t("equal($f20(1.1,2.2,3.3,4.4),(4.4+((1.1-2.2)/3.3)))",1.0),
|
test_t("equal($f20(1.1,2.2,3.3),(1.1*2.2^4+3.3))",1.0),
|
||||||
test_t("equal($f21(1.1,2.2,3.3,4.4),(4.4+((1.1-2.2)*3.3)))",1.0),
|
test_t("equal($f21(1.1,2.2,3.3),(1.1*2.2^5+3.3))",1.0),
|
||||||
test_t("equal($f22(1.1,2.2,3.3,4.4),(4.4+((1.1*2.2)/3.3)))",1.0),
|
test_t("equal($f22(1.1,2.2,3.3),(1.1*2.2^6+3.3))",1.0),
|
||||||
test_t("equal($f23(1.1,2.2,3.3,4.4),(4.4+((1.1*2.2)*3.3)))",1.0),
|
test_t("equal($f23(1.1,2.2,3.3),(1.1*2.2^7+3.3))",1.0),
|
||||||
test_t("equal($f24(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)+3.3)))",1.0),
|
test_t("equal($f24(1.1,2.2,3.3),(1.1*2.2^8+3.3))",1.0),
|
||||||
test_t("equal($f25(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)/3.3)))",1.0),
|
test_t("equal($f25(1.1,2.2,3.3),(1.1*2.2^9+3.3))",1.0),
|
||||||
test_t("equal($f26(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)*3.3)))",1.0),
|
test_t("equal($f26(1.1,2.2,3.3,4.4),(4.4+((1.1+2.2)/3.3)))",1.0),
|
||||||
test_t("equal($f27(1.1,2.2,3.3,4.4),(4.4-((1.1+2.2)/3.3)))",1.0),
|
test_t("equal($f27(1.1,2.2,3.3,4.4),(4.4+((1.1+2.2)*3.3)))",1.0),
|
||||||
test_t("equal($f28(1.1,2.2,3.3,4.4),(4.4-((1.1+2.2)*3.3)))",1.0),
|
test_t("equal($f28(1.1,2.2,3.3,4.4),(4.4+((1.1-2.2)/3.3)))",1.0),
|
||||||
test_t("equal($f29(1.1,2.2,3.3,4.4),(4.4-((1.1-2.2)/3.3)))",1.0),
|
test_t("equal($f29(1.1,2.2,3.3,4.4),(4.4+((1.1-2.2)*3.3)))",1.0),
|
||||||
test_t("equal($f30(1.1,2.2,3.3,4.4),(4.4-((1.1-2.2)*3.3)))",1.0),
|
test_t("equal($f30(1.1,2.2,3.3,4.4),(4.4+((1.1*2.2)/3.3)))",1.0),
|
||||||
test_t("equal($f31(1.1,2.2,3.3,4.4),(4.4-((1.1*2.2)/3.3)))",1.0),
|
test_t("equal($f31(1.1,2.2,3.3,4.4),(4.4+((1.1*2.2)*3.3)))",1.0),
|
||||||
test_t("equal($f32(1.1,2.2,3.3,4.4),(4.4-((1.1*2.2)*3.3)))",1.0),
|
test_t("equal($f32(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)+3.3)))",1.0),
|
||||||
test_t("equal($f33(1.1,2.2,3.3,4.4),(4.4-((1.1/2.2)/3.3)))",1.0),
|
test_t("equal($f33(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)/3.3)))",1.0),
|
||||||
test_t("equal($f34(1.1,2.2,3.3,4.4),(4.4-((1.1/2.2)*3.3)))",1.0),
|
test_t("equal($f34(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)*3.3)))",1.0),
|
||||||
test_t("equal($f35(1.1,2.2,3.3,4.4),(((1.1+2.2)*3.3)-4.4))",1.0),
|
test_t("equal($f35(1.1,2.2,3.3,4.4),(4.4-((1.1+2.2)/3.3)))",1.0),
|
||||||
test_t("equal($f36(1.1,2.2,3.3,4.4),(((1.1-2.2)*3.3)-4.4))",1.0),
|
test_t("equal($f36(1.1,2.2,3.3,4.4),(4.4-((1.1+2.2)*3.3)))",1.0),
|
||||||
test_t("equal($f37(1.1,2.2,3.3,4.4),(((1.1*2.2)*3.3)-4.4))",1.0),
|
test_t("equal($f37(1.1,2.2,3.3,4.4),(4.4-((1.1-2.2)/3.3)))",1.0),
|
||||||
test_t("equal($f38(1.1,2.2,3.3,4.4),(((1.1/2.2)*3.3)-4.4))",1.0),
|
test_t("equal($f38(1.1,2.2,3.3,4.4),(4.4-((1.1-2.2)*3.3)))",1.0),
|
||||||
test_t("equal($f39(1.1,2.2,3.3,4.4),(((1.1+2.2)/3.3)-4.4))",1.0),
|
test_t("equal($f39(1.1,2.2,3.3,4.4),(4.4-((1.1*2.2)/3.3)))",1.0),
|
||||||
test_t("equal($f40(1.1,2.2,3.3,4.4),(((1.1-2.2)/3.3)-4.4))",1.0),
|
test_t("equal($f40(1.1,2.2,3.3,4.4),(4.4-((1.1*2.2)*3.3)))",1.0),
|
||||||
test_t("equal($f41(1.1,2.2,3.3,4.4),(((1.1*2.2)/3.3)-4.4))",1.0),
|
test_t("equal($f41(1.1,2.2,3.3,4.4),(4.4-((1.1/2.2)/3.3)))",1.0),
|
||||||
test_t("equal($f42(1.1,2.2,3.3,4.4),(((1.1/2.2)/3.3)-4.4))",1.0),
|
test_t("equal($f42(1.1,2.2,3.3,4.4),(4.4-((1.1/2.2)*3.3)))",1.0),
|
||||||
|
test_t("equal($f43(1.1,2.2,3.3,4.4),(((1.1+2.2)*3.3)-4.4))",1.0),
|
||||||
|
test_t("equal($f44(1.1,2.2,3.3,4.4),(((1.1-2.2)*3.3)-4.4))",1.0),
|
||||||
|
test_t("equal($f45(1.1,2.2,3.3,4.4),(((1.1*2.2)*3.3)-4.4))",1.0),
|
||||||
|
test_t("equal($f46(1.1,2.2,3.3,4.4),(((1.1/2.2)*3.3)-4.4))",1.0),
|
||||||
|
test_t("equal($f47(1.1,2.2,3.3,4.4),(((1.1+2.2)/3.3)-4.4))",1.0),
|
||||||
|
test_t("equal($f48(1.1,2.2,3.3,4.4),(((1.1-2.2)/3.3)-4.4))",1.0),
|
||||||
|
test_t("equal($f49(1.1,2.2,3.3,4.4),(((1.1*2.2)/3.3)-4.4))",1.0),
|
||||||
|
test_t("equal($f50(1.1,2.2,3.3,4.4),(((1.1/2.2)/3.3)-4.4))",1.0),
|
||||||
|
test_t("equal($f51(1.1,2.2,3.3,4.4),(1.1*2.2^2+3.3*4.4^2))",1.0),
|
||||||
|
test_t("equal($f52(1.1,2.2,3.3,4.4),(1.1*2.2^3+3.3*4.4^3))",1.0),
|
||||||
|
test_t("equal($f53(1.1,2.2,3.3,4.4),(1.1*2.2^4+3.3*4.4^4))",1.0),
|
||||||
|
test_t("equal($f54(1.1,2.2,3.3,4.4),(1.1*2.2^5+3.3*4.4^5))",1.0),
|
||||||
|
test_t("equal($f55(1.1,2.2,3.3,4.4),(1.1*2.2^6+3.3*4.4^6))",1.0),
|
||||||
|
test_t("equal($f56(1.1,2.2,3.3,4.4),(1.1*2.2^7+3.3*4.4^7))",1.0),
|
||||||
|
test_t("equal($f57(1.1,2.2,3.3,4.4),(1.1*2.2^8+3.3*4.4^8))",1.0),
|
||||||
|
test_t("equal($f58(1.1,2.2,3.3,4.4),(1.1*2.2^9+3.3*4.4^9))",1.0),
|
||||||
test_t("1+2+3+4+5+6+7+8+9+0",45.0),
|
test_t("1+2+3+4+5+6+7+8+9+0",45.0),
|
||||||
test_t("1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0",45.0),
|
test_t("1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0",45.0),
|
||||||
test_t("1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + 0.0",45.0),
|
test_t("1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + 0.0",45.0),
|
||||||
|
@ -697,7 +713,9 @@ inline bool not_equal(const T& t1,
|
||||||
{
|
{
|
||||||
if (t1 != t1) return true;
|
if (t1 != t1) return true;
|
||||||
if (t2 != t2) return true;
|
if (t2 != t2) return true;
|
||||||
return std::abs(t1 - t2) > (std::max(T(1.0),std::max(std::abs(t1),std::abs(t2))) * epsilon);
|
T diff = std::abs(t1 - t2);
|
||||||
|
T eps_norm = (std::max(T(1.0),std::max(std::abs(t1),std::abs(t2))) * epsilon);
|
||||||
|
return diff > eps_norm;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -746,7 +764,7 @@ inline bool run_test00()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
struct test_xy
|
struct test_xy
|
||||||
{
|
{
|
||||||
test_xy(std::string e, const T& v0, const T& v1, const T& r)
|
test_xy(std::string e, const T& v0, const T& v1, const T& r)
|
||||||
|
@ -924,7 +942,7 @@ inline bool run_test01()
|
||||||
|
|
||||||
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_xy<T>);
|
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_xy<T>);
|
||||||
|
|
||||||
const std::size_t rounds = 1000;
|
const std::size_t rounds = 100;
|
||||||
for (std::size_t r = 0; r < rounds; ++r)
|
for (std::size_t r = 0; r < rounds; ++r)
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < test_list_size; ++i)
|
for (std::size_t i = 0; i < test_list_size; ++i)
|
||||||
|
@ -961,7 +979,7 @@ inline bool run_test01()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
struct test_ab
|
struct test_ab
|
||||||
{
|
{
|
||||||
test_ab(std::string e, const std::string& v0, const std::string& v1, const T& r)
|
test_ab(std::string e, const std::string& v0, const std::string& v1, const T& r)
|
||||||
|
@ -1040,12 +1058,19 @@ inline bool run_test02()
|
||||||
test_ab<T>("inrange(a,b,c)" ,"aaa","bbb",T(1.0)),
|
test_ab<T>("inrange(a,b,c)" ,"aaa","bbb",T(1.0)),
|
||||||
test_ab<T>("inrange(a,b,'ccc')" ,"aaa","bbb",T(1.0)),
|
test_ab<T>("inrange(a,b,'ccc')" ,"aaa","bbb",T(1.0)),
|
||||||
test_ab<T>("inrange('aaa',b,c)" ,"aaa","bbb",T(1.0)),
|
test_ab<T>("inrange('aaa',b,c)" ,"aaa","bbb",T(1.0)),
|
||||||
|
test_ab<T>("inrange('aaa',b,c)" ,"aaa","bbb",T(1.0)),
|
||||||
|
test_ab<T>("'!@#$%^&*([{}])-=' != ')]}{[(*&^%$#@!'","","",T(1.0)),
|
||||||
|
test_ab<T>("('!@#$%^&*([{}])-=') != (')]}{[(*&^%$#@!')","","",T(1.0)),
|
||||||
|
test_ab<T>("{[('a')]} == [{('a')}]","","",T(1.0)),
|
||||||
|
test_ab<T>("{[('!@#$%^&*([{}])-=')]} != [{(')]}{[(*&^%$#@!')}]","","",T(1.0)),
|
||||||
|
test_ab<T>("'!@#$%^&*([{}])-=' == '!@#$%^&*([{}])-='","","",T(1.0)),
|
||||||
|
test_ab<T>("('!@#$%^&*([{}])-=') == ('!@#$%^&*([{}])-=')","","",T(1.0)),
|
||||||
|
test_ab<T>("{[('!@#$%^&*([{}])-=')]} == [{('!@#$%^&*([{}])-=')}]","","",T(1.0))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_ab<T>);
|
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_ab<T>);
|
||||||
|
|
||||||
const std::size_t rounds = 10000;
|
const std::size_t rounds = 1000;
|
||||||
for (std::size_t r = 0; r < rounds; ++r)
|
for (std::size_t r = 0; r < rounds; ++r)
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < test_list_size; ++i)
|
for (std::size_t i = 0; i < test_list_size; ++i)
|
||||||
|
@ -1122,7 +1147,7 @@ inline bool run_test03()
|
||||||
|
|
||||||
static const std::size_t variable_list_size = sizeof(variable_list) / sizeof(std::string);
|
static const std::size_t variable_list_size = sizeof(variable_list) / sizeof(std::string);
|
||||||
|
|
||||||
static const std::size_t rounds = 10000;
|
static const std::size_t rounds = 1000;
|
||||||
|
|
||||||
for (std::size_t r = 0; r < rounds; ++r)
|
for (std::size_t r = 0; r < rounds; ++r)
|
||||||
{
|
{
|
||||||
|
@ -1409,46 +1434,62 @@ inline bool run_test08()
|
||||||
"equal($f15(x,y,z),(z/(x/y)))",
|
"equal($f15(x,y,z),(z/(x/y)))",
|
||||||
"equal($f16(x,y,z),(z-(x/y)))",
|
"equal($f16(x,y,z),(z-(x/y)))",
|
||||||
"equal($f17(x,y,z),(z-(x/y)))",
|
"equal($f17(x,y,z),(z-(x/y)))",
|
||||||
"equal($f18(x,y,z,w),(w+((x+y)/z)))",
|
"equal($f18(x,y,z),(x*y^2+z))",
|
||||||
"equal($f19(x,y,z,w),(w+((x+y)*z)))",
|
"equal($f19(x,y,z),(x*y^3+z))",
|
||||||
"equal($f20(x,y,z,w),(w+((x-y)/z)))",
|
"equal($f20(x,y,z),(x*y^4+z))",
|
||||||
"equal($f21(x,y,z,w),(w+((x-y)*z)))",
|
"equal($f21(x,y,z),(x*y^5+z))",
|
||||||
"equal($f22(x,y,z,w),(w+((x*y)/z)))",
|
"equal($f22(x,y,z),(x*y^6+z))",
|
||||||
"equal($f23(x,y,z,w),(w+((x*y)*z)))",
|
"equal($f23(x,y,z),(x*y^7+z))",
|
||||||
"equal($f24(x,y,z,w),(w+((x/y)+z)))",
|
"equal($f24(x,y,z),(x*y^8+z))",
|
||||||
"equal($f25(x,y,z,w),(w+((x/y)/z)))",
|
"equal($f25(x,y,z),(x*y^9+z))",
|
||||||
"equal($f26(x,y,z,w),(w+((x/y)*z)))",
|
"equal($f26(x,y,z,w),(w+((x+y)/z)))",
|
||||||
"equal($f27(x,y,z,w),(w-((x+y)/z)))",
|
"equal($f27(x,y,z,w),(w+((x+y)*z)))",
|
||||||
"equal($f28(x,y,z,w),(w-((x+y)*z)))",
|
"equal($f28(x,y,z,w),(w+((x-y)/z)))",
|
||||||
"equal($f29(x,y,z,w),(w-((x-y)/z)))",
|
"equal($f29(x,y,z,w),(w+((x-y)*z)))",
|
||||||
"equal($f30(x,y,z,w),(w-((x-y)*z)))",
|
"equal($f30(x,y,z,w),(w+((x*y)/z)))",
|
||||||
"equal($f31(x,y,z,w),(w-((x*y)/z)))",
|
"equal($f31(x,y,z,w),(w+((x*y)*z)))",
|
||||||
"equal($f32(x,y,z,w),(w-((x*y)*z)))",
|
"equal($f32(x,y,z,w),(w+((x/y)+z)))",
|
||||||
"equal($f33(x,y,z,w),(w-((x/y)/z)))",
|
"equal($f33(x,y,z,w),(w+((x/y)/z)))",
|
||||||
"equal($f34(x,y,z,w),(w-((x/y)*z)))",
|
"equal($f34(x,y,z,w),(w+((x/y)*z)))",
|
||||||
"equal($f35(x,y,z,w),(((x+y)*z)-w))",
|
"equal($f35(x,y,z,w),(w-((x+y)/z)))",
|
||||||
"equal($f36(x,y,z,w),(((x-y)*z)-w))",
|
"equal($f36(x,y,z,w),(w-((x+y)*z)))",
|
||||||
"equal($f37(x,y,z,w),(((x*y)*z)-w))",
|
"equal($f37(x,y,z,w),(w-((x-y)/z)))",
|
||||||
"equal($f38(x,y,z,w),(((x/y)*z)-w))",
|
"equal($f38(x,y,z,w),(w-((x-y)*z)))",
|
||||||
"equal($f39(x,y,z,w),(((x+y)/z)-w))",
|
"equal($f39(x,y,z,w),(w-((x*y)/z)))",
|
||||||
"equal($f40(x,y,z,w),(((x-y)/z)-w))",
|
"equal($f40(x,y,z,w),(w-((x*y)*z)))",
|
||||||
"equal($f41(x,y,z,w),(((x*y)/z)-w))",
|
"equal($f41(x,y,z,w),(w-((x/y)/z)))",
|
||||||
"equal($f42(x,y,z,w),(((x/y)/z)-w))",
|
"equal($f42(x,y,z,w),(w-((x/y)*z)))",
|
||||||
|
"equal($f43(x,y,z,w),(((x+y)*z)-w))",
|
||||||
|
"equal($f44(x,y,z,w),(((x-y)*z)-w))",
|
||||||
|
"equal($f45(x,y,z,w),(((x*y)*z)-w))",
|
||||||
|
"equal($f46(x,y,z,w),(((x/y)*z)-w))",
|
||||||
|
"equal($f47(x,y,z,w),(((x+y)/z)-w))",
|
||||||
|
"equal($f48(x,y,z,w),(((x-y)/z)-w))",
|
||||||
|
"equal($f49(x,y,z,w),(((x*y)/z)-w))",
|
||||||
|
"equal($f50(x,y,z,w),(((x/y)/z)-w))",
|
||||||
|
"equal($f51(x,y,z,w),(x*y^2+z*w^2))",
|
||||||
|
"equal($f52(x,y,z,w),(x*y^3+z*w^3))",
|
||||||
|
"equal($f53(x,y,z,w),(x*y^4+z*w^4))",
|
||||||
|
"equal($f54(x,y,z,w),(x*y^5+z*w^5))",
|
||||||
|
"equal($f55(x,y,z,w),(x*y^6+z*w^6))",
|
||||||
|
"equal($f56(x,y,z,w),(x*y^7+z*w^7))",
|
||||||
|
"equal($f57(x,y,z,w),(x*y^8+z*w^8))",
|
||||||
|
"equal($f58(x,y,z,w),(x*y^9+z*w^9))"
|
||||||
};
|
};
|
||||||
static const std::size_t expr_str_size = sizeof(expr_str) / sizeof(std::string);
|
static const std::size_t expr_str_size = sizeof(expr_str) / sizeof(std::string);
|
||||||
|
|
||||||
static const std::size_t rounds = 1000;
|
static const std::size_t rounds = 100;
|
||||||
for (std::size_t i = 0; i < rounds; ++i)
|
for (std::size_t i = 0; i < rounds; ++i)
|
||||||
{
|
{
|
||||||
for (std::size_t j = 0; j < expr_str_size; ++j)
|
for (std::size_t j = 0; j < expr_str_size; ++j)
|
||||||
{
|
{
|
||||||
typedef exprtk::expression<T> expression_t;
|
typedef exprtk::expression<T> expression_t;
|
||||||
|
|
||||||
T x = T(1.0);
|
T x = T(1.123);
|
||||||
T y = T(2.0);
|
T y = T(2.123);
|
||||||
T z = T(3.0);
|
T z = T(3.123);
|
||||||
T w = T(4.0);
|
T w = T(4.123);
|
||||||
T u = T(5.0);
|
T u = T(5.123);
|
||||||
|
|
||||||
exprtk::symbol_table<T> symbol_table;
|
exprtk::symbol_table<T> symbol_table;
|
||||||
symbol_table.add_variable("x",x);
|
symbol_table.add_variable("x",x);
|
||||||
|
@ -1470,6 +1511,7 @@ inline bool run_test08()
|
||||||
expression.value();
|
expression.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1487,7 +1529,7 @@ struct myfunc : public exprtk::ifunction<T>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool run_test09()
|
inline bool run_test09()
|
||||||
{
|
{
|
||||||
static const std::size_t rounds = 100000;
|
static const std::size_t rounds = 10000;
|
||||||
for (std::size_t i = 0; i < rounds; ++i)
|
for (std::size_t i = 0; i < rounds; ++i)
|
||||||
{
|
{
|
||||||
typedef exprtk::expression<T> expression_t;
|
typedef exprtk::expression<T> expression_t;
|
||||||
|
@ -1496,24 +1538,24 @@ inline bool run_test09()
|
||||||
"myfunc4(sin(x*pi),y/2)+myfunc5(sin(x*pi),y/2)+"
|
"myfunc4(sin(x*pi),y/2)+myfunc5(sin(x*pi),y/2)+"
|
||||||
"myfunc6(sin(x*pi),y/2)+myfunc7(sin(x*pi),y/2)+"
|
"myfunc6(sin(x*pi),y/2)+myfunc7(sin(x*pi),y/2)+"
|
||||||
"myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)+"
|
"myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)+"
|
||||||
"myfunc0(sin(1*pi),y/2)+myfunc1(sin(1*pi),y/2)+"
|
"myfunc0(sin(x*pi),y/2)+myfunc1(sin(x*pi),y/2)+"
|
||||||
"myfunc2(sin(1*pi),y/2)+myfunc3(sin(1*pi),y/2)+"
|
"myfunc2(sin(x*pi),y/2)+myfunc3(sin(x*pi),y/2)+"
|
||||||
"myfunc4(sin(1*pi),y/2)+myfunc5(sin(1*pi),y/2)+"
|
"myfunc4(sin(x*pi),y/2)+myfunc5(sin(x*pi),y/2)+"
|
||||||
"myfunc6(sin(1*pi),y/2)+myfunc7(sin(1*pi),y/2)+"
|
"myfunc6(sin(x*pi),y/2)+myfunc7(sin(x*pi),y/2)+"
|
||||||
"myfunc8(sin(1*pi),y/2)+myfunc9(sin(1*pi),y/2)+"
|
"myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)+"
|
||||||
"myfunc0(sin(x*pi),2/2)+myfunc1(sin(x*pi),2/2)+"
|
"myfunc0(sin(x*pi),y/2)+myfunc1(sin(x*pi),y/2)+"
|
||||||
"myfunc2(sin(x*pi),2/2)+myfunc3(sin(x*pi),2/2)+"
|
"myfunc2(sin(x*pi),y/2)+myfunc3(sin(x*pi),y/2)+"
|
||||||
"myfunc4(sin(x*pi),2/2)+myfunc5(sin(x*pi),2/2)+"
|
"myfunc4(sin(x*pi),y/2)+myfunc5(sin(x*pi),y/2)+"
|
||||||
"myfunc6(sin(x*pi),2/2)+myfunc7(sin(x*pi),2/2)+"
|
"myfunc6(sin(x*pi),y/2)+myfunc7(sin(x*pi),y/2)+"
|
||||||
"myfunc8(sin(x*pi),2/2)+myfunc9(sin(x*pi),2/2)+"
|
"myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)+"
|
||||||
"myfunc0(sin(1*pi),2/2)+myfunc1(sin(1*pi),2/2)+"
|
"myfunc0(sin(x*pi),y/2)+myfunc1(sin(x*pi),y/2)+"
|
||||||
"myfunc2(sin(1*pi),2/2)+myfunc3(sin(1*pi),2/2)+"
|
"myfunc2(sin(x*pi),y/2)+myfunc3(sin(x*pi),y/2)+"
|
||||||
"myfunc4(sin(1*pi),2/2)+myfunc5(sin(1*pi),2/2)+"
|
"myfunc4(sin(x*pi),y/2)+myfunc5(sin(x*pi),y/2)+"
|
||||||
"myfunc6(sin(1*pi),2/2)+myfunc7(sin(1*pi),2/2)+"
|
"myfunc6(sin(x*pi),y/2)+myfunc7(sin(x*pi),y/2)+"
|
||||||
"myfunc8(sin(1*pi),2/2)+myfunc9(sin(1*pi),2/2)";
|
"myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)";
|
||||||
|
|
||||||
T x = T(1.0);
|
T x = T(1.0) + (i/10000.0);
|
||||||
T y = T(2.0);
|
T y = T(2.0) + (i/10000.0);
|
||||||
myfunc<T> mf;
|
myfunc<T> mf;
|
||||||
|
|
||||||
exprtk::symbol_table<T> symbol_table;
|
exprtk::symbol_table<T> symbol_table;
|
||||||
|
@ -1541,7 +1583,7 @@ inline bool run_test09()
|
||||||
std::cout << "run_test09() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl;
|
std::cout << "run_test09() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const T pi = T(3.14159265358979323846);
|
const T pi = T(3.141592653589793238462);
|
||||||
|
|
||||||
T result = expression.value();
|
T result = expression.value();
|
||||||
T expected = T(4.0) *
|
T expected = T(4.0) *
|
||||||
|
@ -1607,7 +1649,7 @@ inline bool run_test10()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::size_t rounds = 1000;
|
static const std::size_t rounds = 100;
|
||||||
|
|
||||||
for (std::size_t r = 0; r < rounds; ++r)
|
for (std::size_t r = 0; r < rounds; ++r)
|
||||||
{
|
{
|
||||||
|
@ -1964,7 +2006,7 @@ inline bool run_test10()
|
||||||
T y0 = T(0);
|
T y0 = T(0);
|
||||||
T z0 = T(0);
|
T z0 = T(0);
|
||||||
std::string expression_string = "(x0 + y0) / z0";
|
std::string expression_string = "(x0 + y0) / z0";
|
||||||
static const std::size_t rounds = 10000000;
|
static const std::size_t rounds = 1000000;
|
||||||
for (std::size_t i = 0; i < rounds; ++i)
|
for (std::size_t i = 0; i < rounds; ++i)
|
||||||
{
|
{
|
||||||
expression_t expression0;
|
expression_t expression0;
|
||||||
|
@ -2023,7 +2065,7 @@ inline bool run_test11()
|
||||||
expression_t expression;
|
expression_t expression;
|
||||||
expression.register_symbol_table(symbol_table);
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
static const std::size_t rounds = 100000;
|
static const std::size_t rounds = 10000;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < rounds; ++i)
|
for (std::size_t i = 0; i < rounds; ++i)
|
||||||
{
|
{
|
||||||
|
|
52
readme.txt
52
readme.txt
|
@ -30,7 +30,7 @@ operations, functions and processes:
|
||||||
(6) Conditional &
|
(6) Conditional &
|
||||||
Loop statement: if-then-else, while
|
Loop statement: if-then-else, while
|
||||||
|
|
||||||
(7) Assigment: :=, <-
|
(7) Assigment: :=
|
||||||
|
|
||||||
|
|
||||||
[EXAMPLE EXPRESSIONS]
|
[EXAMPLE EXPRESSIONS]
|
||||||
|
@ -93,6 +93,56 @@ Expression Library can be found at:
|
||||||
(*) Comeau C++ Compiler (4.3+)
|
(*) Comeau C++ Compiler (4.3+)
|
||||||
|
|
||||||
|
|
||||||
|
[SPECIAL FUNCTIONS]
|
||||||
|
The purpose of special functions in ExprTk is to provide compiler
|
||||||
|
generated equivalents of common mathematical expressions which can be
|
||||||
|
invoked by using the 'special function' syntax (eg: $f12(x,y,z) or
|
||||||
|
$f24(x,y,z,w)).
|
||||||
|
|
||||||
|
Special functions dramatically decrease the total evaluation time of
|
||||||
|
expressions which would otherwise have been written using the common
|
||||||
|
form by reducing the total number of nodes in the evaluation tree of
|
||||||
|
an expression and by also leveraging the compiler's ability to
|
||||||
|
correctly optimize such expressions for a given architecture.
|
||||||
|
|
||||||
|
3-Parameter 4-Parameter
|
||||||
|
| Prototype | Operation | | Prototype | Operation |
|
||||||
|
+------------+-------------+ +--------------+------------------+
|
||||||
|
sf00(x,y,z) | (x + y) / z sf26(x,y,z,w) | w + ((x + y) / z)
|
||||||
|
sf01(x,y,z) | (x + y) * z sf27(x,y,z,w) | w + ((x + y) * z)
|
||||||
|
sf02(x,y,z) | (x - y) / z sf28(x,y,z,w) | w + ((x - y) / z)
|
||||||
|
sf03(x,y,z) | (x - y) * z sf29(x,y,z,w) | w + ((x - y) * z)
|
||||||
|
sf04(x,y,z) | (x * y) + z sf30(x,y,z,w) | w + ((x * y) / z)
|
||||||
|
sf05(x,y,z) | (x * y) - z sf31(x,y,z,w) | w + ((x * y) * z)
|
||||||
|
sf06(x,y,z) | (x * y) / z sf32(x,y,z,w) | w + ((x / y) + z)
|
||||||
|
sf07(x,y,z) | (x * y) * z sf33(x,y,z,w) | w + ((x / y) / z)
|
||||||
|
sf08(x,y,z) | (x / y) + z sf34(x,y,z,w) | w + ((x / y) * z)
|
||||||
|
sf09(x,y,z) | (x / y) - z sf35(x,y,z,w) | w - ((x + y) / z)
|
||||||
|
sf10(x,y,z) | (x / y) / z sf36(x,y,z,w) | w - ((x + y) * z)
|
||||||
|
sf11(x,y,z) | (x / y) * z sf37(x,y,z,w) | w - ((x - y) / z)
|
||||||
|
sf12(x,y,z) | z / (x + y) sf38(x,y,z,w) | w - ((x - y) * z)
|
||||||
|
sf13(x,y,z) | z / (x - y) sf39(x,y,z,w) | w - ((x * y) / z)
|
||||||
|
sf14(x,y,z) | z / (x * y) sf40(x,y,z,w) | w - ((x * y) * z)
|
||||||
|
sf15(x,y,z) | z / (x / y) sf41(x,y,z,w) | w - ((x / y) / z)
|
||||||
|
sf16(x,y,z) | z - (x / y) sf42(x,y,z,w) | w - ((x / y) * z)
|
||||||
|
sf17(x,y,z) | z - (x / y) sf43(x,y,z,w) | ((x + y) * z) - w
|
||||||
|
sf18(x,y,z) | x * y^2 + z sf44(x,y,z,w) | ((x - y) * z) - w
|
||||||
|
sf19(x,y,z) | x * y^3 + z sf45(x,y,z,w) | ((x * y) * z) - w
|
||||||
|
sf20(x,y,z) | x * y^4 + z sf46(x,y,z,w) | ((x / y) * z) - w
|
||||||
|
sf21(x,y,z) | x * y^5 + z sf47(x,y,z,w) | ((x + y) / z) - w
|
||||||
|
sf22(x,y,z) | x * y^6 + z sf48(x,y,z,w) | ((x - y) / z) - w
|
||||||
|
sf23(x,y,z) | x * y^7 + z sf49(x,y,z,w) | ((x * y) / z) - w
|
||||||
|
sf24(x,y,z) | x * y^8 + z sf50(x,y,z,w) | ((x / y) / z) - w
|
||||||
|
sf25(x,y,z) | x * y^9 + z sf51(x,y,z,w) | x * y^2 + z * w^2
|
||||||
|
sf52(x,y,z,w) | x * y^3 + z * w^3
|
||||||
|
sf53(x,y,z,w) | x * y^4 + z * w^4
|
||||||
|
sf54(x,y,z,w) | x * y^5 + z * w^5
|
||||||
|
sf55(x,y,z,w) | x * y^6 + z * w^6
|
||||||
|
sf56(x,y,z,w) | x * y^7 + z * w^7
|
||||||
|
sf57(x,y,z,w) | x * y^8 + z * w^8
|
||||||
|
sf58(x,y,z,w) | x * y^9 + z * w^9
|
||||||
|
|
||||||
|
|
||||||
[MACROS]
|
[MACROS]
|
||||||
ExprTk utilizes certain macros to modify the underlying behaviour of
|
ExprTk utilizes certain macros to modify the underlying behaviour of
|
||||||
the parser and the evaluation engine. The following macros are used to
|
the parser and the evaluation engine. The following macros are used to
|
||||||
|
|
Loading…
Reference in New Issue