C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
8a64a1faf6
commit
904f924005
45
exprtk.hpp
45
exprtk.hpp
|
@ -458,6 +458,36 @@ namespace exprtk
|
|||
#undef exprtk_register_real_type_tag
|
||||
#undef exprtk_register_int_type_tag
|
||||
|
||||
template <typename T>
|
||||
struct epsilon_type
|
||||
{
|
||||
static inline T value()
|
||||
{
|
||||
const T epsilon = T(0.0000000001);
|
||||
return epsilon;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct epsilon_type <float>
|
||||
{
|
||||
static inline float value()
|
||||
{
|
||||
const float epsilon = float(0.000001f);
|
||||
return epsilon;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct epsilon_type <long double>
|
||||
{
|
||||
static inline long double value()
|
||||
{
|
||||
const long double epsilon = (long double)(0.000000000001);
|
||||
return epsilon;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline bool is_true_impl(const T v)
|
||||
{
|
||||
|
@ -479,13 +509,13 @@ namespace exprtk
|
|||
template <typename T>
|
||||
inline T equal_impl(const T v0, const T v1, real_type_tag)
|
||||
{
|
||||
static const T epsilon = T(0.0000000001);
|
||||
const T epsilon = epsilon_type<T>::value();
|
||||
return (abs_impl(v0 - v1,real_type_tag()) <= (std::max(T(1),std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? T(1) : T(0);
|
||||
}
|
||||
|
||||
inline float equal_impl(const float v0, const float v1, real_type_tag)
|
||||
{
|
||||
static const float epsilon = float(0.000001f);
|
||||
const float epsilon = epsilon_type<float>::value();
|
||||
return (abs_impl(v0 - v1,real_type_tag()) <= (std::max(1.0f,std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
|
@ -514,13 +544,13 @@ namespace exprtk
|
|||
template <typename T>
|
||||
inline T nequal_impl(const T v0, const T v1, real_type_tag)
|
||||
{
|
||||
static const T epsilon = T(0.0000000001);
|
||||
const T epsilon = epsilon_type<T>::value();
|
||||
return (abs_impl(v0 - v1,real_type_tag()) > (std::max(T(1),std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? T(1) : T(0);
|
||||
}
|
||||
|
||||
inline float nequal_impl(const float v0, const float v1, real_type_tag)
|
||||
{
|
||||
static const float epsilon = float(0.000001f);
|
||||
const float epsilon = epsilon_type<float>::value();
|
||||
return (abs_impl(v0 - v1,real_type_tag()) > (std::max(1.0f,std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
|
@ -3343,6 +3373,11 @@ namespace exprtk
|
|||
return (0.0 != v);
|
||||
}
|
||||
|
||||
inline bool is_true(const long double v)
|
||||
{
|
||||
return (0.0 != v);
|
||||
}
|
||||
|
||||
inline bool is_true(const float v)
|
||||
{
|
||||
return (0.0f != v);
|
||||
|
@ -9547,7 +9582,7 @@ namespace exprtk
|
|||
|
||||
inline bool add_epsilon()
|
||||
{
|
||||
static const T local_epsilon = std::numeric_limits<T>::epsilon();
|
||||
static const T local_epsilon = details::numeric::details::epsilon_type<T>::value();
|
||||
return add_constant("epsilon",local_epsilon);
|
||||
}
|
||||
|
||||
|
|
197
exprtk_test.cpp
197
exprtk_test.cpp
|
@ -27,8 +27,8 @@
|
|||
|
||||
#include "exprtk.hpp"
|
||||
|
||||
|
||||
typedef std::pair<std::string,double> test_t;
|
||||
typedef double numeric_type;
|
||||
typedef std::pair<std::string,numeric_type> test_t;
|
||||
|
||||
static const test_t test_list[] =
|
||||
{
|
||||
|
@ -1095,8 +1095,8 @@ inline bool test_expression(const std::string& expression_string, const T& expec
|
|||
{
|
||||
printf("test_expression() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
|
||||
expression_string.c_str(),
|
||||
expected_result,
|
||||
result);
|
||||
(double)expected_result,
|
||||
(double)result);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1481,8 +1481,8 @@ inline bool run_test01()
|
|||
{
|
||||
printf("run_test01() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
|
||||
test.expr.c_str(),
|
||||
test.result,
|
||||
result);
|
||||
(double)test.result,
|
||||
(double)result);
|
||||
loop_result = false;
|
||||
}
|
||||
}
|
||||
|
@ -1576,8 +1576,8 @@ inline bool run_test01()
|
|||
{
|
||||
printf("run_test01() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
|
||||
test.expr.c_str(),
|
||||
test.result,
|
||||
result);
|
||||
(double)test.result,
|
||||
(double)result);
|
||||
loop_result = false;
|
||||
}
|
||||
}
|
||||
|
@ -1900,8 +1900,8 @@ inline bool run_test02()
|
|||
{
|
||||
printf("run_test02() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
|
||||
test.expr.c_str(),
|
||||
test.result,
|
||||
result);
|
||||
(double)test.result,
|
||||
(double)result);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2038,10 +2038,10 @@ inline bool run_test04()
|
|||
{
|
||||
printf("run_test04() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\n",
|
||||
expression_string.c_str(),
|
||||
result1,
|
||||
result2,
|
||||
x,
|
||||
y);
|
||||
(double)result1,
|
||||
(double)result2,
|
||||
(double)x,
|
||||
(double)y);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2103,10 +2103,10 @@ inline bool run_test05()
|
|||
{
|
||||
printf("run_test05() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\tIndex:%d\n",
|
||||
expression_string.c_str(),
|
||||
real_result,
|
||||
result,
|
||||
x,
|
||||
y,
|
||||
(double)real_result,
|
||||
(double)result,
|
||||
(double)x,
|
||||
(double)y,
|
||||
static_cast<unsigned int>(i));
|
||||
return false;
|
||||
}
|
||||
|
@ -2156,8 +2156,8 @@ inline bool run_test06()
|
|||
if (not_equal(total_area1,T(pi) / T(2),T(0.000001)))
|
||||
{
|
||||
printf("run_test06() - Integration Error: Expected: %19.15f\tResult: %19.15f\n",
|
||||
pi / T(2),
|
||||
total_area1);
|
||||
(double)(pi / T(2)),
|
||||
(double)total_area1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2205,9 +2205,9 @@ inline bool run_test07()
|
|||
if (not_equal(deriv1_result1,deriv1_real_result,T(0.00001)))
|
||||
{
|
||||
printf("run_test07() - 1st Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n",
|
||||
x,
|
||||
deriv1_real_result,
|
||||
deriv1_result1);
|
||||
(double)x,
|
||||
(double)deriv1_real_result,
|
||||
(double)deriv1_result1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2226,9 +2226,9 @@ inline bool run_test07()
|
|||
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);
|
||||
(double)x,
|
||||
(double)deriv2_real_result,
|
||||
(double)deriv2_result1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2247,9 +2247,9 @@ inline bool run_test07()
|
|||
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);
|
||||
(double)x,
|
||||
(double)deriv3_real_result,
|
||||
(double)deriv3_result1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2454,26 +2454,26 @@ inline bool run_test09()
|
|||
for (std::size_t i = 0; i < rounds; ++i)
|
||||
{
|
||||
typedef exprtk::expression<T> expression_t;
|
||||
std::string expression_string = "myfunc0(sin(x*pi),y/2)+myfunc1(sin(x*pi),y/2)+"
|
||||
"myfunc2(sin(x*pi),y/2)+myfunc3(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)+"
|
||||
"myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)+"
|
||||
"myfunc0(sin(x*pi),y/2)+myfunc1(sin(x*pi),y/2)+"
|
||||
"myfunc2(sin(x*pi),y/2)+myfunc3(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)+"
|
||||
"myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)+"
|
||||
"myfunc0(sin(x*pi),y/2)+myfunc1(sin(x*pi),y/2)+"
|
||||
"myfunc2(sin(x*pi),y/2)+myfunc3(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)+"
|
||||
"myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)+"
|
||||
"myfunc0(sin(x*pi),y/2)+myfunc1(sin(x*pi),y/2)+"
|
||||
"myfunc2(sin(x*pi),y/2)+myfunc3(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)+"
|
||||
"myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)";
|
||||
std::string expression_string = "myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
|
||||
"myfunc2(sin(x * pi),y / 2) + myfunc3(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)+"
|
||||
"myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)+"
|
||||
"myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
|
||||
"myfunc2(sin(x * pi),y / 2) + myfunc3(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)+"
|
||||
"myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)+"
|
||||
"myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
|
||||
"myfunc2(sin(x * pi),y / 2) + myfunc3(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)+"
|
||||
"myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)+"
|
||||
"myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
|
||||
"myfunc2(sin(x * pi),y / 2) + myfunc3(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)+"
|
||||
"myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)";
|
||||
|
||||
T x = T(1) + (i / T(10000));
|
||||
T y = T(2) + (i / T(10000));
|
||||
|
@ -2528,8 +2528,8 @@ inline bool run_test09()
|
|||
if (not_equal(result,expected,T(0.0000001)))
|
||||
{
|
||||
printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n",
|
||||
expected,
|
||||
result);
|
||||
(double)expected,
|
||||
(double)result);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3515,8 +3515,8 @@ inline bool run_test15()
|
|||
if (not_equal(base_result,result))
|
||||
{
|
||||
printf("run_test15() - Error in evaluation! (1) Base: %20.10f\tResult: %20.10f\tExpression: %s\n",
|
||||
base_result,
|
||||
result,
|
||||
(double)base_result,
|
||||
(double)result,
|
||||
expr_str_list[i].c_str());
|
||||
failure = true;
|
||||
}
|
||||
|
@ -3999,7 +3999,7 @@ inline bool run_test19()
|
|||
|
||||
// f1(x) = 5 * (f0 + x)
|
||||
compositor
|
||||
.add("f1","5 * (f0+x)","x");
|
||||
.add("f1","5 * (f0 + x)","x");
|
||||
|
||||
// f2(x,y) = 7 * (f1(x) + f1(y))
|
||||
compositor
|
||||
|
@ -4068,9 +4068,9 @@ inline bool run_test19()
|
|||
|
||||
compositor
|
||||
.add("is_prime_impl1",
|
||||
"if(y == 1,true, "
|
||||
" if(0 == (x % y),false, "
|
||||
" is_prime_impl1(x,y-1)))",
|
||||
"if(y == 1,true, "
|
||||
" if(0 == (x % y),false, "
|
||||
" is_prime_impl1(x,y - 1)))",
|
||||
"x","y");
|
||||
|
||||
compositor
|
||||
|
@ -4466,8 +4466,8 @@ inline bool run_test19()
|
|||
printf("run_test19() - Computation Error "
|
||||
"Expression: [%s]\tExpected: %12.8f\tResult: %12.8f\n",
|
||||
expression_str.c_str(),
|
||||
std::sqrt(x),
|
||||
result);
|
||||
(double)std::sqrt(x),
|
||||
(double)result);
|
||||
failure = true;
|
||||
}
|
||||
}
|
||||
|
@ -4566,44 +4566,53 @@ inline bool run_test20()
|
|||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct type_name { static inline std::string value() { return "unknown"; } };
|
||||
template <> struct type_name<float> { static inline std::string value() { return "float"; } };
|
||||
template <> struct type_name<double> { static inline std::string value() { return "double"; } };
|
||||
template <> struct type_name<long double> { static inline std::string value() { return "long double"; } };
|
||||
|
||||
int main()
|
||||
{
|
||||
#define perform_test(Type,Number) \
|
||||
{ \
|
||||
exprtk::timer timer; \
|
||||
timer.start(); \
|
||||
if (!run_test##Number<Type>()) \
|
||||
{ \
|
||||
printf("run_test"#Number" ("#Type") *** FAILED! ***\n"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
timer.stop(); \
|
||||
printf("run_test"#Number" ("#Type") - Result: SUCCESS Time: %8.4fsec\n",timer.time()); \
|
||||
} \
|
||||
} \
|
||||
#define perform_test(Type,Number) \
|
||||
{ \
|
||||
exprtk::timer timer; \
|
||||
timer.start(); \
|
||||
if (!run_test##Number<Type>()) \
|
||||
{ \
|
||||
printf("run_test"#Number" (%s) *** FAILED! ***\n", \
|
||||
type_name<Type>::value().c_str()); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
timer.stop(); \
|
||||
printf("run_test"#Number" (%s) - Result: SUCCESS Time: %8.4fsec\n", \
|
||||
type_name<Type>::value().c_str(), \
|
||||
timer.time()); \
|
||||
} \
|
||||
} \
|
||||
|
||||
perform_test(double,00)
|
||||
perform_test(double,01)
|
||||
perform_test(double,02)
|
||||
perform_test(double,03)
|
||||
perform_test(double,04)
|
||||
perform_test(double,05)
|
||||
perform_test(double,06)
|
||||
perform_test(double,07)
|
||||
perform_test(double,08)
|
||||
perform_test(double,09)
|
||||
perform_test(double,10)
|
||||
perform_test(double,11)
|
||||
perform_test(double,12)
|
||||
perform_test(double,13)
|
||||
perform_test(double,14)
|
||||
perform_test(double,15)
|
||||
perform_test(double,16)
|
||||
perform_test(double,17)
|
||||
perform_test(double,18)
|
||||
perform_test(double,19)
|
||||
perform_test(double,20)
|
||||
perform_test(numeric_type,00)
|
||||
perform_test(numeric_type,01)
|
||||
perform_test(numeric_type,02)
|
||||
perform_test(numeric_type,03)
|
||||
perform_test(numeric_type,04)
|
||||
perform_test(numeric_type,05)
|
||||
perform_test(numeric_type,06)
|
||||
perform_test(numeric_type,07)
|
||||
perform_test(numeric_type,08)
|
||||
perform_test(numeric_type,09)
|
||||
perform_test(numeric_type,10)
|
||||
perform_test(numeric_type,11)
|
||||
perform_test(numeric_type,12)
|
||||
perform_test(numeric_type,13)
|
||||
perform_test(numeric_type,14)
|
||||
perform_test(numeric_type,15)
|
||||
perform_test(numeric_type,16)
|
||||
perform_test(numeric_type,17)
|
||||
perform_test(numeric_type,18)
|
||||
perform_test(numeric_type,19)
|
||||
perform_test(numeric_type,20)
|
||||
|
||||
#undef perform_test
|
||||
|
||||
|
|
Loading…
Reference in New Issue