C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html

This commit is contained in:
Arash Partow 2013-04-01 10:56:44 +11:00
parent 87d4220f7a
commit 7fdaf28b12
3 changed files with 2601 additions and 978 deletions

1396
exprtk.hpp

File diff suppressed because it is too large Load Diff

View File

@ -27,12 +27,13 @@
#include "exprtk.hpp" #include "exprtk.hpp"
typedef std::pair<std::string,double> test_t; typedef std::pair<std::string,double> test_t;
static const test_t test_list[] = static const test_t test_list[] =
{ {
// Note: The each of following tests should // Note: Each of following tests should all
// all compile down to a single literal node. // compile down to a single literal node.
test_t("0",0.0), test_t("0",0.0),
test_t("1",1.0), test_t("1",1.0),
test_t("2",2.0), test_t("2",2.0),
@ -567,6 +568,38 @@ static const test_t test_list[] =
test_t("(1.0 nor 0.0) == not(1.0 | 0.0)",1.0), test_t("(1.0 nor 0.0) == not(1.0 | 0.0)",1.0),
test_t("(0.0 nor 1.0) == not(0.0 | 1.0)",1.0), test_t("(0.0 nor 1.0) == not(0.0 | 1.0)",1.0),
test_t("(0.0 nor 0.0) == not(0.0 | 0.0)",1.0), test_t("(0.0 nor 0.0) == not(0.0 | 0.0)",1.0),
test_t("mand(1,1)",1.0),
test_t("mand(1,0)",0.0),
test_t("mand(0,1)",0.0),
test_t("mand(0,0)",0.0),
test_t("mand(1.0,1.0)",1.0),
test_t("mand(1.0,0.0)",0.0),
test_t("mand(0.0,1.0)",0.0),
test_t("mand(0.0,0.0)",0.0),
test_t("mor(1,1)",1.0),
test_t("mor(1,0)",1.0),
test_t("mor(0,1)",1.0),
test_t("mor(0,0)",0.0),
test_t("mor(1.0,1.0)",1.0),
test_t("mor(1.0,0.0)",1.0),
test_t("mor(0.0,1.0)",1.0),
test_t("mor(0.0,0.0)",0.0),
test_t("(1 nand 1) == not(mand(1,1))",1.0),
test_t("(1 nand 0) == not(mand(1,0))",1.0),
test_t("(0 nand 1) == not(mand(0,1))",1.0),
test_t("(0 nand 0) == not(mand(0,0))",1.0),
test_t("(1 nor 1) == not(mor(1,1))",1.0),
test_t("(1 nor 0) == not(mor(1,0))",1.0),
test_t("(0 nor 1) == not(mor(0,1))",1.0),
test_t("(0 nor 0) == not(mor(0,0))",1.0),
test_t("(1.0 nand 1.0) == not(mand(1.0,1.0))",1.0),
test_t("(1.0 nand 0.0) == not(mand(1.0,0.0))",1.0),
test_t("(0.0 nand 1.0) == not(mand(0.0,1.0))",1.0),
test_t("(0.0 nand 0.0) == not(mand(0.0,0.0))",1.0),
test_t("(1.0 nor 1.0) == not(mor(1.0,1.0))",1.0),
test_t("(1.0 nor 0.0) == not(mor(1.0,0.0))",1.0),
test_t("(0.0 nor 1.0) == not(mor(0.0,1.0))",1.0),
test_t("(0.0 nor 0.0) == not(mor(0.0,0.0))",1.0),
test_t("abs(1)",1.0), test_t("abs(1)",1.0),
test_t("abs(-1)",1.0), test_t("abs(-1)",1.0),
test_t("abs(1.0)",1.0), test_t("abs(1.0)",1.0),
@ -622,6 +655,11 @@ static const test_t test_list[] =
test_t("mul(1.1,2.2,3.3,4.4)",35.1384), test_t("mul(1.1,2.2,3.3,4.4)",35.1384),
test_t("mul(1.1,2.2,3.3,4.4,5.5)",193.2612), test_t("mul(1.1,2.2,3.3,4.4,5.5)",193.2612),
test_t("mul(1.1,2.2,3.3,4.4,5.5,6.6)",1275.52392), test_t("mul(1.1,2.2,3.3,4.4,5.5,6.6)",1275.52392),
test_t("equal(sum(1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9),(1.1+2.2+3.3+4.4+5.5+6.6+7.7+8.8+9.9))",1.0),
test_t("equal(mul(1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9),(1.1*2.2*3.3*4.4*5.5*6.6*7.7*8.8*9.9))",1.0),
test_t("equal(min(1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9),1.1)",1.0),
test_t("equal(max(1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9),9.9)",1.0),
test_t("equal(avg(1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9),5.5)",1.0),
test_t("floor(1.0)",1.0), test_t("floor(1.0)",1.0),
test_t("floor(1.1)",1.0), test_t("floor(1.1)",1.0),
test_t("floor(-1.0)",-1.0), test_t("floor(-1.0)",-1.0),
@ -846,7 +884,11 @@ static const test_t test_list[] =
test_t("equal(poly06(1.2345,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(7.7*1.2345^6+6.6*1.2345^5+5.5*1.2345^4+4.4*1.2345^3+3.3*1.2345^2+2.2*1.2345^1+1.1))",1.0), test_t("equal(poly06(1.2345,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(7.7*1.2345^6+6.6*1.2345^5+5.5*1.2345^4+4.4*1.2345^3+3.3*1.2345^2+2.2*1.2345^1+1.1))",1.0),
test_t("equal(poly07(1.2345,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(8.8*1.2345^7+7.7*1.2345^6+6.6*1.2345^5+5.5*1.2345^4+4.4*1.2345^3+3.3*1.2345^2+2.2*1.2345^1+1.1))",1.0), test_t("equal(poly07(1.2345,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(8.8*1.2345^7+7.7*1.2345^6+6.6*1.2345^5+5.5*1.2345^4+4.4*1.2345^3+3.3*1.2345^2+2.2*1.2345^1+1.1))",1.0),
test_t("equal(poly08(1.2345,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(9.9*1.2345^8+8.8*1.2345^7+7.7*1.2345^6+6.6*1.2345^5+5.5*1.2345^4+4.4*1.2345^3+3.3*1.2345^2+2.2*1.2345^1+1.1))",1.0), test_t("equal(poly08(1.2345,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(9.9*1.2345^8+8.8*1.2345^7+7.7*1.2345^6+6.6*1.2345^5+5.5*1.2345^4+4.4*1.2345^3+3.3*1.2345^2+2.2*1.2345^1+1.1))",1.0),
test_t("equal(poly09(1.2345,1.1,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(1.1*1.2345^9+9.9*1.2345^8+8.8*1.2345^7+7.7*1.2345^6+6.6*1.2345^5+5.5*1.2345^4+4.4*1.2345^3+3.3*1.2345^2+2.2*1.2345^1+1.1))",1.0) test_t("equal(poly09(1.2345,1.1,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(1.1*1.2345^9+9.9*1.2345^8+8.8*1.2345^7+7.7*1.2345^6+6.6*1.2345^5+5.5*1.2345^4+4.4*1.2345^3+3.3*1.2345^2+2.2*1.2345^1+1.1))",1.0),
test_t("equal(poly10(1.37,2.2,1.1,9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1),(2.2*1.37^10+1.1*1.37^9+9.9*1.37^8+8.8*1.37^7+7.7*1.37^6+6.6*1.37^5+5.5*1.37^4+4.4*1.37^3+3.3*1.37^2+2.2*1.37^1+1.1))",1.0),
test_t("equal(poly11(1.37,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.3*1.37^11+2.2*1.37^10+1.1*1.37^9+9.9*1.37^8+8.8*1.37^7+7.7*1.37^6+6.6*1.37^5+5.5*1.37^4+4.4*1.37^3+3.3*1.37^2+2.2*1.37^1+1.1))",1.0),
test_t("equal(poly12(1.37,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.4*1.37^12+3.3*1.37^11+2.2*1.37^10+1.1*1.37^9+9.9*1.37^8+8.8*1.37^7+7.7*1.37^6+6.6*1.37^5+5.5*1.37^4+4.4*1.37^3+3.3*1.37^2+2.2*1.37^1+1.1))",1.0),
test_t("equal(\t \n(\n \r1.1\t\t - \n\n 2.2\n\n/\r3.3\t),(1.1-2.2/3.3))",1.0),
}; };
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_t); static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_t);
@ -2486,7 +2528,19 @@ inline bool run_test12()
"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(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(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(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))" "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))",
"EquaL(Poly01(x,2.2,1.1),(2.2x^1+1.1))",
"eQuAl(pOly02(x,3.3,2.2,1.1),(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(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(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(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(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(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(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);
@ -2656,6 +2710,10 @@ inline std::size_t load_expressions(const std::string& file_name,
std::size_t line_count = 0; std::size_t line_count = 0;
while (std::getline(stream,buffer)) while (std::getline(stream,buffer))
{ {
if (buffer.empty())
continue;
else if ('#' == buffer[0])
continue;
++line_count; ++line_count;
sequence.push_back(buffer); sequence.push_back(buffer);
} }
@ -2774,30 +2832,32 @@ inline bool run_test15()
symbol_table.add_variable("y",y); symbol_table.add_variable("y",y);
symbol_table.add_variable("z",z); symbol_table.add_variable("z",z);
std::deque<std::string> expr_str_list; static const std::string expr_str_list[] =
{
expr_str_list.push_back("2 - (x + y) / z//Comment 01 "); "2 - (x + y) / z//Comment 01 ",
expr_str_list.push_back("2 - (x + y) / z#Comment 02 "); "2 - (x + y) / z#Comment 02 ",
expr_str_list.push_back("2 - (x + y) / z //Comment 03 "); "2 - (x + y) / z //Comment 03 ",
expr_str_list.push_back("2 - (x + y) / z #Comment 04 "); "2 - (x + y) / z #Comment 04 ",
expr_str_list.push_back("2 - (x + y) / z//Comment 05 \n"); "2 - (x + y) / z//Comment 05 \n",
expr_str_list.push_back("2 - (x + y) / z#Comment 06 \n"); "2 - (x + y) / z#Comment 06 \n",
expr_str_list.push_back("2 - (x + y) / z //Comment 07\n"); "2 - (x + y) / z //Comment 07\n",
expr_str_list.push_back("2 - (x + y) / z #Comment 08 \n"); "2 - (x + y) / z #Comment 08 \n",
expr_str_list.push_back("/* Comment 09*/2 - (x + y) / z"); "/* Comment 09*/2 - (x + y) / z",
expr_str_list.push_back("/* Comment 10*/2 - (x + y) / z\n"); "/* Comment 10*/2 - (x + y) / z\n",
expr_str_list.push_back("/* Comment 11*/2 - (x + y) / z/* Comment 12*/"); "/* Comment 11*/2 - (x + y) / z/* Comment 12*/",
expr_str_list.push_back("/* Comment 13*/2 - (x + y) / z/* Comment 14*/\n"); "/* Comment 13*/2 - (x + y) / z/* Comment 14*/\n",
expr_str_list.push_back("2 - /* Comment 15 */(x + y) / z"); "2 - /* Comment 15 */(x + y) / z",
expr_str_list.push_back("2 - /* Comment 15 */(x + y) /* Comment 16 *// z \n"); "2 - /* Comment 15 */(x + y) /* Comment 16 *// z \n",
expr_str_list.push_back("2 - /* Comment 17 */(x + y) /* Comment 18 */ / z //Comment 19\n"); "2 - /* Comment 17 */(x + y) /* Comment 18 */ / z //Comment 19\n",
expr_str_list.push_back("2 - /* Comment 20 */(x + y) /* Comment 21 */ / z #Comment 22\n"); "2 - /* Comment 20 */(x + y) /* Comment 21 */ / z #Comment 22\n",
expr_str_list.push_back("2 - /* Comment 23 */(x + y) /* Comment 24 */ / z //Comment 25"); "2 - /* Comment 23 */(x + y) /* Comment 24 */ / z //Comment 25",
expr_str_list.push_back("2 - /* Comment 26 */(x + y) /* Comment 27 */ / z #Comment 28"); "2 - /* Comment 26 */(x + y) /* Comment 27 */ / z #Comment 28"
};
static const std::size_t expr_str_list_size = sizeof(expr_str_list) / sizeof(std::string);
std::deque<expression_t> expression_list; std::deque<expression_t> expression_list;
for (std::size_t i = 0; i < expr_str_list.size(); ++i) for (std::size_t i = 0; i < expr_str_list_size; ++i)
{ {
expression_t expression; expression_t expression;
expression.register_symbol_table(symbol_table); expression.register_symbol_table(symbol_table);
@ -2852,6 +2912,367 @@ inline bool run_test15()
return !failure; return !failure;
} }
template <typename T>
struct base_func : public exprtk::ifunction<T>
{
typedef const T& type;
base_func(const std::size_t& n) : exprtk::ifunction<T>(n) {}
inline T operator()(type v0, type v1, type v2, type v3, type v4) { return (v0 + v1 + v2 + v3 + v4); }
inline T operator()(type v0, type v1, type v2, type v3) { return (v0 + v1 + v2 + v3); }
inline T operator()(type v0, type v1, type v2) { return (v0 + v1 + v2); }
inline T operator()(type v0, type v1) { return (v0 + v1); }
inline T operator()(type v0) { return v0; }
inline T operator()() { return T(1.1234); }
};
template <typename T> struct test_func5 : public base_func<T> { test_func5() : base_func<T>(5){} };
template <typename T> struct test_func4 : public base_func<T> { test_func4() : base_func<T>(4){} };
template <typename T> struct test_func3 : public base_func<T> { test_func3() : base_func<T>(3){} };
template <typename T> struct test_func2 : public base_func<T> { test_func2() : base_func<T>(2){} };
template <typename T> struct test_func1 : public base_func<T> { test_func1() : base_func<T>(1){} };
template <typename T> struct test_func0 : public base_func<T> { test_func0() : base_func<T>(0){} };
template <typename T>
inline bool run_test16()
{
typedef exprtk::expression<T> expression_t;
T x = T(1.1);
T y = T(2.2);
T z = T(3.3);
T w = T(4.4);
T u = T(5.5);
test_func0<T> test_func00;
test_func1<T> test_func01;
test_func2<T> test_func02;
test_func3<T> test_func03;
test_func4<T> test_func04;
test_func5<T> test_func05;
exprtk::symbol_table<T> symbol_table;
symbol_table.add_constants();
symbol_table.add_variable("x",x);
symbol_table.add_variable("y",y);
symbol_table.add_variable("z",z);
symbol_table.add_variable("w",w);
symbol_table.add_variable("u",u);
symbol_table.add_function("test_func0",test_func00);
symbol_table.add_function("test_func1",test_func01);
symbol_table.add_function("test_func2",test_func02);
symbol_table.add_function("test_func3",test_func03);
symbol_table.add_function("test_func4",test_func04);
symbol_table.add_function("test_func5",test_func05);
static const std::string expr_str_list[] =
{
"test_func0 = test_func0()",
"test_func0 == test_func0()",
"equal(1.1 + test_func0,test_func0() + 1.1)",
"equal(test_func0 + 1.1,1.1 + test_func0())",
"equal((1.1 + test_func0),(test_func0() + 1.1))",
"equal((test_func0 + 1.1),(1.1 + test_func0()))",
"equal(test_func0,test_func0())",
"equal(test_func0,1.1234)",
"equal(test_func0(),1.1234)",
"equal(test_func0 + test_func0(),2 * 1.1234)",
"equal((test_func0 + test_func0()),2 * 1.1234)",
"equal((test_func0) + (test_func0()),2 * 1.1234)",
"equal(test_func1(x),(x))",
"equal(test_func2(x,y),(x + y))",
"equal(test_func3(x,y,z),(x + y + z))",
"equal(test_func4(x,y,z,w),(x + y + z + w))",
"equal(test_func5(x,y,z,w,u),(x + y + z + w + u))",
"equal(1.1 + test_func0,1.1234 + 1.1)",
"equal(1.1 + test_func0(),1.1234 + 1.1)",
"equal(1.1 + test_func1(x),(x + 1.1))",
"equal(1.1 + test_func2(x,y),(x + y + 1.1))",
"equal(1.1 + test_func3(x,y,z),(x + y + z + 1.1))",
"equal(1.1 + test_func4(x,y,z,w),(x + y + z + w + 1.1))",
"equal(1.1 + test_func5(x,y,z,w,u),(x + y + z + w + u + 1.1))",
"equal(test_func0 + 2.2,1.1234 + 2.2)",
"equal(test_func0() + 2.2,1.1234 + 2.2)",
"equal(test_func1(x) + 2.2,(x + 2.2))",
"equal(test_func2(x,y) + 2.2,(x + y + 2.2))",
"equal(test_func3(x,y,z) + 2.2,(x + y + z + 2.2))",
"equal(test_func4(x,y,z,w) + 2.2,(x + y + z + w + 2.2))",
"equal(test_func5(x,y,z,w,u) + 2.2,(x + y + z + w + u + 2.2))",
"equal({[test_func1(x)]},{[(x)]})",
"equal({[test_func2(x,y)]},{[(x + y)]})",
"equal({[test_func3(x,y,z)]},{[(x + y + z)]})",
"equal({[test_func4(x,y,z,w)]},{[(x + y + z + w)]})",
"equal({[test_func5(x,y,z,w,u)]},{[(x + y + z + w + u)]})",
"equal(test_func1(2.12),(2.12))",
"equal(test_func2(2.12,3.12),(2.12 + 3.12))",
"equal(test_func3(2.12,3.12,4.12),(2.12 + 3.12 + 4.12))",
"equal(test_func4(2.12,3.12,4.12,5.12),(2.12 + 3.12 + 4.12 + 5.12))",
"equal(test_func5(2.12,3.12,4.12,5.12,6.12),(2.12 + 3.12 + 4.12 + 5.12 + 6.12))",
"equal(1.1 + test_func1(2.12),(2.12 + 1.1))",
"equal(1.1 + test_func2(2.12,3.12),(2.12 + 3.12 + 1.1))",
"equal(1.1 + test_func3(2.12,3.12,4.12),(2.12 + 3.12 + 4.12 + 1.1))",
"equal(1.1 + test_func4(2.12,3.12,4.12,5.12),(2.12 + 3.12 + 4.12 + 5.12 + 1.1))",
"equal(1.1 + test_func5(2.12,3.12,4.12,5.12,6.12),(2.12 + 3.12 + 4.12 + 5.12 + 6.12 + 1.1))",
"equal(test_func1(2.12) + 2.2,(2.12 + 2.2))",
"equal(test_func2(2.12,3.12) + 2.2,(2.12 + 3.12 + 2.2))",
"equal(test_func3(2.12,3.12,4.12) + 2.2,(2.12 + 3.12 + 4.12 + 2.2))",
"equal(test_func4(2.12,3.12,4.12,5.12) + 2.2,(2.12 + 3.12 + 4.12 + 5.12 + 2.2))",
"equal(test_func5(2.12,3.12,4.12,5.12,6.12) + 2.2,(2.12 + 3.12 + 4.12 + 5.12 + 6.12 + 2.2))",
"equal({[test_func1(2.12)]},{[(2.12)]})",
"equal({[test_func2(2.12,3.12)]},{[(2.12 + 3.12)]})",
"equal({[test_func3(2.12,3.12,4.12)]},{[(2.12 + 3.12 + 4.12)]})",
"equal({[test_func4(2.12,3.12,4.12,5.12)]},{[(2.12 + 3.12 + 4.12 + 5.12)]})",
"equal({[test_func5(2.12,3.12,4.12,5.12,6.12)]},{[(2.12 + 3.12 + 4.12 + 5.12 + 6.12)]})",
"TeSt_FuNc0 = tEsT_fUnC0()",
"TEst_fuNC0 == tESt_fUNc0()",
"EquaL(tEsT_FuNC1(x),(x))",
"eQuAl(teSt_fUnc2(x,y),(x + y))",
"EqUaL(tEsT_fUNc3(x,y,z),(x + y + z))",
"EQUal(TEst_FunC4(x,y,z,w),(x + y + z + w))",
"eqUAL(tEsT_FuNc5(x,y,z,w,u),(x + y + z + w + u))"
};
static const std::size_t expr_str_list_size = sizeof(expr_str_list) / sizeof(std::string);
std::deque<expression_t> expression_list;
for (std::size_t i = 0; i < expr_str_list_size; ++i)
{
expression_t expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
if (!parser.compile(expr_str_list[i],expression))
{
printf("run_test16() - Error: %s Expression: %s\n",
parser.error().c_str(),
expr_str_list[i].c_str());
return false;
}
else
expression_list.push_back(expression);
}
bool failure = false;
for (std::size_t i = 0; i < expression_list.size(); ++i)
{
if (T(1) != expression_list[i].value())
{
printf("run_test16() - Error in evaluation! (1) Expression: %s\n",
expr_str_list[i].c_str());
failure = true;
}
}
return !failure;
}
template <typename T>
inline bool run_test17()
{
typedef exprtk::expression<T> expression_t;
T x = T(1.1);
T y = T(2.2);
T z = T(3.3);
T w = T(4.4);
T u = T(5.5);
T v = T(6.6);
T t = T(7.7);
T one = T(1.0);
T zero = T(0.0);
exprtk::symbol_table<T> symbol_table;
symbol_table.add_constants();
symbol_table.add_variable("x",x);
symbol_table.add_variable("y",y);
symbol_table.add_variable("z",z);
symbol_table.add_variable("w",w);
symbol_table.add_variable("u",u);
symbol_table.add_variable("v",v);
symbol_table.add_variable("t",t);
symbol_table.add_variable("one",one);
symbol_table.add_variable("zero",zero);
static const std::string expr_str_list[] =
{
"equal(mand(one,one),1.0)",
"equal(mand(one,zero),0.0)",
"equal(mand(zero,one),0.0)",
"equal(mand(zero,zero),0.0)",
"equal(mand(one,one),1.0)",
"equal(mand(one,one,one),1.0)",
"equal(mand(one,one,one,one),1.0)",
"equal(mand(one,one,one,one,one),1.0)",
"equal(mand(one,one,zero),0.0)",
"equal(mand(one,one,one,zero),0.0)",
"equal(mand(one,one,one,one,zero),0.0)",
"equal(mand(one,one,one,one,one,zero),0.0)",
"equal(mor(one,one),1.0)",
"equal(mor(one,zero),1.0)",
"equal(mor(zero,one),1.0)",
"equal(mor(zero,zero),0.0)",
"equal(mor(one,one),1.0)",
"equal(mor(one,one,zero),1.0)",
"equal(mor(one,zero,one),1.0)",
"equal(mor(one,zero,one,zero),1.0)",
"equal(mor(zero,one),1.0)",
"equal(mor(zero,zero,one),1.0)",
"equal(mor(zero,zero,zero,zero,one),1.0)",
"equal(mor(zero,zero,zero,zero,zero,one),1.0)",
"equal(mor(zero,zero,zero,zero,zero,zero,zero,zero),0.0)",
"equal((one nand one),not(mand(one,one)))",
"equal((one nand zero),not(mand(one,zero)))",
"equal((zero nand one),not(mand(zero,one)))",
"equal((zero nand zero),not(mand(zero,zero)))",
"equal((one nor one),not(mor(one,one)))",
"equal((one nor zero),not(mor(one,zero)))",
"equal((zero nor one),not(mor(zero,one)))",
"equal((zero nor zero),not(mor(zero,zero)))",
"equal(sum(x,y,z,w,u,v,t),(x+y+z+w+u+v+t))",
"equal(sum(x+t,y+v,z+u,w+w,u+z,v+y,t+x),2*(x+y+z+w+u+v+t))",
"equal(mul(x,y,z,w,u,v,t),(x*y*z*w*u*v*t))",
"equal(mul(x*t,y*v,z*u,w*w,u*z,v*y,t*x),(x*y*z*w*u*v*t)^2)",
"equal(sum(x,1.0,y,2.0,z,3.0,w,4.0,u,5.0,v,6.0,t),(x+y+z+w+u+v+t+21.0))",
"equal(sum(x+1.0,y+2.0,z+3.0,w+4.0,u+5.0,v+6.0,t),(x+y+z+w+u+v+t+21.0))",
"equal(mul(x,1.0,y,2.0,z,3.0,w,4.0,u,5.0,v,6.0,t),(x*y*z*w*u*v*t*720.0))",
"equal(mul(x*1.0,y*2.0,z*3.0,w*4.0,u*5.0,v*6.0,t),(x*y*z*w*u*v*t*720.0))",
"equal(min(x,y,z,w,u,v,t,zero),zero)",
"equal(min(x+y,z+w,u+v,t,zero),zero)",
"equal(max(one,x,y,z,w,u,v,t),t)",
"equal(max(x+y,z+w,u+v,t,one),u+v)",
"equal(avg(x,y,z,w,u,v,t),(x+y+z+w+u+v+t)/7.0)",
"equal(avg(x+t,y+v,z+u,w+w,u+z,v+y,t+x),2/7*(x+y+z+w+u+v+t))"
};
static const std::size_t expr_str_list_size = sizeof(expr_str_list) / sizeof(std::string);
std::deque<expression_t> expression_list;
for (std::size_t i = 0; i < expr_str_list_size; ++i)
{
expression_t expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
if (!parser.compile(expr_str_list[i],expression))
{
printf("run_test17() - Error: %s Expression: %s\n",
parser.error().c_str(),
expr_str_list[i].c_str());
return false;
}
else
expression_list.push_back(expression);
}
bool failure = false;
for (std::size_t i = 0; i < expression_list.size(); ++i)
{
if (T(1) != expression_list[i].value())
{
printf("run_test17() - Error in evaluation! (1) Expression: %s\n",
expr_str_list[i].c_str());
failure = true;
}
}
return !failure;
}
template <typename T>
struct va_func : public exprtk::ivararg_function<T>
{
inline T operator()(const std::vector<T>& arglist)
{
T result = T(0);
for (std::size_t i = 0; i < arglist.size(); ++i)
{
result += arglist[i];
}
return result;
}
};
template <typename T>
inline bool run_test18()
{
typedef exprtk::expression<T> expression_t;
T x = T(1.1);
T y = T(2.2);
T z = T(3.3);
T w = T(4.4);
T u = T(5.5);
T v = T(6.6);
T t = T(7.7);
va_func<T> vaf;
exprtk::symbol_table<T> symbol_table;
symbol_table.add_constants();
symbol_table.add_variable("x",x);
symbol_table.add_variable("y",y);
symbol_table.add_variable("z",z);
symbol_table.add_variable("w",w);
symbol_table.add_variable("u",u);
symbol_table.add_variable("v",v);
symbol_table.add_variable("t",t);
symbol_table.add_vararg_function("va_func",vaf);
static const std::string expr_str_list[] =
{
"equal(va_func(1,2,3,4,5,6,7,8,9),(1+2+3+4+5+6+7+8+9))",
"equal(va_func(1,x,3,y,5,z,7,w,9),(1+x+3+y+5+z+7+w+9))",
"equal(va_func(x,2,y,4,z,6,w,8,u),(x+2+y+4+z+6+w+8+u))",
"equal(va_func(x,y,z,w,u,v,t,1,2,3),(x+y+z+w+u+v+t+1+2+3))",
"equal(va_func(x,y,z,w,u,v,t),(x+y+z+w+u+v+t))",
"equal(va_func(x+t,y+v,z+u,w+w,u+z,v+y,t+x),2*(x+y+z+w+u+v+t))",
"equal(1+va_func(1,x,3,y,5,z,7,w,9),(1+x+3+y+5+z+7+w+9)+1)",
"equal(va_func(va_func(x,y,z,w,u,v,t),va_func(x,y,z,w,u,v,t)),2*(x+y+z+w+u+v+t))",
"equal(va_func(va_func(x),va_func(y),va_func(z)),va_func(x,y,z))"
};
static const std::size_t expr_str_list_size = sizeof(expr_str_list) / sizeof(std::string);
std::deque<expression_t> expression_list;
for (std::size_t i = 0; i < expr_str_list_size; ++i)
{
expression_t expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
if (!parser.compile(expr_str_list[i],expression))
{
printf("run_test18() - Error: %s Expression: %s\n",
parser.error().c_str(),
expr_str_list[i].c_str());
return false;
}
else
expression_list.push_back(expression);
}
bool failure = false;
for (std::size_t i = 0; i < expression_list.size(); ++i)
{
if (T(1) != expression_list[i].value())
{
printf("run_test18() - Error in evaluation! (1) Expression: %s\n",
expr_str_list[i].c_str());
failure = true;
}
}
return !failure;
}
int main() int main()
{ {
#define perform_test(Type,Number) \ #define perform_test(Type,Number) \
@ -2885,6 +3306,9 @@ int main()
perform_test(double,13) perform_test(double,13)
perform_test(double,14) perform_test(double,14)
perform_test(double,15) perform_test(double,15)
perform_test(double,16)
perform_test(double,17)
perform_test(double,18)
#undef perform_test #undef perform_test

View File

@ -160,6 +160,14 @@ Expression Library can be found at:
| and | Logical AND, True only if x and y are both true. | | and | Logical AND, True only if x and y are both true. |
| | (eg: x and y) | | | (eg: x and y) |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
| mand | Multi-input logical AND, True only if all inputs are |
| | true. Left to right short-circuiting of expressions. |
| | (eg: mand(x > y,z < w,u or v,w and x)) |
+-----------|--------------------------------------------------------+
| mor | Multi-input logical OR, True if at least one of the |
| | inputs are true. Left to right short-circuiting of |
| | expressions. (eg: mand(x > y,z < w,u or v,w and x)) |
+-----------+--------------------------------------------------------+
| nand | Logical NAND, True only if either x or y is false. | | nand | Logical NAND, True only if either x or y is false. |
| | (eg: x nand y) | | | (eg: x nand y) |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
@ -179,6 +187,12 @@ Expression Library can be found at:
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
| if | If x is true then return y else return z. | | if | If x is true then return y else return z. |
| | (eg: if(x, y, z) or if((x + 1) > 2y, z + 1, w / v)) | | | (eg: if(x, y, z) or if((x + 1) > 2y, z + 1, w / v)) |
+-----------|--------------------------------------------------------+
| & | Similar to AND but with left to right expression short |
| | circuiting optimisation. (eg: (x & y) == (y and x)) |
+-----------|--------------------------------------------------------+
| | | Similar to OR but with left to right expression short |
| | circuiting optimisation. (eg: (x | y) == (y or x)) |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
(3) General Purpose Functions (3) General Purpose Functions
@ -188,7 +202,7 @@ Expression Library can be found at:
| abs | Absolute value of x. | | abs | Absolute value of x. |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
| avg | Average of all the inputs. | | avg | Average of all the inputs. |
| | (eg: avg(x,y,z,w) == (x+y+z+w)/4) | | | (eg: avg(x,y,z,w,u,v) == (x+y+z+w+u+v)/6) |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
| ceil | Smallest integer that is greater than or equal to x. | | ceil | Smallest integer that is greater than or equal to x. |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
@ -219,9 +233,12 @@ Expression Library can be found at:
| logn | Base N logarithm of x (eg: logn(1235,8)) | | logn | Base N logarithm of x (eg: logn(1235,8)) |
| | where n > 0 and is an integer. | | | where n > 0 and is an integer. |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
| max | Largest value of all the inputs. (eg: max(x,y,z,w)) | | max | Largest value of all the inputs. (eg: max(x,y,z,w,u,v))|
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
| min | Smallest value of all the inputs. (eg: min(x,y,z,w)) | | min | Smallest value of all the inputs. (eg: min(x,y,z,w,u)) |
+-----------+--------------------------------------------------------+
| mul | Product of all the inputs. |
| | (eg: mul(x,y,z,w,u,v,t) == (x*y*z*w*u*v*t)) |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
| nequal | Not-equal test between x and y using normalized epsilon| | nequal | Not-equal test between x and y using normalized epsilon|
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
@ -238,7 +255,7 @@ Expression Library can be found at:
| sqrt | Square root of x, where x > 0 | | sqrt | Square root of x, where x > 0 |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
| sum | Sum of all the inputs. | | sum | Sum of all the inputs. |
| | (eg: sum(x,y,z,w,v) == (x+y+z+w+v)) | | | (eg: sum(x,y,z,w,u,v,t) == (x+y+z+w+u+v+t)) |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
| trunc | Integer portion of x | | trunc | Integer portion of x |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
@ -405,7 +422,9 @@ correctly optimize such expressions for a given architecture.
be enclosed with single-quotes. be enclosed with single-quotes.
eg: 'Frankly, my dear, I don't give a damn!' eg: 'Frankly, my dear, I don't give a damn!'
(10) User defined functions can have up to 20 parameters. (10) User defined normal functions can have up to 20 parameters.
Where as user defined vararg-functions can have unlimited an
number of parameters.
(11) The inbuilt polynomial functions can be at most of degree 12. (11) The inbuilt polynomial functions can be at most of degree 12.