diff --git a/Makefile b/Makefile index 4801654..31ff47b 100644 --- a/Makefile +++ b/Makefile @@ -34,18 +34,17 @@ exprtk_benchmark: exprtk_benchmark.cpp exprtk.hpp $(COMPILER) $(OPTIONS) exprtk_benchmark exprtk_benchmark.cpp $(LINKER_OPT) pgo: exprtk_test.cpp exprtk_benchmark.cpp exprtk.hpp - $(COMPILER) $(BASE_OPTIONS) -O3 -march=native -fprofile-generate -o exprtk_test exprtk_test.cpp $(LINKER_OPT) $(COMPILER) $(BASE_OPTIONS) -O3 -march=native -fprofile-generate -o exprtk_benchmark exprtk_benchmark.cpp $(LINKER_OPT) - ./exprtk_test ./exprtk_benchmark - $(COMPILER) $(BASE_OPTIONS) -O3 -march=native -fprofile-use -o exprtk_test exprtk_test.cpp $(LINKER_OPT) $(COMPILER) $(BASE_OPTIONS) -O3 -march=native -fprofile-use -o exprtk_benchmark exprtk_benchmark.cpp $(LINKER_OPT) strip_bin: strip -s exprtk_test + strip -s exprtk_benchmark valgrind_check: valgrind --leak-check=full --show-reachable=yes --track-origins=yes ./exprtk_test + valgrind --leak-check=full --show-reachable=yes --track-origins=yes ./exprtk_benchmark clean: rm -f core.* *~ *.o *.bak *stackdump gmon.out *.gcda *.gcno *.gcnor *.gch diff --git a/exprtk.hpp b/exprtk.hpp index 6ded51a..3dc5b3e 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -6873,6 +6873,101 @@ namespace exprtk return std::numeric_limits::quiet_NaN(); } + /* + Note: The following 'compute' routines are very simple helpers, + for quickly setting up the required pieces of code in order to + evaluate an expression. By virtue of how they the operate there + will be an overhead with regards to their setup and teardown and + hence should not be used in time critical sections of code. + Furthermore they only assume a small sub set of variables - no + string variables or user defined functions. + */ + template + inline bool compute(const std::string& expression_string, T& result) + { + //No variables + symbol_table symbol_table; + symbol_table.add_constants(); + expression expression; + parser parser; + if (parser.compile(expression_string,expression)) + { + result = expression.value(); + return true; + } + else + return false; + } + + template + inline bool compute(const std::string& expression_string, + const T& x, + T& result) + { + //Only 'x' + static const std::string x_var("x"); + symbol_table symbol_table; + symbol_table.add_constants(); + symbol_table.add_variable("x",x); + expression expression; + parser parser; + if (parser.compile(expression_string,expression)) + { + result = expression.value(); + return true; + } + else + return false; + } + + template + inline bool compute(const std::string& expression_string, + const T&x, const T& y, + T& result) + { + //Only 'x' and 'y' + static const std::string x_var("x"); + static const std::string y_var("y"); + symbol_table symbol_table; + symbol_table.add_constants(); + symbol_table.add_variable("x",x); + symbol_table.add_variable("y",y); + expression expression; + parser parser; + if (parser.compile(expression_string,expression)) + { + result = expression.value(); + return true; + } + else + return false; + } + + template + inline bool compute(const std::string& expression_string, + const T& x, const T& y, const T& z, + T& result) + { + //Only 'x', 'y' or 'z' + static const std::string x_var("x"); + static const std::string y_var("y"); + static const std::string z_var("z"); + symbol_table symbol_table; + symbol_table.add_constants(); + symbol_table.add_variable(x_var,x); + symbol_table.add_variable(y_var,y); + symbol_table.add_variable(z_var,z); + expression expression; + parser parser; + if (parser.compile(expression_string,expression)) + { + result = expression.value(); + return true; + } + else + return false; + } + template inline bool pgo_primer() { @@ -7035,6 +7130,26 @@ namespace exprtk else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(38.0)))) return false; else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(39.0)))) return false; else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(40.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(41.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(42.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(43.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(44.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(45.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(46.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(47.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(48.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(49.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(50.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(51.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(52.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(53.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(54.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(55.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(56.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(57.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(58.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(59.0)))) return false; + else if (details::numeric::nequal(details::numeric::fast_exp::result(v),std::pow(v,T(60.0)))) return false; else return true; } diff --git a/exprtk_benchmark.cpp b/exprtk_benchmark.cpp index f447991..6447786 100644 --- a/exprtk_benchmark.cpp +++ b/exprtk_benchmark.cpp @@ -30,7 +30,7 @@ const std::string expression_list[] = { "(y + x / y) * (x - y / x)", "x / ((x + y) * (x - y)) / y", "1 - ((x * y) + (y / x)) - 3", - "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^4 - 5.5x^5 + 6.6y^6", + "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^15 - 5.5x^23 + 6.6y^55", "sin(2 * x) + cos(pi / y)", "1 - sin(2 * x) + cos(pi / y)", "sqrt(1 - sin(2 * x) + cos(pi / y) / 3)", @@ -114,7 +114,7 @@ template inline T func02(const T& x, const T& y) { return (T(2.0) * template inline T func03(const T& x, const T& y) { return (y + x / y) * (x - y / x); } template inline T func04(const T& x, const T& y) { return x / ((x + y) * (x - y)) / y; } template inline T func05(const T& x, const T& y) { return T(1.0) - ((x * y) + (y / x)) - T(3.0); } -template inline T func06(const T& x, const T& y) { return (1.1*pow(x,T(1.0))+2.2*pow(y,T(2.0))-3.3*pow(x,T(3.0))+4.4*pow(y,T(4.0))-5.5*pow(x,T(5.0))+6.6*pow(y,T(6.0))); } +template inline T func06(const T& x, const T& y) { return (1.1*pow(x,T(1.0))+2.2*pow(y,T(2.0))-3.3*pow(x,T(3.0))+4.4*pow(y,T(15.0))-5.5*pow(x,T(23.0))+6.6*pow(y,T(55.0))); } template inline T func07(const T& x, const T& y) { return std::sin(T(2.0) * x) + std::cos(pi / y); } template inline T func08(const T& x, const T& y) { return T(1.0) - std::sin(2.0 * x) + std::cos(pi / y); } template inline T func09(const T& x, const T& y) { return std::sqrt(T(1.0) - std::sin(T(2.0) * x) + std::cos(pi / y) / T(3.0)); }