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"
typedef std::pair<std::string,double> test_t;
static const test_t test_list[] =
{
// Note: The each of following tests should
// all compile down to a single literal node.
// Note: Each of following tests should all
// compile down to a single literal node.
test_t("0",0.0),
test_t("1",1.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("(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("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.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,5.5)",193.2612),
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.1)",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(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(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);
@ -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(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))"
"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);
@ -2656,6 +2710,10 @@ inline std::size_t load_expressions(const std::string& file_name,
std::size_t line_count = 0;
while (std::getline(stream,buffer))
{
if (buffer.empty())
continue;
else if ('#' == buffer[0])
continue;
++line_count;
sequence.push_back(buffer);
}
@ -2774,30 +2832,32 @@ inline bool run_test15()
symbol_table.add_variable("y",y);
symbol_table.add_variable("z",z);
std::deque<std::string> expr_str_list;
expr_str_list.push_back("2 - (x + y) / z//Comment 01 ");
expr_str_list.push_back("2 - (x + y) / z#Comment 02 ");
expr_str_list.push_back("2 - (x + y) / z //Comment 03 ");
expr_str_list.push_back("2 - (x + y) / z #Comment 04 ");
expr_str_list.push_back("2 - (x + y) / z//Comment 05 \n");
expr_str_list.push_back("2 - (x + y) / z#Comment 06 \n");
expr_str_list.push_back("2 - (x + y) / z //Comment 07\n");
expr_str_list.push_back("2 - (x + y) / z #Comment 08 \n");
expr_str_list.push_back("/* Comment 09*/2 - (x + y) / z");
expr_str_list.push_back("/* Comment 10*/2 - (x + y) / z\n");
expr_str_list.push_back("/* Comment 11*/2 - (x + y) / z/* Comment 12*/");
expr_str_list.push_back("/* Comment 13*/2 - (x + y) / z/* Comment 14*/\n");
expr_str_list.push_back("2 - /* Comment 15 */(x + y) / z");
expr_str_list.push_back("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");
expr_str_list.push_back("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");
expr_str_list.push_back("2 - /* Comment 26 */(x + y) /* Comment 27 */ / z #Comment 28");
static const std::string expr_str_list[] =
{
"2 - (x + y) / z//Comment 01 ",
"2 - (x + y) / z#Comment 02 ",
"2 - (x + y) / z //Comment 03 ",
"2 - (x + y) / z #Comment 04 ",
"2 - (x + y) / z//Comment 05 \n",
"2 - (x + y) / z#Comment 06 \n",
"2 - (x + y) / z //Comment 07\n",
"2 - (x + y) / z #Comment 08 \n",
"/* Comment 09*/2 - (x + y) / z",
"/* Comment 10*/2 - (x + y) / z\n",
"/* Comment 11*/2 - (x + y) / z/* Comment 12*/",
"/* Comment 13*/2 - (x + y) / z/* Comment 14*/\n",
"2 - /* Comment 15 */(x + y) / z",
"2 - /* Comment 15 */(x + y) /* Comment 16 *// z \n",
"2 - /* Comment 17 */(x + y) /* Comment 18 */ / z //Comment 19\n",
"2 - /* Comment 20 */(x + y) /* Comment 21 */ / z #Comment 22\n",
"2 - /* Comment 23 */(x + y) /* Comment 24 */ / z //Comment 25",
"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;
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.register_symbol_table(symbol_table);
@ -2852,6 +2912,367 @@ inline bool run_test15()
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()
{
#define perform_test(Type,Number) \
@ -2885,6 +3306,9 @@ int main()
perform_test(double,13)
perform_test(double,14)
perform_test(double,15)
perform_test(double,16)
perform_test(double,17)
perform_test(double,18)
#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. |
| | (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. |
| | (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. |
| | (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
@ -188,7 +202,7 @@ Expression Library can be found at:
| abs | Absolute value of x. |
+-----------+--------------------------------------------------------+
| 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. |
+-----------+--------------------------------------------------------+
@ -219,9 +233,12 @@ Expression Library can be found at:
| logn | Base N logarithm of x (eg: logn(1235,8)) |
| | 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|
+-----------+--------------------------------------------------------+
@ -238,7 +255,7 @@ Expression Library can be found at:
| sqrt | Square root of x, where x > 0 |
+-----------+--------------------------------------------------------+
| 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 |
+-----------+--------------------------------------------------------+
@ -405,7 +422,9 @@ correctly optimize such expressions for a given architecture.
be enclosed with single-quotes.
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.