C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
9d798d71e5
commit
7103525a7f
189
exprtk.hpp
189
exprtk.hpp
|
@ -1504,7 +1504,7 @@ namespace exprtk
|
||||||
s_end_ = str.data() + str.size();
|
s_end_ = str.data() + str.size();
|
||||||
eof_token_.set_operator(token_t::e_eof,s_end_,s_end_,base_itr_);
|
eof_token_.set_operator(token_t::e_eof,s_end_,s_end_,base_itr_);
|
||||||
token_list_.clear();
|
token_list_.clear();
|
||||||
while (s_end_ != s_itr_)
|
while (!is_end(s_itr_))
|
||||||
{
|
{
|
||||||
scan_token();
|
scan_token();
|
||||||
if (token_list_.back().is_error())
|
if (token_list_.back().is_error())
|
||||||
|
@ -1564,9 +1564,14 @@ namespace exprtk
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
inline bool is_end(const char* itr)
|
||||||
|
{
|
||||||
|
return (s_end_ == itr);
|
||||||
|
}
|
||||||
|
|
||||||
inline void skip_whitespace()
|
inline void skip_whitespace()
|
||||||
{
|
{
|
||||||
while ((s_end_ != s_itr_) && details::is_whitespace(*s_itr_))
|
while (!is_end(s_itr_) && details::is_whitespace(*s_itr_))
|
||||||
{
|
{
|
||||||
++s_itr_;
|
++s_itr_;
|
||||||
}
|
}
|
||||||
|
@ -1575,15 +1580,48 @@ namespace exprtk
|
||||||
inline void skip_comments()
|
inline void skip_comments()
|
||||||
{
|
{
|
||||||
#ifndef exprtk_disable_comments
|
#ifndef exprtk_disable_comments
|
||||||
if ((s_end_ == s_itr_) || (s_end_ == (s_itr_ + 1)))
|
//The following comment styles are supported:
|
||||||
|
// 1. // .... \n
|
||||||
|
// 2. # .... \n
|
||||||
|
// 3. /* .... */
|
||||||
|
struct test
|
||||||
|
{
|
||||||
|
static inline bool comment_start(const char c0, const char c1, int& mode, int& incr)
|
||||||
|
{
|
||||||
|
mode = 0;
|
||||||
|
if ('#' == c0) { mode = 1; incr = 1; }
|
||||||
|
else if ('/' == c0)
|
||||||
|
{
|
||||||
|
if ('/' == c1) { mode = 1; incr = 2; }
|
||||||
|
else if ('*' == c1) { mode = 2; incr = 2; }
|
||||||
|
}
|
||||||
|
return (mode != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool comment_end(const char c0, const char c1, const int mode)
|
||||||
|
{
|
||||||
|
return ((1 == mode) && ('\n' == c0)) ||
|
||||||
|
((2 == mode) && ( '*' == c0) && ('/' == c1));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int mode = 0;
|
||||||
|
int increment = 0;
|
||||||
|
if (is_end(s_itr_) || is_end((s_itr_ + 1)))
|
||||||
return;
|
return;
|
||||||
else if (('/' != *s_itr_) || ('/' != *(s_itr_ + 1)))
|
else if (!test::comment_start(*s_itr_,*(s_itr_ + 1),mode,increment))
|
||||||
return;
|
return;
|
||||||
while ((s_end_ != s_itr_) && ('\n' != *s_itr_))
|
s_itr_ += increment;
|
||||||
|
while (!is_end(s_itr_) && !test::comment_end(*s_itr_,*(s_itr_ + 1),mode))
|
||||||
{
|
{
|
||||||
++s_itr_;
|
++s_itr_;
|
||||||
}
|
}
|
||||||
|
if (is_end(s_itr_))
|
||||||
|
{
|
||||||
|
s_itr_ += mode;
|
||||||
skip_whitespace();
|
skip_whitespace();
|
||||||
|
skip_comments();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1591,7 +1629,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
skip_whitespace();
|
skip_whitespace();
|
||||||
skip_comments();
|
skip_comments();
|
||||||
if (s_end_ == s_itr_)
|
if (is_end(s_itr_))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1635,7 +1673,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
token_t t;
|
token_t t;
|
||||||
|
|
||||||
if ((s_itr_ + 1) != s_end_)
|
if (!is_end(s_itr_ + 1))
|
||||||
{
|
{
|
||||||
token_t::token_type ttype = token_t::e_none;
|
token_t::token_type ttype = token_t::e_none;
|
||||||
char c0 = s_itr_[0];
|
char c0 = s_itr_[0];
|
||||||
|
@ -1675,7 +1713,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
const char* begin = s_itr_;
|
const char* begin = s_itr_;
|
||||||
while (
|
while (
|
||||||
(s_end_ != s_itr_) &&
|
(!is_end(s_itr_)) &&
|
||||||
(details::is_letter_or_digit(*s_itr_) || ((*s_itr_) == '_'))
|
(details::is_letter_or_digit(*s_itr_) || ((*s_itr_) == '_'))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -1705,7 +1743,7 @@ namespace exprtk
|
||||||
bool post_e_sign_found = false;
|
bool post_e_sign_found = false;
|
||||||
token_t t;
|
token_t t;
|
||||||
|
|
||||||
while (s_end_ != s_itr_)
|
while (!is_end(s_itr_))
|
||||||
{
|
{
|
||||||
if ('.' == (*s_itr_))
|
if ('.' == (*s_itr_))
|
||||||
{
|
{
|
||||||
|
@ -1723,7 +1761,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
const char& c = *(s_itr_ + 1);
|
const char& c = *(s_itr_ + 1);
|
||||||
|
|
||||||
if (s_end_ == (s_itr_ + 1))
|
if (is_end(s_itr_ + 1))
|
||||||
{
|
{
|
||||||
t.set_error(token::e_err_number,begin,s_itr_,base_itr_);
|
t.set_error(token::e_err_number,begin,s_itr_,base_itr_);
|
||||||
token_list_.push_back(t);
|
token_list_.push_back(t);
|
||||||
|
@ -1778,7 +1816,6 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
t.set_error(token::e_err_sfunc,begin,s_itr_,base_itr_);
|
t.set_error(token::e_err_sfunc,begin,s_itr_,base_itr_);
|
||||||
token_list_.push_back(t);
|
token_list_.push_back(t);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1791,7 +1828,6 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
t.set_error(token::e_err_sfunc,begin,s_itr_,base_itr_);
|
t.set_error(token::e_err_sfunc,begin,s_itr_,base_itr_);
|
||||||
token_list_.push_back(t);
|
token_list_.push_back(t);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1812,14 +1848,13 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
t.set_error(token::e_err_string,begin,s_itr_,base_itr_);
|
t.set_error(token::e_err_string,begin,s_itr_,base_itr_);
|
||||||
token_list_.push_back(t);
|
token_list_.push_back(t);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
++s_itr_;
|
++s_itr_;
|
||||||
|
|
||||||
bool escaped = false;
|
bool escaped = false;
|
||||||
|
|
||||||
while (s_end_ != s_itr_)
|
while (!is_end(s_itr_))
|
||||||
{
|
{
|
||||||
if ('\\' == *s_itr_)
|
if ('\\' == *s_itr_)
|
||||||
{
|
{
|
||||||
|
@ -1834,16 +1869,16 @@ namespace exprtk
|
||||||
}
|
}
|
||||||
else if (escaped)
|
else if (escaped)
|
||||||
escaped = false;
|
escaped = false;
|
||||||
|
|
||||||
++s_itr_;
|
++s_itr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_end_ == s_itr_)
|
if (is_end(s_itr_))
|
||||||
{
|
{
|
||||||
t.set_error(token::e_err_string,begin,s_itr_,base_itr_);
|
t.set_error(token::e_err_string,begin,s_itr_,base_itr_);
|
||||||
token_list_.push_back(t);
|
token_list_.push_back(t);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
t.set_string(begin,s_itr_,base_itr_);
|
t.set_string(begin,s_itr_,base_itr_);
|
||||||
token_list_.push_back(t);
|
token_list_.push_back(t);
|
||||||
++s_itr_;
|
++s_itr_;
|
||||||
|
@ -10775,7 +10810,7 @@ namespace exprtk
|
||||||
if (!expr_gen.sf3_optimizable(id,sf3opr))
|
if (!expr_gen.sf3_optimizable(id,sf3opr))
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
result = synthesize_sf3ext_expression::process<T0,T1,T2>(expr_gen,sf3opr,t0,t1,t2);
|
result = synthesize_sf3ext_expression::template process<T0,T1,T2>(expr_gen,sf3opr,t0,t1,t2);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10846,7 +10881,7 @@ namespace exprtk
|
||||||
if (!expr_gen.sf4_optimizable(id,sf4opr))
|
if (!expr_gen.sf4_optimizable(id,sf4opr))
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
result = synthesize_sf4ext_expression::process<T0,T1,T2,T3>(expr_gen,sf4opr,t0,t1,t2,t3);
|
result = synthesize_sf4ext_expression::template process<T0,T1,T2,T3>(expr_gen,sf4opr,t0,t1,t2,t3);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13874,7 +13909,7 @@ namespace exprtk
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T derivative(expression<T>& e,
|
inline T derivative(expression<T>& e,
|
||||||
T& x,
|
T& x,
|
||||||
const T& h = T(0.00001))
|
const T& h = T(0.00000001))
|
||||||
{
|
{
|
||||||
T x_init = x;
|
T x_init = x;
|
||||||
x = x_init + T(2.0) * h;
|
x = x_init + T(2.0) * h;
|
||||||
|
@ -13889,10 +13924,47 @@ namespace exprtk
|
||||||
return (-y0 + T(8.0) * (y1 - y2) + y3) / (T(12.0) * h);
|
return (-y0 + T(8.0) * (y1 - y2) + y3) / (T(12.0) * h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T second_derivative(expression<T>& e,
|
||||||
|
T& x,
|
||||||
|
const T& h = T(0.00001))
|
||||||
|
{
|
||||||
|
T y = e.value();
|
||||||
|
T x_init = x;
|
||||||
|
x = x_init + T(2.0) * h;
|
||||||
|
T y0 = e.value();
|
||||||
|
x = x_init + h;
|
||||||
|
T y1 = e.value();
|
||||||
|
x = x_init - h;
|
||||||
|
T y2 = e.value();
|
||||||
|
x = x_init - T(2.0) * h;
|
||||||
|
T y3 = e.value();
|
||||||
|
x = x_init;
|
||||||
|
return (-y0 + T(16.0) * (y1 + y2) - T(30.0) * y - y3) / (T(12.0) * h * h);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T third_derivative(expression<T>& e,
|
||||||
|
T& x,
|
||||||
|
const T& h = T(0.0001))
|
||||||
|
{
|
||||||
|
T x_init = x;
|
||||||
|
x = x_init + T(2.0) * h;
|
||||||
|
T y0 = e.value();
|
||||||
|
x = x_init + h;
|
||||||
|
T y1 = e.value();
|
||||||
|
x = x_init - h;
|
||||||
|
T y2 = e.value();
|
||||||
|
x = x_init - T(2.0) * h;
|
||||||
|
T y3 = e.value();
|
||||||
|
x = x_init;
|
||||||
|
return (y0 + T(2.0) * (y2 - y1) - y3) / (T(2.0) * h * h * h);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T derivative(expression<T>& e,
|
inline T derivative(expression<T>& e,
|
||||||
const std::string& variable_name,
|
const std::string& variable_name,
|
||||||
const T& h = T(0.00001))
|
const T& h = T(0.00000001))
|
||||||
{
|
{
|
||||||
symbol_table<T>& sym_table = e.get_symbol_table();
|
symbol_table<T>& sym_table = e.get_symbol_table();
|
||||||
if (!sym_table.valid())
|
if (!sym_table.valid())
|
||||||
|
@ -13904,7 +13976,48 @@ namespace exprtk
|
||||||
T x_original = x;
|
T x_original = x;
|
||||||
T result = derivative(e,x,h);
|
T result = derivative(e,x,h);
|
||||||
x = x_original;
|
x = x_original;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T second_derivative(expression<T>& e,
|
||||||
|
const std::string& variable_name,
|
||||||
|
const T& h = T(0.00001))
|
||||||
|
{
|
||||||
|
symbol_table<T>& sym_table = e.get_symbol_table();
|
||||||
|
if (!sym_table.valid())
|
||||||
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
details::variable_node<T>* var = sym_table.get_variable(variable_name);
|
||||||
|
if (var)
|
||||||
|
{
|
||||||
|
T& x = var->ref();
|
||||||
|
T x_original = x;
|
||||||
|
T result = second_derivative(e,x,h);
|
||||||
|
x = x_original;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T third_derivative(expression<T>& e,
|
||||||
|
const std::string& variable_name,
|
||||||
|
const T& h = T(0.0001))
|
||||||
|
{
|
||||||
|
symbol_table<T>& sym_table = e.get_symbol_table();
|
||||||
|
if (!sym_table.valid())
|
||||||
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
details::variable_node<T>* var = sym_table.get_variable(variable_name);
|
||||||
|
if (var)
|
||||||
|
{
|
||||||
|
T& x = var->ref();
|
||||||
|
T x_original = x;
|
||||||
|
T result = third_derivative(e,x,h);
|
||||||
|
x = x_original;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -14016,6 +14129,32 @@ namespace exprtk
|
||||||
template <typename Type, std::size_t NumberOfCoefficients>
|
template <typename Type, std::size_t NumberOfCoefficients>
|
||||||
struct poly_impl { };
|
struct poly_impl { };
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct poly_impl <Type,12>
|
||||||
|
{
|
||||||
|
static inline T evaluate(const Type x,
|
||||||
|
const Type c12, const Type c11, const Type c10, 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_12x^12 + c_11x^11 + c_10x^10 + 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_0x^0
|
||||||
|
return ((((((((((((c12 * x + c11) * x + c10) * x + 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,11>
|
||||||
|
{
|
||||||
|
static inline T evaluate(const Type x,
|
||||||
|
const Type c11, const Type c10, 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_11x^11 + c_10x^10 + 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_0x^0
|
||||||
|
return ((((((((((( c11 * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
struct poly_impl <Type,10>
|
struct poly_impl <Type,10>
|
||||||
{
|
{
|
||||||
|
@ -14183,6 +14322,16 @@ namespace exprtk
|
||||||
return ((10 == N) ? poly_impl<T,10>::evaluate(x,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
return ((10 == N) ? poly_impl<T,10>::evaluate(x,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T& x, const T& c11, const T& c10, const T& c9, 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 ((11 == N) ? poly_impl<T,11>::evaluate(x,c11,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual T operator()(const T& x, const T& c12, const T& c11, const T& c10, const T& c9, 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 ((12 == N) ? poly_impl<T,12>::evaluate(x,c12,c11,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits<T>::quiet_NaN());
|
||||||
|
}
|
||||||
|
|
||||||
inline virtual T operator()()
|
inline virtual T operator()()
|
||||||
{
|
{
|
||||||
return std::numeric_limits<T>::quiet_NaN();
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
|
107
exprtk_test.cpp
107
exprtk_test.cpp
|
@ -1498,26 +1498,70 @@ inline bool run_test07()
|
||||||
|
|
||||||
for (x = T(-200.0); x < T(200); x += T(0.0001))
|
for (x = T(-200.0); x < T(200); x += T(0.0001))
|
||||||
{
|
{
|
||||||
T result1 = exprtk::derivative(expression,x);
|
|
||||||
T result2 = exprtk::derivative(expression,"x");
|
|
||||||
T real_result = T(2.0) * std::cos(T(2.0) * x + T(1.0/3.0));
|
|
||||||
|
|
||||||
if (not_equal(result1,result2,T(0.000000001)))
|
|
||||||
{
|
{
|
||||||
printf("run_test07() - Derivative Error: result1 != result2\n");
|
T deriv1_real_result = T(2.0) * std::cos(T(2.0) * x + T(1.0/3.0));
|
||||||
|
T deriv1_result1 = exprtk::derivative(expression,x);
|
||||||
|
T deriv1_result2 = exprtk::derivative(expression,"x");
|
||||||
|
|
||||||
|
if (not_equal(deriv1_result1,deriv1_result2,T(0.00001)))
|
||||||
|
{
|
||||||
|
printf("run_test07() - 1st Derivative Error: result1 != result2\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not_equal(result1,real_result,T(0.000000001)))
|
if (not_equal(deriv1_result1,deriv1_real_result,T(0.00001)))
|
||||||
{
|
{
|
||||||
printf("run_test07() - Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n",
|
printf("run_test07() - 1st Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n",
|
||||||
x,
|
x,
|
||||||
real_result,
|
deriv1_real_result,
|
||||||
result1);
|
deriv1_result1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
T deriv2_real_result = T(-4.0) * std::sin(T(2.0) * x + T(1.0/3.0));
|
||||||
|
T deriv2_result1 = exprtk::second_derivative(expression,x);
|
||||||
|
T deriv2_result2 = exprtk::second_derivative(expression,"x");
|
||||||
|
|
||||||
|
if (not_equal(deriv2_result1,deriv2_result2,T(0.0000001)))
|
||||||
|
{
|
||||||
|
printf("run_test07() - 2nd Derivative Error: result1 != result2\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not_equal(deriv2_result1,deriv2_real_result,T(0.01)))
|
||||||
|
{
|
||||||
|
printf("run_test07() - 2nd Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n",
|
||||||
|
x,
|
||||||
|
deriv2_real_result,
|
||||||
|
deriv2_result1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
T deriv3_real_result = T(-8.0) * std::cos(T(2.0) * x + T(1.0/3.0));
|
||||||
|
T deriv3_result1 = exprtk::third_derivative(expression,x);
|
||||||
|
T deriv3_result2 = exprtk::third_derivative(expression,"x");
|
||||||
|
|
||||||
|
if (not_equal(deriv3_result1,deriv3_result2,T(0.0000001)))
|
||||||
|
{
|
||||||
|
printf("run_test07() - 3rd Derivative Error: result1 != result2\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not_equal(deriv3_result1,deriv3_real_result,T(0.01)))
|
||||||
|
{
|
||||||
|
printf("run_test07() - 3rd Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n",
|
||||||
|
x,
|
||||||
|
deriv3_real_result,
|
||||||
|
deriv3_result1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2332,15 +2376,18 @@ inline bool run_test12()
|
||||||
typedef exprtk::expression<T> expression_t;
|
typedef exprtk::expression<T> expression_t;
|
||||||
static const std::string expression_string[] =
|
static const std::string expression_string[] =
|
||||||
{
|
{
|
||||||
"equal(poly1(x,2.2,1.1),(2.2x^1+1.1))",
|
"equal(poly01(x,2.2,1.1),(2.2x^1+1.1))",
|
||||||
"equal(poly2(x,3.3,2.2,1.1),(3.3x^2+2.2x^1+1.1))",
|
"equal(poly02(x,3.3,2.2,1.1),(3.3x^2+2.2x^1+1.1))",
|
||||||
"equal(poly3(x,4.4,3.3,2.2,1.1),(4.4x^3+3.3x^2+2.2x^1+1.1))",
|
"equal(poly03(x,4.4,3.3,2.2,1.1),(4.4x^3+3.3x^2+2.2x^1+1.1))",
|
||||||
"equal(poly4(x,5.5,4.4,3.3,2.2,1.1),(5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))",
|
"equal(poly04(x,5.5,4.4,3.3,2.2,1.1),(5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))",
|
||||||
"equal(poly5(x,6.6,5.5,4.4,3.3,2.2,1.1),(6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))",
|
"equal(poly05(x,6.6,5.5,4.4,3.3,2.2,1.1),(6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))",
|
||||||
"equal(poly6(x,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(7.7x^6+6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))",
|
"equal(poly06(x,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(7.7x^6+6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))",
|
||||||
"equal(poly7(x,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(8.8x^7+7.7x^6+6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))",
|
"equal(poly07(x,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(8.8x^7+7.7x^6+6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))",
|
||||||
"equal(poly8(x,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(9.9x^8+8.8x^7+7.7x^6+6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))",
|
"equal(poly08(x,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(9.9x^8+8.8x^7+7.7x^6+6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))",
|
||||||
"equal(poly9(x,1.1,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(1.1x^9+9.9x^8+8.8x^7+7.7x^6+6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))"
|
"equal(poly09(x,1.1,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(1.1x^9+9.9x^8+8.8x^7+7.7x^6+6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))"
|
||||||
|
"equal(poly10(x,2.2,1.1,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(2.2x^10+1.1x^9+9.9x^8+8.8x^7+7.7x^6+6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))"
|
||||||
|
"equal(poly11(x,3.3,2.2,1.1,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(3.3x^11+2.2x^10+1.1x^9+9.9x^8+8.8x^7+7.7x^6+6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))"
|
||||||
|
"equal(poly12(x,4.4,3.3,2.2,1.1,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(4.4x^12+3.3x^11+2.2x^10+1.1x^9+9.9x^8+8.8x^7+7.7x^6+6.6x^5+5.5x^4+4.4x^3+3.3x^2+2.2x^1+1.1))"
|
||||||
};
|
};
|
||||||
static const std::size_t expression_string_size = sizeof(expression_string) / sizeof(std::string);
|
static const std::size_t expression_string_size = sizeof(expression_string) / sizeof(std::string);
|
||||||
|
|
||||||
|
@ -2356,20 +2403,24 @@ inline bool run_test12()
|
||||||
exprtk::polynomial<T, 8> poly08;
|
exprtk::polynomial<T, 8> poly08;
|
||||||
exprtk::polynomial<T, 9> poly09;
|
exprtk::polynomial<T, 9> poly09;
|
||||||
exprtk::polynomial<T,10> poly10;
|
exprtk::polynomial<T,10> poly10;
|
||||||
|
exprtk::polynomial<T,11> poly11;
|
||||||
|
exprtk::polynomial<T,12> poly12;
|
||||||
|
|
||||||
exprtk::symbol_table<T> symbol_table;
|
exprtk::symbol_table<T> symbol_table;
|
||||||
|
|
||||||
symbol_table.add_variable("x",x);
|
symbol_table.add_variable("x",x);
|
||||||
symbol_table.add_function( "poly1", poly01);
|
symbol_table.add_function("poly01", poly01);
|
||||||
symbol_table.add_function( "poly2", poly02);
|
symbol_table.add_function("poly02", poly02);
|
||||||
symbol_table.add_function( "poly3", poly03);
|
symbol_table.add_function("poly03", poly03);
|
||||||
symbol_table.add_function( "poly4", poly04);
|
symbol_table.add_function("poly04", poly04);
|
||||||
symbol_table.add_function( "poly5", poly05);
|
symbol_table.add_function("poly05", poly05);
|
||||||
symbol_table.add_function( "poly6", poly06);
|
symbol_table.add_function("poly06", poly06);
|
||||||
symbol_table.add_function( "poly7", poly07);
|
symbol_table.add_function("poly07", poly07);
|
||||||
symbol_table.add_function( "poly8", poly08);
|
symbol_table.add_function("poly08", poly08);
|
||||||
symbol_table.add_function( "poly9", poly09);
|
symbol_table.add_function("poly09", poly09);
|
||||||
symbol_table.add_function("poly10", poly10);
|
symbol_table.add_function("poly10", poly10);
|
||||||
|
symbol_table.add_function("poly11", poly11);
|
||||||
|
symbol_table.add_function("poly12", poly12);
|
||||||
|
|
||||||
expression_t expression;
|
expression_t expression;
|
||||||
expression.register_symbol_table(symbol_table);
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
11
readme.txt
11
readme.txt
|
@ -406,7 +406,7 @@ correctly optimize such expressions for a given architecture.
|
||||||
|
|
||||||
(10) User defined functions can have up to 20 parameters.
|
(10) User defined functions can have up to 20 parameters.
|
||||||
|
|
||||||
(11) The inbuilt polynomial functions can be at most of degree 10.
|
(11) The inbuilt polynomial functions can be at most of degree 12.
|
||||||
|
|
||||||
(12) Where appropriate constant folding optimisations will be
|
(12) Where appropriate constant folding optimisations will be
|
||||||
applied. (eg: The expression '2+(3-(x/y))' becomes '5-(x/y)')
|
applied. (eg: The expression '2+(3-(x/y))' becomes '5-(x/y)')
|
||||||
|
@ -415,11 +415,10 @@ correctly optimize such expressions for a given architecture.
|
||||||
To turn them off, the following needs to be defined at
|
To turn them off, the following needs to be defined at
|
||||||
compile time: exprtk_disable_string_capabilities
|
compile time: exprtk_disable_string_capabilities
|
||||||
|
|
||||||
(14) Expressions may contain trailing comments that must be prefixed
|
(14) Expressions may contain any of the following comment styles:
|
||||||
with '//' and are terminated by the next occurrence of new-line
|
1. // .... \n
|
||||||
or line-break. To disallow comments, the following needs to be
|
2. # .... \n
|
||||||
defined at compile time: exprtk_disable_comments
|
3. /* .... */
|
||||||
(eg: '2+(3-(x/y)) // This is an expression')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue