C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
a0872d7a6d
commit
a60b7646c1
34
exprtk.hpp
34
exprtk.hpp
|
@ -142,7 +142,7 @@ namespace exprtk
|
||||||
"floor", "for", "grad2deg", "hyp", "if", "ilike", "in", "inrange",
|
"floor", "for", "grad2deg", "hyp", "if", "ilike", "in", "inrange",
|
||||||
"like", "log", "log10", "logn", "max", "min", "mod", "mul", "nand",
|
"like", "log", "log10", "logn", "max", "min", "mod", "mul", "nand",
|
||||||
"nor", "not", "not_equal", "or", "rad2deg", "root", "round", "roundn",
|
"nor", "not", "not_equal", "or", "rad2deg", "root", "round", "roundn",
|
||||||
"sec", "shl", "shr", "sin", "sinh", "sqrt", "sum", "tan", "tanh",
|
"sec", "sgn", "shl", "shr", "sin", "sinh", "sqrt", "sum", "tan", "tanh",
|
||||||
"while", "xor"
|
"while", "xor"
|
||||||
};
|
};
|
||||||
static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
|
static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
|
||||||
|
@ -447,6 +447,22 @@ namespace exprtk
|
||||||
return v0 << v1;
|
return v0 << v1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T sgn_impl(const T& v, real_type_tag)
|
||||||
|
{
|
||||||
|
if (v > T(0.0)) return T(+1.0);
|
||||||
|
else if (v < T(0.0)) return T(-1.0);
|
||||||
|
else return T( 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T sgn_impl(const T& v, int_type_tag)
|
||||||
|
{
|
||||||
|
if (v > T(0)) return T(+1);
|
||||||
|
else if (v < T(0)) return T(-1);
|
||||||
|
else return T( 0);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T xor_impl(const T& v0, const T& v1, real_type_tag)
|
inline T xor_impl(const T& v0, const T& v1, real_type_tag)
|
||||||
{
|
{
|
||||||
|
@ -546,6 +562,13 @@ namespace exprtk
|
||||||
return details::shl_impl(v0,v1,num_type);
|
return details::shl_impl(v0,v1,num_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T sgn(const T& v)
|
||||||
|
{
|
||||||
|
typename details::number_type<T>::type num_type;
|
||||||
|
return details::sgn_impl(v,num_type);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T xor_opr(const T& v0, const T& v1)
|
inline T xor_opr(const T& v0, const T& v1)
|
||||||
{
|
{
|
||||||
|
@ -1344,6 +1367,7 @@ namespace exprtk
|
||||||
e_cot ,
|
e_cot ,
|
||||||
e_clamp ,
|
e_clamp ,
|
||||||
e_inrange,
|
e_inrange,
|
||||||
|
e_sgn ,
|
||||||
e_r2d ,
|
e_r2d ,
|
||||||
e_d2r ,
|
e_d2r ,
|
||||||
e_d2g ,
|
e_d2g ,
|
||||||
|
@ -1437,6 +1461,7 @@ namespace exprtk
|
||||||
case e_d2g : return (arg * T(20/9));
|
case e_d2g : return (arg * T(20/9));
|
||||||
case e_g2d : return (arg * T(9/20));
|
case e_g2d : return (arg * T(9/20));
|
||||||
case e_not : return (arg != T(0) ? T(0) : T(1));
|
case e_not : return (arg != T(0) ? T(0) : T(1));
|
||||||
|
case e_sgn : return numeric::sgn(arg);
|
||||||
default : return std::numeric_limits<T>::quiet_NaN();
|
default : return std::numeric_limits<T>::quiet_NaN();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1454,6 +1479,7 @@ namespace exprtk
|
||||||
case e_pos : return +arg;
|
case e_pos : return +arg;
|
||||||
case e_sqrt : return std::sqrt (arg);
|
case e_sqrt : return std::sqrt (arg);
|
||||||
case e_not : return !arg;
|
case e_not : return !arg;
|
||||||
|
case e_sgn : return numeric::sgn(arg);
|
||||||
default : return std::numeric_limits<T>::quiet_NaN();
|
default : return std::numeric_limits<T>::quiet_NaN();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3403,6 +3429,7 @@ namespace exprtk
|
||||||
operation_t( "deg2rad" , e_d2r , 1),
|
operation_t( "deg2rad" , e_d2r , 1),
|
||||||
operation_t( "deg2grad" , e_d2g , 1),
|
operation_t( "deg2grad" , e_d2g , 1),
|
||||||
operation_t( "grad2deg" , e_g2d , 1),
|
operation_t( "grad2deg" , e_g2d , 1),
|
||||||
|
operation_t( "sgn" , e_sgn , 1),
|
||||||
operation_t( "not" , e_not , 1),
|
operation_t( "not" , e_not , 1),
|
||||||
operation_t( "atan2", e_atan2 , 2),
|
operation_t( "atan2", e_atan2 , 2),
|
||||||
operation_t( "min", e_min , 2),
|
operation_t( "min", e_min , 2),
|
||||||
|
@ -5418,7 +5445,10 @@ namespace exprtk
|
||||||
return error_node();
|
return error_node();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!all_nodes_valid(b))
|
//has the function call been completely optimized?
|
||||||
|
if (details::is_constant_node(result))
|
||||||
|
return result;
|
||||||
|
else if (!all_nodes_valid(b))
|
||||||
return error_node();
|
return error_node();
|
||||||
else if (N != f->param_count)
|
else if (N != f->param_count)
|
||||||
return error_node();
|
return error_node();
|
||||||
|
|
|
@ -600,6 +600,9 @@ static const test_t test_list[] =
|
||||||
test_t("clamp(-1,-1.5,+1.0) + clamp(-1,+1.5,+1.0)",0.0),
|
test_t("clamp(-1,-1.5,+1.0) + clamp(-1,+1.5,+1.0)",0.0),
|
||||||
test_t("inrange(-2,1,+2) == ((-2 <= 1) and (1 <= +2))",1.0),
|
test_t("inrange(-2,1,+2) == ((-2 <= 1) and (1 <= +2))",1.0),
|
||||||
test_t("inrange(-2,1,+2) == if(({-2 <= 1} and [1 <= +2]),1.0,0.0)",1.0),
|
test_t("inrange(-2,1,+2) == if(({-2 <= 1} and [1 <= +2]),1.0,0.0)",1.0),
|
||||||
|
test_t("sgn( 0)", 0.0),
|
||||||
|
test_t("sgn(+3)",+1.0),
|
||||||
|
test_t("sgn(-3)",-1.0),
|
||||||
test_t("equal($f00(1.1,2.2,3.3),((1.1+2.2)/3.3))",1.0),
|
test_t("equal($f00(1.1,2.2,3.3),((1.1+2.2)/3.3))",1.0),
|
||||||
test_t("equal($f01(1.1,2.2,3.3),((1.1+2.2)*3.3))",1.0),
|
test_t("equal($f01(1.1,2.2,3.3),((1.1+2.2)*3.3))",1.0),
|
||||||
test_t("equal($f02(1.1,2.2,3.3),((1.1-2.2)/3.3))",1.0),
|
test_t("equal($f02(1.1,2.2,3.3),((1.1-2.2)/3.3))",1.0),
|
||||||
|
@ -1365,16 +1368,26 @@ inline bool run_test09()
|
||||||
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;
|
||||||
std::string expression_string = "myfunc0(sin(x*pi),y/2)+"
|
std::string expression_string = "myfunc0(sin(x*pi),y/2)+myfunc1(sin(x*pi),y/2)+"
|
||||||
"myfunc1(sin(x*pi),y/2)+"
|
"myfunc2(sin(x*pi),y/2)+myfunc3(sin(x*pi),y/2)+"
|
||||||
"myfunc2(sin(x*pi),y/2)+"
|
"myfunc4(sin(x*pi),y/2)+myfunc5(sin(x*pi),y/2)+"
|
||||||
"myfunc3(sin(x*pi),y/2)+"
|
"myfunc6(sin(x*pi),y/2)+myfunc7(sin(x*pi),y/2)+"
|
||||||
"myfunc4(sin(x*pi),y/2)+"
|
"myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)+"
|
||||||
"myfunc5(sin(x*pi),y/2)+"
|
"myfunc0(sin(1*pi),y/2)+myfunc1(sin(1*pi),y/2)+"
|
||||||
"myfunc6(sin(x*pi),y/2)+"
|
"myfunc2(sin(1*pi),y/2)+myfunc3(sin(1*pi),y/2)+"
|
||||||
"myfunc7(sin(x*pi),y/2)+"
|
"myfunc4(sin(1*pi),y/2)+myfunc5(sin(1*pi),y/2)+"
|
||||||
"myfunc8(sin(x*pi),y/2)+"
|
"myfunc6(sin(1*pi),y/2)+myfunc7(sin(1*pi),y/2)+"
|
||||||
"myfunc9(sin(x*pi),y/2)";
|
"myfunc8(sin(1*pi),y/2)+myfunc9(sin(1*pi),y/2)+"
|
||||||
|
"myfunc0(sin(x*pi),2/2)+myfunc1(sin(x*pi),2/2)+"
|
||||||
|
"myfunc2(sin(x*pi),2/2)+myfunc3(sin(x*pi),2/2)+"
|
||||||
|
"myfunc4(sin(x*pi),2/2)+myfunc5(sin(x*pi),2/2)+"
|
||||||
|
"myfunc6(sin(x*pi),2/2)+myfunc7(sin(x*pi),2/2)+"
|
||||||
|
"myfunc8(sin(x*pi),2/2)+myfunc9(sin(x*pi),2/2)+"
|
||||||
|
"myfunc0(sin(1*pi),2/2)+myfunc1(sin(1*pi),2/2)+"
|
||||||
|
"myfunc2(sin(1*pi),2/2)+myfunc3(sin(1*pi),2/2)+"
|
||||||
|
"myfunc4(sin(1*pi),2/2)+myfunc5(sin(1*pi),2/2)+"
|
||||||
|
"myfunc6(sin(1*pi),2/2)+myfunc7(sin(1*pi),2/2)+"
|
||||||
|
"myfunc8(sin(1*pi),2/2)+myfunc9(sin(1*pi),2/2)";
|
||||||
|
|
||||||
T x = T(1.0);
|
T x = T(1.0);
|
||||||
T y = T(2.0);
|
T y = T(2.0);
|
||||||
|
@ -1408,7 +1421,8 @@ inline bool run_test09()
|
||||||
const T pi = T(3.14159265358979323846);
|
const T pi = T(3.14159265358979323846);
|
||||||
|
|
||||||
T result = expression.value();
|
T result = expression.value();
|
||||||
T expected = mf(sin(x*pi),y/2.0) +
|
T expected = T(4.0) *
|
||||||
|
(
|
||||||
mf(sin(x*pi),y/2.0) +
|
mf(sin(x*pi),y/2.0) +
|
||||||
mf(sin(x*pi),y/2.0) +
|
mf(sin(x*pi),y/2.0) +
|
||||||
mf(sin(x*pi),y/2.0) +
|
mf(sin(x*pi),y/2.0) +
|
||||||
|
@ -1417,7 +1431,9 @@ inline bool run_test09()
|
||||||
mf(sin(x*pi),y/2.0) +
|
mf(sin(x*pi),y/2.0) +
|
||||||
mf(sin(x*pi),y/2.0) +
|
mf(sin(x*pi),y/2.0) +
|
||||||
mf(sin(x*pi),y/2.0) +
|
mf(sin(x*pi),y/2.0) +
|
||||||
mf(sin(x*pi),y/2.0);
|
mf(sin(x*pi),y/2.0) +
|
||||||
|
mf(sin(x*pi),y/2.0)
|
||||||
|
);
|
||||||
|
|
||||||
if (not_equal<T>(result,expected,0.0000001))
|
if (not_equal<T>(result,expected,0.0000001))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue