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_real_type_tag
|
||||||
#undef exprtk_register_int_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>
|
template <typename T>
|
||||||
inline bool is_true_impl(const T v)
|
inline bool is_true_impl(const T v)
|
||||||
{
|
{
|
||||||
|
@ -479,13 +509,13 @@ namespace exprtk
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T equal_impl(const T v0, const T v1, real_type_tag)
|
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);
|
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)
|
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;
|
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>
|
template <typename T>
|
||||||
inline T nequal_impl(const T v0, const T v1, real_type_tag)
|
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);
|
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)
|
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;
|
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);
|
return (0.0 != v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool is_true(const long double v)
|
||||||
|
{
|
||||||
|
return (0.0 != v);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool is_true(const float v)
|
inline bool is_true(const float v)
|
||||||
{
|
{
|
||||||
return (0.0f != v);
|
return (0.0f != v);
|
||||||
|
@ -9547,7 +9582,7 @@ namespace exprtk
|
||||||
|
|
||||||
inline bool add_epsilon()
|
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);
|
return add_constant("epsilon",local_epsilon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
125
exprtk_test.cpp
125
exprtk_test.cpp
|
@ -27,8 +27,8 @@
|
||||||
|
|
||||||
#include "exprtk.hpp"
|
#include "exprtk.hpp"
|
||||||
|
|
||||||
|
typedef double numeric_type;
|
||||||
typedef std::pair<std::string,double> test_t;
|
typedef std::pair<std::string,numeric_type> test_t;
|
||||||
|
|
||||||
static const test_t test_list[] =
|
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",
|
printf("test_expression() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
|
||||||
expression_string.c_str(),
|
expression_string.c_str(),
|
||||||
expected_result,
|
(double)expected_result,
|
||||||
result);
|
(double)result);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1481,8 +1481,8 @@ inline bool run_test01()
|
||||||
{
|
{
|
||||||
printf("run_test01() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
|
printf("run_test01() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
|
||||||
test.expr.c_str(),
|
test.expr.c_str(),
|
||||||
test.result,
|
(double)test.result,
|
||||||
result);
|
(double)result);
|
||||||
loop_result = false;
|
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",
|
printf("run_test01() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
|
||||||
test.expr.c_str(),
|
test.expr.c_str(),
|
||||||
test.result,
|
(double)test.result,
|
||||||
result);
|
(double)result);
|
||||||
loop_result = false;
|
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",
|
printf("run_test02() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
|
||||||
test.expr.c_str(),
|
test.expr.c_str(),
|
||||||
test.result,
|
(double)test.result,
|
||||||
result);
|
(double)result);
|
||||||
return false;
|
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",
|
printf("run_test04() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\n",
|
||||||
expression_string.c_str(),
|
expression_string.c_str(),
|
||||||
result1,
|
(double)result1,
|
||||||
result2,
|
(double)result2,
|
||||||
x,
|
(double)x,
|
||||||
y);
|
(double)y);
|
||||||
return false;
|
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",
|
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(),
|
expression_string.c_str(),
|
||||||
real_result,
|
(double)real_result,
|
||||||
result,
|
(double)result,
|
||||||
x,
|
(double)x,
|
||||||
y,
|
(double)y,
|
||||||
static_cast<unsigned int>(i));
|
static_cast<unsigned int>(i));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2156,8 +2156,8 @@ inline bool run_test06()
|
||||||
if (not_equal(total_area1,T(pi) / T(2),T(0.000001)))
|
if (not_equal(total_area1,T(pi) / T(2),T(0.000001)))
|
||||||
{
|
{
|
||||||
printf("run_test06() - Integration Error: Expected: %19.15f\tResult: %19.15f\n",
|
printf("run_test06() - Integration Error: Expected: %19.15f\tResult: %19.15f\n",
|
||||||
pi / T(2),
|
(double)(pi / T(2)),
|
||||||
total_area1);
|
(double)total_area1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2205,9 +2205,9 @@ inline bool run_test07()
|
||||||
if (not_equal(deriv1_result1,deriv1_real_result,T(0.00001)))
|
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",
|
printf("run_test07() - 1st Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n",
|
||||||
x,
|
(double)x,
|
||||||
deriv1_real_result,
|
(double)deriv1_real_result,
|
||||||
deriv1_result1);
|
(double)deriv1_result1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2226,9 +2226,9 @@ inline bool run_test07()
|
||||||
if (not_equal(deriv2_result1,deriv2_real_result,T(0.01)))
|
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",
|
printf("run_test07() - 2nd Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n",
|
||||||
x,
|
(double)x,
|
||||||
deriv2_real_result,
|
(double)deriv2_real_result,
|
||||||
deriv2_result1);
|
(double)deriv2_result1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2247,9 +2247,9 @@ inline bool run_test07()
|
||||||
if (not_equal(deriv3_result1,deriv3_real_result,T(0.01)))
|
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",
|
printf("run_test07() - 3rd Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n",
|
||||||
x,
|
(double)x,
|
||||||
deriv3_real_result,
|
(double)deriv3_real_result,
|
||||||
deriv3_result1);
|
(double)deriv3_result1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2528,8 +2528,8 @@ inline bool run_test09()
|
||||||
if (not_equal(result,expected,T(0.0000001)))
|
if (not_equal(result,expected,T(0.0000001)))
|
||||||
{
|
{
|
||||||
printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n",
|
printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n",
|
||||||
expected,
|
(double)expected,
|
||||||
result);
|
(double)result);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3515,8 +3515,8 @@ inline bool run_test15()
|
||||||
if (not_equal(base_result,result))
|
if (not_equal(base_result,result))
|
||||||
{
|
{
|
||||||
printf("run_test15() - Error in evaluation! (1) Base: %20.10f\tResult: %20.10f\tExpression: %s\n",
|
printf("run_test15() - Error in evaluation! (1) Base: %20.10f\tResult: %20.10f\tExpression: %s\n",
|
||||||
base_result,
|
(double)base_result,
|
||||||
result,
|
(double)result,
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
failure = true;
|
failure = true;
|
||||||
}
|
}
|
||||||
|
@ -4466,8 +4466,8 @@ inline bool run_test19()
|
||||||
printf("run_test19() - Computation Error "
|
printf("run_test19() - Computation Error "
|
||||||
"Expression: [%s]\tExpected: %12.8f\tResult: %12.8f\n",
|
"Expression: [%s]\tExpected: %12.8f\tResult: %12.8f\n",
|
||||||
expression_str.c_str(),
|
expression_str.c_str(),
|
||||||
std::sqrt(x),
|
(double)std::sqrt(x),
|
||||||
result);
|
(double)result);
|
||||||
failure = true;
|
failure = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4566,6 +4566,12 @@ inline bool run_test20()
|
||||||
return true;
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
#define perform_test(Type,Number) \
|
#define perform_test(Type,Number) \
|
||||||
|
@ -4574,36 +4580,39 @@ int main()
|
||||||
timer.start(); \
|
timer.start(); \
|
||||||
if (!run_test##Number<Type>()) \
|
if (!run_test##Number<Type>()) \
|
||||||
{ \
|
{ \
|
||||||
printf("run_test"#Number" ("#Type") *** FAILED! ***\n"); \
|
printf("run_test"#Number" (%s) *** FAILED! ***\n", \
|
||||||
|
type_name<Type>::value().c_str()); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
timer.stop(); \
|
timer.stop(); \
|
||||||
printf("run_test"#Number" ("#Type") - Result: SUCCESS Time: %8.4fsec\n",timer.time()); \
|
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(numeric_type,00)
|
||||||
perform_test(double,01)
|
perform_test(numeric_type,01)
|
||||||
perform_test(double,02)
|
perform_test(numeric_type,02)
|
||||||
perform_test(double,03)
|
perform_test(numeric_type,03)
|
||||||
perform_test(double,04)
|
perform_test(numeric_type,04)
|
||||||
perform_test(double,05)
|
perform_test(numeric_type,05)
|
||||||
perform_test(double,06)
|
perform_test(numeric_type,06)
|
||||||
perform_test(double,07)
|
perform_test(numeric_type,07)
|
||||||
perform_test(double,08)
|
perform_test(numeric_type,08)
|
||||||
perform_test(double,09)
|
perform_test(numeric_type,09)
|
||||||
perform_test(double,10)
|
perform_test(numeric_type,10)
|
||||||
perform_test(double,11)
|
perform_test(numeric_type,11)
|
||||||
perform_test(double,12)
|
perform_test(numeric_type,12)
|
||||||
perform_test(double,13)
|
perform_test(numeric_type,13)
|
||||||
perform_test(double,14)
|
perform_test(numeric_type,14)
|
||||||
perform_test(double,15)
|
perform_test(numeric_type,15)
|
||||||
perform_test(double,16)
|
perform_test(numeric_type,16)
|
||||||
perform_test(double,17)
|
perform_test(numeric_type,17)
|
||||||
perform_test(double,18)
|
perform_test(numeric_type,18)
|
||||||
perform_test(double,19)
|
perform_test(numeric_type,19)
|
||||||
perform_test(double,20)
|
perform_test(numeric_type,20)
|
||||||
|
|
||||||
#undef perform_test
|
#undef perform_test
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue