From 1b4e3d7cc29ebe8085efaa3de0fb2bdca6b1dd4d Mon Sep 17 00:00:00 2001 From: Arash Partow Date: Sun, 20 May 2012 08:30:38 +1000 Subject: [PATCH] C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html --- exprtk.hpp | 525 ++++++++++++++++++++++++++++++++++++++++-------- exprtk_test.cpp | 282 ++++++++++++++++++-------- readme.txt | 89 ++++---- 3 files changed, 697 insertions(+), 199 deletions(-) diff --git a/exprtk.hpp b/exprtk.hpp index 5311ec7..a907870 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -1659,8 +1659,32 @@ namespace exprtk e_sf55 = 1055, e_sf56 = 1056, e_sf57 = 1057, - e_sf58 = 1058 - + e_sf58 = 1058, + e_sf59 = 1059, + e_sf60 = 1060, + e_sf61 = 1061, + e_sf62 = 1062, + e_sf63 = 1063, + e_sf64 = 1064, + e_sf65 = 1065, + e_sf66 = 1066, + e_sf67 = 1067, + e_sf68 = 1068, + e_sf69 = 1069, + e_sf70 = 1070, + e_sf71 = 1071, + e_sf72 = 1072, + e_sf73 = 1073, + e_sf74 = 1074, + e_sf75 = 1075, + e_sf76 = 1076, + e_sf77 = 1077, + e_sf78 = 1078, + e_sf79 = 1079, + e_sf80 = 1080, + e_sf81 = 1081, + e_sf82 = 1082, + e_sf83 = 1083 }; namespace numeric @@ -2077,7 +2101,7 @@ namespace exprtk bool branch_deletable_; }; - template + template struct construct_branch_pair { template @@ -2085,7 +2109,7 @@ namespace exprtk {} }; - template + template struct construct_branch_pair { template @@ -2609,12 +2633,12 @@ namespace exprtk template struct sf09_op { static inline T process(const T& x, const T& y, const T& z) { return (x / y) - z; } }; template struct sf10_op { static inline T process(const T& x, const T& y, const T& z) { return (x / y) / z; } }; template struct sf11_op { static inline T process(const T& x, const T& y, const T& z) { return (x / y) * z; } }; - template struct sf12_op { static inline T process(const T& x, const T& y, const T& z) { return z / (x + y); } }; - template struct sf13_op { static inline T process(const T& x, const T& y, const T& z) { return z / (x - y); } }; - template struct sf14_op { static inline T process(const T& x, const T& y, const T& z) { return z / (x * y); } }; - template struct sf15_op { static inline T process(const T& x, const T& y, const T& z) { return z / (x / y); } }; - template struct sf16_op { static inline T process(const T& x, const T& y, const T& z) { return z - (x / y); } }; - template struct sf17_op { static inline T process(const T& x, const T& y, const T& z) { return z - (x / y); } }; + template struct sf12_op { static inline T process(const T& x, const T& y, const T& z) { return x / (y + z); } }; + template struct sf13_op { static inline T process(const T& x, const T& y, const T& z) { return x / (y - z); } }; + template struct sf14_op { static inline T process(const T& x, const T& y, const T& z) { return x / (y * z); } }; + template struct sf15_op { static inline T process(const T& x, const T& y, const T& z) { return x / (y / z); } }; + template struct sf16_op { static inline T process(const T& x, const T& y, const T& z) { return x - (y / z); } }; + template struct sf17_op { static inline T process(const T& x, const T& y, const T& z) { return x - (y / z); } }; template struct sf18_op { static inline T process(const T& x, const T& y, const T& z) { return axnb(x,y,z); } }; //x * y^2 + z template struct sf19_op { static inline T process(const T& x, const T& y, const T& z) { return axnb(x,y,z); } }; //x * y^3 + z template struct sf20_op { static inline T process(const T& x, const T& y, const T& z) { return axnb(x,y,z); } }; //x * y^4 + z @@ -2623,39 +2647,64 @@ namespace exprtk template struct sf23_op { static inline T process(const T& x, const T& y, const T& z) { return axnb(x,y,z); } }; //x * y^7 + z template struct sf24_op { static inline T process(const T& x, const T& y, const T& z) { return axnb(x,y,z); } }; //x * y^8 + z template struct sf25_op { static inline T process(const T& x, const T& y, const T& z) { return axnb(x,y,z); } }; //x * y^9 + z - template struct sf26_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x + y) / z); } }; - template struct sf27_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x + y) * z); } }; - template struct sf28_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x - y) / z); } }; - template struct sf29_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x - y) * z); } }; - template struct sf30_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x * y) / z); } }; - template struct sf31_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x * y) * z); } }; - template struct sf32_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x / y) + z); } }; - template struct sf33_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x / y) / z); } }; - template struct sf34_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w + ((x / y) * z); } }; - template struct sf35_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x + y) / z); } }; - template struct sf36_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x + y) * z); } }; - template struct sf37_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x - y) / z); } }; - template struct sf38_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x - y) * z); } }; - template struct sf39_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x * y) / z); } }; - template struct sf40_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x * y) * z); } }; - template struct sf41_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x / y) / z); } }; - template struct sf42_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return w - ((x / y) * z); } }; - template struct sf43_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x + y) * z) - w; } }; - template struct sf44_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x - y) * z) - w; } }; - template struct sf45_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x * y) * z) - w; } }; - template struct sf46_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x / y) * z) - w; } }; - template struct sf47_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x + y) / z) - w; } }; - template struct sf48_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x - y) / z) - w; } }; - template struct sf49_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x * y) / z) - w; } }; - template struct sf50_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x / y) / z) - w; } }; - template struct sf51_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^2+z*w^2 - template struct sf52_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^3+z*w^3 - template struct sf53_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^4+z*w^4 - template struct sf54_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^5+z*w^5 - template struct sf55_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^6+z*w^6 - template struct sf56_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^7+z*w^7 - template struct sf57_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^8+z*w^8 - template struct sf58_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^9+z*w^9 + template struct sf26_op { static inline T process(const T& x, const T& y, const T& z) { return x * numeric::log(y) + z; } }; + template struct sf27_op { static inline T process(const T& x, const T& y, const T& z) { return x * numeric::log(y) - z; } }; + template struct sf28_op { static inline T process(const T& x, const T& y, const T& z) { return x * numeric::log10(y) + z; } }; + template struct sf29_op { static inline T process(const T& x, const T& y, const T& z) { return x * numeric::log10(y) - z; } }; + template struct sf30_op { static inline T process(const T& x, const T& y, const T& z) { return x * numeric::sin(y) + z; } }; + template struct sf31_op { static inline T process(const T& x, const T& y, const T& z) { return x * numeric::sin(y) - z; } }; + template struct sf32_op { static inline T process(const T& x, const T& y, const T& z) { return x * numeric::cos(y) + z; } }; + template struct sf33_op { static inline T process(const T& x, const T& y, const T& z) { return x * numeric::cos(y) - z; } }; + template struct sf34_op { static inline T process(const T& x, const T& y, const T& z) { return (T(0) != x) ? y : z; } }; + template struct sf35_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x + ((y + z) / w); } }; + template struct sf36_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x + ((y + z) * w); } }; + template struct sf37_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x + ((y - z) / w); } }; + template struct sf38_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x + ((y - z) * w); } }; + template struct sf39_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x + ((y * z) / w); } }; + template struct sf40_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x + ((y * z) * w); } }; + template struct sf41_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x + ((y / z) + w); } }; + template struct sf42_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x + ((y / z) / w); } }; + template struct sf43_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x + ((y / z) * w); } }; + template struct sf44_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x - ((y + z) / w); } }; + template struct sf45_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x - ((y + z) * w); } }; + template struct sf46_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x - ((y - z) / w); } }; + template struct sf47_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x - ((y - z) * w); } }; + template struct sf48_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x - ((y * z) / w); } }; + template struct sf49_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x - ((y * z) * w); } }; + template struct sf50_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x - ((y / z) / w); } }; + template struct sf51_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x - ((y / z) * w); } }; + template struct sf52_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x + y) * z) - w; } }; + template struct sf53_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x - y) * z) - w; } }; + template struct sf54_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x * y) * z) - w; } }; + template struct sf55_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x / y) * z) - w; } }; + template struct sf56_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x + y) / z) - w; } }; + template struct sf57_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x - y) / z) - w; } }; + template struct sf58_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x * y) / z) - w; } }; + template struct sf59_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((x / y) / z) - w; } }; + template struct sf60_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x * y) + (z * w); } }; + template struct sf61_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x * y) - (z * w); } }; + template struct sf62_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x * y) + (z / w); } }; + template struct sf63_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x * y) - (z / w); } }; + template struct sf64_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x / y) + (z / w); } }; + template struct sf65_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x / y) - (z / w); } }; + template struct sf66_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x / y) - (z / w); } }; + template struct sf67_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x / y) - (z * w); } }; + template struct sf68_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^2+z*w^2 + template struct sf69_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^3+z*w^3 + template struct sf70_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^4+z*w^4 + template struct sf71_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^5+z*w^5 + template struct sf72_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^6+z*w^6 + template struct sf73_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^7+z*w^7 + template struct sf74_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^8+z*w^8 + template struct sf75_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return axn(x,y) + axn(z,w); } }; //x*y^9+z*w^9 + template struct sf76_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((T(0) != x) && (T(0) != y)) ? z : w; } }; + template struct sf77_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return ((T(0) != x) || (T(0) != y)) ? z : w; } }; + template struct sf78_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x < y) ? z : w; } }; + template struct sf79_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x <= y) ? z : w; } }; + template struct sf80_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x > y) ? z : w; } }; + template struct sf81_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return (x >= y) ? z : w; } }; + template struct sf82_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return numeric::equal(x,y) ? z : w; } }; + template struct sf83_op { static inline T process(const T& x, const T& y, const T& z, const T& w) { return x * numeric::sin(y) + z * numeric::cos(w); } }; template class sf3_node : public trinary_node @@ -2874,16 +2923,144 @@ namespace exprtk template struct invoke { static inline T execute(ifunction*, branch_t (&)[ParamCount]) { return std::numeric_limits::quiet_NaN(); } }; - template struct invoke { static inline T_ execute(ifunction& f, T_ (&v)[10]) { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9]); } }; - template struct invoke { static inline T_ execute(ifunction& f, T_ (&v)[ 9]) { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]); } }; - template struct invoke { static inline T_ execute(ifunction& f, T_ (&v)[ 8]) { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]); } }; - template struct invoke { static inline T_ execute(ifunction& f, T_ (&v)[ 7]) { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6]); } }; - template struct invoke { static inline T_ execute(ifunction& f, T_ (&v)[ 6]) { return f(v[0],v[1],v[2],v[3],v[4],v[5]); } }; - template struct invoke { static inline T_ execute(ifunction& f, T_ (&v)[ 5]) { return f(v[0],v[1],v[2],v[3],v[4]); } }; - template struct invoke { static inline T_ execute(ifunction& f, T_ (&v)[ 4]) { return f(v[0],v[1],v[2],v[3]); } }; - template struct invoke { static inline T_ execute(ifunction& f, T_ (&v)[ 3]) { return f(v[0],v[1],v[2]); } }; - template struct invoke { static inline T_ execute(ifunction& f, T_ (&v)[ 2]) { return f(v[0],v[1]); } }; - template struct invoke { static inline T_ execute(ifunction& f, T_ (&v)[ 1]) { return f(v[0]); } }; + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[20]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16],v[17],v[18],v[19]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[19]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16],v[17],v[18]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[18]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16],v[17]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[17]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[16]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[15]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[14]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[13]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[12]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[11]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[10]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[9]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[8]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[ 7]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6]); } }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[6]) + { return f(v[0],v[1],v[2],v[3],v[4],v[5]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[5]) + { return f(v[0],v[1],v[2],v[3],v[4]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[4]) + { return f(v[0],v[1],v[2],v[3]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[3]) + { return f(v[0],v[1],v[2]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[2]) + { return f(v[0],v[1]); } + }; + + template + struct invoke + { + static inline T_ execute(ifunction& f, T_ (&v)[1]) + { return f(v[0]); } + }; inline typename expression_node::node_type type() const { @@ -4228,6 +4405,67 @@ namespace exprtk { return std::numeric_limits::quiet_NaN(); } + + inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, + const T&) + { + return std::numeric_limits::quiet_NaN(); + } + + inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, + const T&, const T&) + { + return std::numeric_limits::quiet_NaN(); + } + + inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, + const T&, const T&, const T&) + { + return std::numeric_limits::quiet_NaN(); + } + + inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, + const T&, const T&, const T&, const T&) + { + return std::numeric_limits::quiet_NaN(); + } + + inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, + const T&, const T&, const T&, const T&, const T&) + { + return std::numeric_limits::quiet_NaN(); + } + + inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, + const T&, const T&, const T&, const T&, const T&, const T&) + { + return std::numeric_limits::quiet_NaN(); + } + + inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, + const T&, const T&, const T&, const T&, const T&, const T&, const T&) + { + return std::numeric_limits::quiet_NaN(); + } + + inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, + const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) + { + return std::numeric_limits::quiet_NaN(); + } + + inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, + const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) + { + return std::numeric_limits::quiet_NaN(); + } + + inline virtual T operator()(const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, + const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) + { + return std::numeric_limits::quiet_NaN(); + } + }; template @@ -4793,6 +5031,19 @@ namespace exprtk return local_data().variable_store.add(variable_name,t,is_constant); } + inline bool add_constant(const std::string& constant_name, const T& value) + { + if (!valid()) + return false; + else if (!valid_symbol(constant_name)) + return false; + else if (symbol_exists(constant_name)) + return false; + local_data().local_symbol_list_.push_back(value); + T& t = local_data().local_symbol_list_.back(); + return add_variable(constant_name,t,true); + } + #ifndef exprtk_disable_string_capabilities inline bool add_stringvar(const std::string& stringvar_name, std::string& s, const bool is_constant = false) { @@ -4854,20 +5105,20 @@ namespace exprtk inline bool add_pi() { - static T pi = T(details::numeric::constant::pi); - return add_variable("pi",pi,true); + static const T local_pi = T(details::numeric::constant::pi); + return add_constant("pi",local_pi); } inline bool add_epsilon() { - static T epsilon = std::numeric_limits::epsilon(); - return add_variable("epsilon",epsilon,true); + static const T local_epsilon = std::numeric_limits::epsilon(); + return add_constant("epsilon",local_epsilon); } inline bool add_infinity() { - static T infinity = std::numeric_limits::infinity(); - return add_variable("inf",infinity,true); + static const T local_infinity = std::numeric_limits::infinity(); + return add_constant("inf",local_infinity); } template (NumberofParameters); ++i) { branch[i] = parse_expression(); - if (i < static_cast(NumberofParameters - 1)) + if (0 == branch[i]) + { + return error_node(); + } + else if (i < static_cast(NumberofParameters - 1)) { if (!token_is(token_t::comma)) { @@ -5540,7 +5795,11 @@ namespace exprtk for (int i = 0; i < static_cast(NumberofParameters); ++i) { branch[i] = parse_expression(); - if (i < static_cast(NumberofParameters - 1)) + if (0 == branch[i]) + { + return error_node(); + } + else if (i < static_cast(NumberofParameters - 1)) { if (!token_is(token_t::comma)) { @@ -5566,15 +5825,27 @@ namespace exprtk expression_node_ptr alternative = 0; next_token(); if (token_is(token_t::lbracket)) + { condition = parse_expression(); + if (0 == condition) + return error_node(); + } else return error_node(); if (token_is(token_t::comma)) + { consequent = parse_expression(); + if (0 == consequent) + return error_node(); + } else return error_node(); if (token_is(token_t::comma)) + { alternative = parse_expression(); + if (0 == alternative) + return error_node(); + } else return error_node(); if (token_is(token_t::rbracket)) @@ -5608,11 +5879,12 @@ namespace exprtk inline expression_node_ptr parse_special_function(const unsigned int id) { //Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3) + const std::size_t sf_3_to_4 = details::e_sf35; const details::operator_type opt_type = details::operator_type(id + 1000); - const std::size_t NumberOfParameters = (id < (details::e_sf26 - 1000)) ? 3 : 4; + const std::size_t NumberOfParameters = (id < (sf_3_to_4 - 1000)) ? 3 : 4; expression_node_ptr branch3[3]; expression_node_ptr branch4[4]; - expression_node_ptr* branch = (id < (details::e_sf26 - 1000)) ? &branch3[0] : &branch4[0]; + expression_node_ptr* branch = (id < (sf_3_to_4 - 1000)) ? &branch3[0] : &branch4[0]; expression_node_ptr result = 0; std::fill_n(branch3,3,reinterpret_cast(0)); std::fill_n(branch4,4,reinterpret_cast(0)); @@ -5626,7 +5898,11 @@ namespace exprtk for (std::size_t i = 0; i < NumberOfParameters; ++i) { branch[i] = parse_expression(); - if (i < (NumberOfParameters - 1)) + if (0 == branch[i]) + { + return error_node(); + } + else if (i < (NumberOfParameters - 1)) { if (!token_is(token_t::comma)) { @@ -5768,6 +6044,16 @@ namespace exprtk case 8 : func_node = parse_function_call< 8>(function); break; case 9 : func_node = parse_function_call< 9>(function); break; case 10 : func_node = parse_function_call<10>(function); break; + case 11 : func_node = parse_function_call<11>(function); break; + case 12 : func_node = parse_function_call<12>(function); break; + case 13 : func_node = parse_function_call<13>(function); break; + case 14 : func_node = parse_function_call<14>(function); break; + case 15 : func_node = parse_function_call<15>(function); break; + case 16 : func_node = parse_function_call<16>(function); break; + case 17 : func_node = parse_function_call<17>(function); break; + case 18 : func_node = parse_function_call<18>(function); break; + case 19 : func_node = parse_function_call<19>(function); break; + case 20 : func_node = parse_function_call<20>(function); break; default : { set_error("parser::parse_branch() - invalid number of parameters for function: " + symbol); return expression_node_ptr(0); @@ -6353,6 +6639,15 @@ namespace exprtk case_stmt(details::e_sf23,details::sf23_op) case_stmt(details::e_sf24,details::sf24_op) case_stmt(details::e_sf25,details::sf25_op) + case_stmt(details::e_sf26,details::sf26_op) + case_stmt(details::e_sf27,details::sf27_op) + case_stmt(details::e_sf28,details::sf28_op) + case_stmt(details::e_sf29,details::sf29_op) + case_stmt(details::e_sf30,details::sf30_op) + case_stmt(details::e_sf31,details::sf31_op) + case_stmt(details::e_sf32,details::sf32_op) + case_stmt(details::e_sf33,details::sf33_op) + case_stmt(details::e_sf34,details::sf34_op) #undef case_stmt default : return error_node(); } @@ -6396,6 +6691,15 @@ namespace exprtk case_stmt(details::e_sf23,details::sf23_op) case_stmt(details::e_sf24,details::sf24_op) case_stmt(details::e_sf25,details::sf25_op) + case_stmt(details::e_sf26,details::sf26_op) + case_stmt(details::e_sf27,details::sf27_op) + case_stmt(details::e_sf28,details::sf28_op) + case_stmt(details::e_sf29,details::sf29_op) + case_stmt(details::e_sf30,details::sf30_op) + case_stmt(details::e_sf31,details::sf31_op) + case_stmt(details::e_sf32,details::sf32_op) + case_stmt(details::e_sf33,details::sf33_op) + case_stmt(details::e_sf34,details::sf34_op) #undef case_stmt default : return error_node(); } @@ -6407,15 +6711,6 @@ namespace exprtk switch (operation) { #define case_stmt(op0,op1) case op0 : temp_node = node_allocator_->allocate > >(operation,branch); break; - case_stmt(details::e_sf26,details::sf26_op) - case_stmt(details::e_sf27,details::sf27_op) - case_stmt(details::e_sf28,details::sf28_op) - case_stmt(details::e_sf29,details::sf29_op) - case_stmt(details::e_sf30,details::sf30_op) - case_stmt(details::e_sf31,details::sf31_op) - case_stmt(details::e_sf32,details::sf32_op) - case_stmt(details::e_sf33,details::sf33_op) - case_stmt(details::e_sf34,details::sf34_op) case_stmt(details::e_sf35,details::sf35_op) case_stmt(details::e_sf36,details::sf36_op) case_stmt(details::e_sf37,details::sf37_op) @@ -6440,6 +6735,31 @@ namespace exprtk case_stmt(details::e_sf56,details::sf56_op) case_stmt(details::e_sf57,details::sf57_op) case_stmt(details::e_sf58,details::sf58_op) + case_stmt(details::e_sf59,details::sf59_op) + case_stmt(details::e_sf60,details::sf60_op) + case_stmt(details::e_sf61,details::sf61_op) + case_stmt(details::e_sf62,details::sf62_op) + case_stmt(details::e_sf63,details::sf63_op) + case_stmt(details::e_sf64,details::sf64_op) + case_stmt(details::e_sf65,details::sf65_op) + case_stmt(details::e_sf66,details::sf66_op) + case_stmt(details::e_sf67,details::sf67_op) + case_stmt(details::e_sf68,details::sf68_op) + case_stmt(details::e_sf69,details::sf69_op) + case_stmt(details::e_sf70,details::sf70_op) + case_stmt(details::e_sf71,details::sf71_op) + case_stmt(details::e_sf72,details::sf72_op) + case_stmt(details::e_sf73,details::sf73_op) + case_stmt(details::e_sf74,details::sf74_op) + case_stmt(details::e_sf75,details::sf75_op) + case_stmt(details::e_sf76,details::sf76_op) + case_stmt(details::e_sf77,details::sf77_op) + case_stmt(details::e_sf78,details::sf78_op) + case_stmt(details::e_sf79,details::sf79_op) + case_stmt(details::e_sf80,details::sf80_op) + case_stmt(details::e_sf81,details::sf81_op) + case_stmt(details::e_sf82,details::sf82_op) + case_stmt(details::e_sf83,details::sf83_op) #undef case_stmt default : return error_node(); } @@ -6457,15 +6777,6 @@ namespace exprtk switch (operation) { #define case_stmt(op0,op1) case op0 : return node_allocator_->allocate > >(operation,branch); - case_stmt(details::e_sf26,details::sf26_op) - case_stmt(details::e_sf27,details::sf27_op) - case_stmt(details::e_sf28,details::sf28_op) - case_stmt(details::e_sf29,details::sf29_op) - case_stmt(details::e_sf30,details::sf30_op) - case_stmt(details::e_sf31,details::sf31_op) - case_stmt(details::e_sf32,details::sf32_op) - case_stmt(details::e_sf33,details::sf33_op) - case_stmt(details::e_sf34,details::sf34_op) case_stmt(details::e_sf35,details::sf35_op) case_stmt(details::e_sf36,details::sf36_op) case_stmt(details::e_sf37,details::sf37_op) @@ -6490,6 +6801,31 @@ namespace exprtk case_stmt(details::e_sf56,details::sf56_op) case_stmt(details::e_sf57,details::sf57_op) case_stmt(details::e_sf58,details::sf58_op) + case_stmt(details::e_sf59,details::sf59_op) + case_stmt(details::e_sf60,details::sf60_op) + case_stmt(details::e_sf61,details::sf61_op) + case_stmt(details::e_sf62,details::sf62_op) + case_stmt(details::e_sf63,details::sf63_op) + case_stmt(details::e_sf64,details::sf64_op) + case_stmt(details::e_sf65,details::sf65_op) + case_stmt(details::e_sf66,details::sf66_op) + case_stmt(details::e_sf67,details::sf67_op) + case_stmt(details::e_sf68,details::sf68_op) + case_stmt(details::e_sf69,details::sf69_op) + case_stmt(details::e_sf70,details::sf70_op) + case_stmt(details::e_sf71,details::sf71_op) + case_stmt(details::e_sf72,details::sf72_op) + case_stmt(details::e_sf73,details::sf73_op) + case_stmt(details::e_sf74,details::sf74_op) + case_stmt(details::e_sf75,details::sf75_op) + case_stmt(details::e_sf76,details::sf76_op) + case_stmt(details::e_sf77,details::sf77_op) + case_stmt(details::e_sf78,details::sf78_op) + case_stmt(details::e_sf79,details::sf79_op) + case_stmt(details::e_sf80,details::sf80_op) + case_stmt(details::e_sf81,details::sf81_op) + case_stmt(details::e_sf82,details::sf82_op) + case_stmt(details::e_sf83,details::sf83_op) #undef case_stmt default : return error_node(); } @@ -7723,6 +8059,19 @@ namespace exprtk template struct poly_impl { }; + template + struct poly_impl + { + static inline T evaluate(const Type x, + const Type c10, const Type c9, const Type c8, const Type c7, const Type c6, + const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, + const Type c0) + { + //p(x) = c_10x^10 + c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0 + return ((((((((((c10 * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); + } + }; + template struct poly_impl { @@ -7825,7 +8174,7 @@ namespace exprtk public: - polynomial() : exprtk::ifunction(N) {} + polynomial() : exprtk::ifunction((N+2 <= 20) ? (N + 2) : std::numeric_limits::max()) {} inline virtual T operator()(const T& x, const T& c1, const T& c0) { @@ -7867,6 +8216,16 @@ namespace exprtk return ((8 == N) ? poly_impl::evaluate(x,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits::quiet_NaN()); } + inline virtual T operator()(const T& x, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0) + { + return ((9 == N) ? poly_impl::evaluate(x,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits::quiet_NaN()); + } + + inline virtual T operator()(const T& x, const T& c10, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0) + { + return ((10 == N) ? poly_impl::evaluate(x,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0) : std::numeric_limits::quiet_NaN()); + } + inline virtual T operator()() { return std::numeric_limits::quiet_NaN(); diff --git a/exprtk_test.cpp b/exprtk_test.cpp index 5d8494d..13fbaa5 100644 --- a/exprtk_test.cpp +++ b/exprtk_test.cpp @@ -649,12 +649,12 @@ static const test_t test_list[] = test_t("equal($f09(1.1,2.2,3.3),((1.1/2.2)-3.3))",1.0), test_t("equal($f10(1.1,2.2,3.3),((1.1/2.2)/3.3))",1.0), test_t("equal($f11(1.1,2.2,3.3),((1.1/2.2)*3.3))",1.0), - test_t("equal($f12(1.1,2.2,3.3),(3.3/(1.1+2.2)))",1.0), - test_t("equal($f13(1.1,2.2,3.3),(3.3/(1.1-2.2)))",1.0), - test_t("equal($f14(1.1,2.2,3.3),(3.3/(1.1*2.2)))",1.0), - test_t("equal($f15(1.1,2.2,3.3),(3.3/(1.1/2.2)))",1.0), - test_t("equal($f16(1.1,2.2,3.3),(3.3-(1.1/2.2)))",1.0), - test_t("equal($f17(1.1,2.2,3.3),(3.3-(1.1/2.2)))",1.0), + test_t("equal($f12(1.1,2.2,3.3),(1.1/(2.2+3.3)))",1.0), + test_t("equal($f13(1.1,2.2,3.3),(1.1/(2.2-3.3)))",1.0), + test_t("equal($f14(1.1,2.2,3.3),(1.1/(2.2*3.3)))",1.0), + test_t("equal($f15(1.1,2.2,3.3),(1.1/(2.2/3.3)))",1.0), + test_t("equal($f16(1.1,2.2,3.3),(1.1-(2.2/3.3)))",1.0), + test_t("equal($f17(1.1,2.2,3.3),(1.1-(2.2/3.3)))",1.0), test_t("equal($f18(1.1,2.2,3.3),(1.1*2.2^2+3.3))",1.0), test_t("equal($f19(1.1,2.2,3.3),(1.1*2.2^3+3.3))",1.0), test_t("equal($f20(1.1,2.2,3.3),(1.1*2.2^4+3.3))",1.0), @@ -663,39 +663,64 @@ static const test_t test_list[] = test_t("equal($f23(1.1,2.2,3.3),(1.1*2.2^7+3.3))",1.0), test_t("equal($f24(1.1,2.2,3.3),(1.1*2.2^8+3.3))",1.0), test_t("equal($f25(1.1,2.2,3.3),(1.1*2.2^9+3.3))",1.0), - test_t("equal($f26(1.1,2.2,3.3,4.4),(4.4+((1.1+2.2)/3.3)))",1.0), - test_t("equal($f27(1.1,2.2,3.3,4.4),(4.4+((1.1+2.2)*3.3)))",1.0), - test_t("equal($f28(1.1,2.2,3.3,4.4),(4.4+((1.1-2.2)/3.3)))",1.0), - test_t("equal($f29(1.1,2.2,3.3,4.4),(4.4+((1.1-2.2)*3.3)))",1.0), - test_t("equal($f30(1.1,2.2,3.3,4.4),(4.4+((1.1*2.2)/3.3)))",1.0), - test_t("equal($f31(1.1,2.2,3.3,4.4),(4.4+((1.1*2.2)*3.3)))",1.0), - test_t("equal($f32(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)+3.3)))",1.0), - test_t("equal($f33(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)/3.3)))",1.0), - test_t("equal($f34(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)*3.3)))",1.0), - test_t("equal($f35(1.1,2.2,3.3,4.4),(4.4-((1.1+2.2)/3.3)))",1.0), - test_t("equal($f36(1.1,2.2,3.3,4.4),(4.4-((1.1+2.2)*3.3)))",1.0), - test_t("equal($f37(1.1,2.2,3.3,4.4),(4.4-((1.1-2.2)/3.3)))",1.0), - test_t("equal($f38(1.1,2.2,3.3,4.4),(4.4-((1.1-2.2)*3.3)))",1.0), - test_t("equal($f39(1.1,2.2,3.3,4.4),(4.4-((1.1*2.2)/3.3)))",1.0), - test_t("equal($f40(1.1,2.2,3.3,4.4),(4.4-((1.1*2.2)*3.3)))",1.0), - test_t("equal($f41(1.1,2.2,3.3,4.4),(4.4-((1.1/2.2)/3.3)))",1.0), - test_t("equal($f42(1.1,2.2,3.3,4.4),(4.4-((1.1/2.2)*3.3)))",1.0), - test_t("equal($f43(1.1,2.2,3.3,4.4),(((1.1+2.2)*3.3)-4.4))",1.0), - test_t("equal($f44(1.1,2.2,3.3,4.4),(((1.1-2.2)*3.3)-4.4))",1.0), - test_t("equal($f45(1.1,2.2,3.3,4.4),(((1.1*2.2)*3.3)-4.4))",1.0), - test_t("equal($f46(1.1,2.2,3.3,4.4),(((1.1/2.2)*3.3)-4.4))",1.0), - test_t("equal($f47(1.1,2.2,3.3,4.4),(((1.1+2.2)/3.3)-4.4))",1.0), - test_t("equal($f48(1.1,2.2,3.3,4.4),(((1.1-2.2)/3.3)-4.4))",1.0), - test_t("equal($f49(1.1,2.2,3.3,4.4),(((1.1*2.2)/3.3)-4.4))",1.0), - test_t("equal($f50(1.1,2.2,3.3,4.4),(((1.1/2.2)/3.3)-4.4))",1.0), - test_t("equal($f51(1.1,2.2,3.3,4.4),(1.1*2.2^2+3.3*4.4^2))",1.0), - test_t("equal($f52(1.1,2.2,3.3,4.4),(1.1*2.2^3+3.3*4.4^3))",1.0), - test_t("equal($f53(1.1,2.2,3.3,4.4),(1.1*2.2^4+3.3*4.4^4))",1.0), - test_t("equal($f54(1.1,2.2,3.3,4.4),(1.1*2.2^5+3.3*4.4^5))",1.0), - test_t("equal($f55(1.1,2.2,3.3,4.4),(1.1*2.2^6+3.3*4.4^6))",1.0), - test_t("equal($f56(1.1,2.2,3.3,4.4),(1.1*2.2^7+3.3*4.4^7))",1.0), - test_t("equal($f57(1.1,2.2,3.3,4.4),(1.1*2.2^8+3.3*4.4^8))",1.0), - test_t("equal($f58(1.1,2.2,3.3,4.4),(1.1*2.2^9+3.3*4.4^9))",1.0), + test_t("equal($f26(1.1,2.2,3.3),(1.1*log(2.2)+3.3))",1.0), + test_t("equal($f27(1.1,2.2,3.3),(1.1*log(2.2)-3.3))",1.0), + test_t("equal($f28(1.1,2.2,3.3),(1.1*log10(2.2)+3.3))",1.0), + test_t("equal($f29(1.1,2.2,3.3),(1.1*log10(2.2)-3.3))",1.0), + test_t("equal($f30(1.1,2.2,3.3),(1.1*sin(2.2)+3.3))",1.0), + test_t("equal($f31(1.1,2.2,3.3),(1.1*sin(2.2)-3.3))",1.0), + test_t("equal($f32(1.1,2.2,3.3),(1.1*cos(2.2)+3.3))",1.0), + test_t("equal($f33(1.1,2.2,3.3),(1.1*cos(2.2)-3.3))",1.0), + test_t("equal($f34(1.1,2.2,3.3),if((0 != 1.1),2.2,3.3))",1.0), + test_t("equal($f35(1.1,2.2,3.3,4.4),(1.1+((2.2+3.3)/4.4)))",1.0), + test_t("equal($f36(1.1,2.2,3.3,4.4),(1.1+((2.2+3.3)*4.4)))",1.0), + test_t("equal($f37(1.1,2.2,3.3,4.4),(1.1+((2.2-3.3)/4.4)))",1.0), + test_t("equal($f38(1.1,2.2,3.3,4.4),(1.1+((2.2-3.3)*4.4)))",1.0), + test_t("equal($f39(1.1,2.2,3.3,4.4),(1.1+((2.2*3.3)/4.4)))",1.0), + test_t("equal($f40(1.1,2.2,3.3,4.4),(1.1+((2.2*3.3)*4.4)))",1.0), + test_t("equal($f41(1.1,2.2,3.3,4.4),(1.1+((2.2/3.3)+4.4)))",1.0), + test_t("equal($f42(1.1,2.2,3.3,4.4),(1.1+((2.2/3.3)/4.4)))",1.0), + test_t("equal($f43(1.1,2.2,3.3,4.4),(1.1+((2.2/3.3)*4.4)))",1.0), + test_t("equal($f44(1.1,2.2,3.3,4.4),(1.1-((2.2+3.3)/4.4)))",1.0), + test_t("equal($f45(1.1,2.2,3.3,4.4),(1.1-((2.2+3.3)*4.4)))",1.0), + test_t("equal($f46(1.1,2.2,3.3,4.4),(1.1-((2.2-3.3)/4.4)))",1.0), + test_t("equal($f47(1.1,2.2,3.3,4.4),(1.1-((2.2-3.3)*4.4)))",1.0), + test_t("equal($f48(1.1,2.2,3.3,4.4),(1.1-((2.2*3.3)/4.4)))",1.0), + test_t("equal($f49(1.1,2.2,3.3,4.4),(1.1-((2.2*3.3)*4.4)))",1.0), + test_t("equal($f50(1.1,2.2,3.3,4.4),(1.1-((2.2/3.3)/4.4)))",1.0), + test_t("equal($f51(1.1,2.2,3.3,4.4),(1.1-((2.2/3.3)*4.4)))",1.0), + test_t("equal($f52(1.1,2.2,3.3,4.4),(((1.1+2.2)*3.3)-4.4))",1.0), + test_t("equal($f53(1.1,2.2,3.3,4.4),(((1.1-2.2)*3.3)-4.4))",1.0), + test_t("equal($f54(1.1,2.2,3.3,4.4),(((1.1*2.2)*3.3)-4.4))",1.0), + test_t("equal($f55(1.1,2.2,3.3,4.4),(((1.1/2.2)*3.3)-4.4))",1.0), + test_t("equal($f56(1.1,2.2,3.3,4.4),(((1.1+2.2)/3.3)-4.4))",1.0), + test_t("equal($f57(1.1,2.2,3.3,4.4),(((1.1-2.2)/3.3)-4.4))",1.0), + test_t("equal($f58(1.1,2.2,3.3,4.4),(((1.1*2.2)/3.3)-4.4))",1.0), + test_t("equal($f59(1.1,2.2,3.3,4.4),(((1.1/2.2)/3.3)-4.4))",1.0), + test_t("equal($f60(1.1,2.2,3.3,4.4),(1.1*2.2)+(3.3*4.4))",1.0), + test_t("equal($f61(1.1,2.2,3.3,4.4),(1.1*2.2)-(3.3*4.4))",1.0), + test_t("equal($f62(1.1,2.2,3.3,4.4),(1.1*2.2)+(3.3/4.4))",1.0), + test_t("equal($f63(1.1,2.2,3.3,4.4),(1.1*2.2)-(3.3/4.4))",1.0), + test_t("equal($f64(1.1,2.2,3.3,4.4),(1.1/2.2)+(3.3/4.4))",1.0), + test_t("equal($f65(1.1,2.2,3.3,4.4),(1.1/2.2)-(3.3/4.4))",1.0), + test_t("equal($f66(1.1,2.2,3.3,4.4),(1.1/2.2)-(3.3/4.4))",1.0), + test_t("equal($f67(1.1,2.2,3.3,4.4),(1.1/2.2)-(3.3*4.4))",1.0), + test_t("equal($f68(1.1,2.2,3.3,4.4),(1.1*2.2^2+3.3*4.4^2))",1.0), + test_t("equal($f69(1.1,2.2,3.3,4.4),(1.1*2.2^3+3.3*4.4^3))",1.0), + test_t("equal($f70(1.1,2.2,3.3,4.4),(1.1*2.2^4+3.3*4.4^4))",1.0), + test_t("equal($f71(1.1,2.2,3.3,4.4),(1.1*2.2^5+3.3*4.4^5))",1.0), + test_t("equal($f72(1.1,2.2,3.3,4.4),(1.1*2.2^6+3.3*4.4^6))",1.0), + test_t("equal($f73(1.1,2.2,3.3,4.4),(1.1*2.2^7+3.3*4.4^7))",1.0), + test_t("equal($f74(1.1,2.2,3.3,4.4),(1.1*2.2^8+3.3*4.4^8))",1.0), + test_t("equal($f75(1.1,2.2,3.3,4.4),(1.1*2.2^9+3.3*4.4^9))",1.0), + test_t("equal($f76(1.1,2.2,3.3,4.4),if(1.1 and 2.2,3.3,4.4))",1.0), + test_t("equal($f77(1.1,2.2,3.3,4.4),if(1.1 or 2.2,3.3,4.4))",1.0), + test_t("equal($f78(1.1,2.2,3.3,4.4),if(1.1 < 2.2,3.3,4.4))",1.0), + test_t("equal($f79(1.1,2.2,3.3,4.4),if(1.1 <= 2.2,3.3,4.4))",1.0), + test_t("equal($f80(1.1,2.2,3.3,4.4),if(1.1 > 2.2,3.3,4.4))",1.0), + test_t("equal($f81(1.1,2.2,3.3,4.4),if(1.1 >= 2.2,3.3,4.4))",1.0), + test_t("equal($f82(1.1,2.2,3.3,4.4),if(equal(1.1,2.2),3.3,4.4))",1.0), + test_t("equal($f83(1.1,2.2,3.3,4.4),1.1*sin(2.2)+3.3*cos(4.4))",1.0), test_t("1+2+3+4+5+6+7+8+9+0",45.0), test_t("1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0",45.0), test_t("1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + 0.0",45.0), @@ -1461,12 +1486,12 @@ inline bool run_test08() "equal($f09(x,y,z),((x/y)-z))", "equal($f10(x,y,z),((x/y)/z))", "equal($f11(x,y,z),((x/y)*z))", - "equal($f12(x,y,z),(z/(x+y)))", - "equal($f13(x,y,z),(z/(x-y)))", - "equal($f14(x,y,z),(z/(x*y)))", - "equal($f15(x,y,z),(z/(x/y)))", - "equal($f16(x,y,z),(z-(x/y)))", - "equal($f17(x,y,z),(z-(x/y)))", + "equal($f12(x,y,z),(x/(y+z)))", + "equal($f13(x,y,z),(x/(y-z)))", + "equal($f14(x,y,z),(x/(y*z)))", + "equal($f15(x,y,z),(x/(y/z)))", + "equal($f16(x,y,z),(x-(y/z)))", + "equal($f17(x,y,z),(x-(y/z)))", "equal($f18(x,y,z),(x*y^2+z))", "equal($f19(x,y,z),(x*y^3+z))", "equal($f20(x,y,z),(x*y^4+z))", @@ -1475,39 +1500,64 @@ inline bool run_test08() "equal($f23(x,y,z),(x*y^7+z))", "equal($f24(x,y,z),(x*y^8+z))", "equal($f25(x,y,z),(x*y^9+z))", - "equal($f26(x,y,z,w),(w+((x+y)/z)))", - "equal($f27(x,y,z,w),(w+((x+y)*z)))", - "equal($f28(x,y,z,w),(w+((x-y)/z)))", - "equal($f29(x,y,z,w),(w+((x-y)*z)))", - "equal($f30(x,y,z,w),(w+((x*y)/z)))", - "equal($f31(x,y,z,w),(w+((x*y)*z)))", - "equal($f32(x,y,z,w),(w+((x/y)+z)))", - "equal($f33(x,y,z,w),(w+((x/y)/z)))", - "equal($f34(x,y,z,w),(w+((x/y)*z)))", - "equal($f35(x,y,z,w),(w-((x+y)/z)))", - "equal($f36(x,y,z,w),(w-((x+y)*z)))", - "equal($f37(x,y,z,w),(w-((x-y)/z)))", - "equal($f38(x,y,z,w),(w-((x-y)*z)))", - "equal($f39(x,y,z,w),(w-((x*y)/z)))", - "equal($f40(x,y,z,w),(w-((x*y)*z)))", - "equal($f41(x,y,z,w),(w-((x/y)/z)))", - "equal($f42(x,y,z,w),(w-((x/y)*z)))", - "equal($f43(x,y,z,w),(((x+y)*z)-w))", - "equal($f44(x,y,z,w),(((x-y)*z)-w))", - "equal($f45(x,y,z,w),(((x*y)*z)-w))", - "equal($f46(x,y,z,w),(((x/y)*z)-w))", - "equal($f47(x,y,z,w),(((x+y)/z)-w))", - "equal($f48(x,y,z,w),(((x-y)/z)-w))", - "equal($f49(x,y,z,w),(((x*y)/z)-w))", - "equal($f50(x,y,z,w),(((x/y)/z)-w))", - "equal($f51(x,y,z,w),(x*y^2+z*w^2))", - "equal($f52(x,y,z,w),(x*y^3+z*w^3))", - "equal($f53(x,y,z,w),(x*y^4+z*w^4))", - "equal($f54(x,y,z,w),(x*y^5+z*w^5))", - "equal($f55(x,y,z,w),(x*y^6+z*w^6))", - "equal($f56(x,y,z,w),(x*y^7+z*w^7))", - "equal($f57(x,y,z,w),(x*y^8+z*w^8))", - "equal($f58(x,y,z,w),(x*y^9+z*w^9))" + "equal($f26(x,y,z),(x*log(y)+z))", + "equal($f27(x,y,z),(x*log(y)-z))", + "equal($f28(x,y,z),(x*log10(y)+z))", + "equal($f29(x,y,z),(x*log10(y)-z))", + "equal($f30(x,y,z),(x*sin(y)+z))", + "equal($f31(x,y,z),(x*sin(y)-z))", + "equal($f32(x,y,z),(x*cos(y)+z))", + "equal($f33(x,y,z),(x*cos(y)-z))", + "equal($f34(x,y,z),if((0 != x),y,z))", + "equal($f35(x,y,z,w),(x+((y+z)/w)))", + "equal($f36(x,y,z,w),(x+((y+z)*w)))", + "equal($f37(x,y,z,w),(x+((y-z)/w)))", + "equal($f38(x,y,z,w),(x+((y-z)*w)))", + "equal($f39(x,y,z,w),(x+((y*z)/w)))", + "equal($f40(x,y,z,w),(x+((y*z)*w)))", + "equal($f41(x,y,z,w),(x+((y/z)+w)))", + "equal($f42(x,y,z,w),(x+((y/z)/w)))", + "equal($f43(x,y,z,w),(x+((y/z)*w)))", + "equal($f44(x,y,z,w),(x-((y+z)/w)))", + "equal($f45(x,y,z,w),(x-((y+z)*w)))", + "equal($f46(x,y,z,w),(x-((y-z)/w)))", + "equal($f47(x,y,z,w),(x-((y-z)*w)))", + "equal($f48(x,y,z,w),(x-((y*z)/w)))", + "equal($f49(x,y,z,w),(x-((y*z)*w)))", + "equal($f50(x,y,z,w),(x-((y/z)/w)))", + "equal($f51(x,y,z,w),(x-((y/z)*w)))", + "equal($f52(x,y,z,w),(((x+y)*z)-w))", + "equal($f53(x,y,z,w),(((x-y)*z)-w))", + "equal($f54(x,y,z,w),(((x*y)*z)-w))", + "equal($f55(x,y,z,w),(((x/y)*z)-w))", + "equal($f56(x,y,z,w),(((x+y)/z)-w))", + "equal($f57(x,y,z,w),(((x-y)/z)-w))", + "equal($f58(x,y,z,w),(((x*y)/z)-w))", + "equal($f59(x,y,z,w),(((x/y)/z)-w))", + "equal($f60(x,y,z,w),(x*y)+(z*w))", + "equal($f61(x,y,z,w),(x*y)-(z*w))", + "equal($f62(x,y,z,w),(x*y)+(z/w))", + "equal($f63(x,y,z,w),(x*y)-(z/w))", + "equal($f64(x,y,z,w),(x/y)+(z/w))", + "equal($f65(x,y,z,w),(x/y)-(z/w))", + "equal($f66(x,y,z,w),(x/y)-(z/w))", + "equal($f67(x,y,z,w),(x/y)-(z*w))", + "equal($f68(x,y,z,w),(x*y^2+z*w^2))", + "equal($f69(x,y,z,w),(x*y^3+z*w^3))", + "equal($f70(x,y,z,w),(x*y^4+z*w^4))", + "equal($f71(x,y,z,w),(x*y^5+z*w^5))", + "equal($f72(x,y,z,w),(x*y^6+z*w^6))", + "equal($f73(x,y,z,w),(x*y^7+z*w^7))", + "equal($f74(x,y,z,w),(x*y^8+z*w^8))", + "equal($f75(x,y,z,w),(x*y^9+z*w^9))", + "equal($f76(x,y,z,w),if(x and y,z,w))", + "equal($f77(x,y,z,w),if(x or y,z,w))", + "equal($f78(x,y,z,w),if(x < y,z,w))", + "equal($f79(x,y,z,w),if(x <= y,z,w))", + "equal($f80(x,y,z,w),if(x > y,z,w))", + "equal($f81(x,y,z,w),if(x >= y,z,w))", + "equal($f82(x,y,z,w),if(equal(x,y),z,w))", + "equal($f83(x,y,z,w),x*sin(y)+z*cos(w))" }; static const std::size_t expr_str_size = sizeof(expr_str) / sizeof(std::string); @@ -2147,6 +2197,79 @@ inline bool run_test11() return true; } +template +inline bool run_test12() +{ + typedef exprtk::expression expression_t; + static const std::string expression_string[] = + { + "equal(poly1(x,2.2,1.1),(2.2x^1+1.1))", + "equal(poly2(x,3.3,2.2,1.1),(3.3x^2+2.2x^1+1.1))", + "equal(poly3(x,4.4,3.3,2.2,1.1),(4.4x^3+3.3x^2+2.2x^1+1.1))", + "equal(poly4(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(poly5(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(poly6(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(poly7(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(poly8(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(poly9(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))" + }; + static const std::size_t expression_string_size = sizeof(expression_string) / sizeof(std::string); + + T x = T(1.23456); + + exprtk::polynomial poly1; + exprtk::polynomial poly2; + exprtk::polynomial poly3; + exprtk::polynomial poly4; + exprtk::polynomial poly5; + exprtk::polynomial poly6; + exprtk::polynomial poly7; + exprtk::polynomial poly8; + exprtk::polynomial poly9; + exprtk::polynomial poly10; + + exprtk::symbol_table symbol_table; + + symbol_table.add_variable("x",x); + symbol_table.add_function( "poly1", poly1); + symbol_table.add_function( "poly2", poly2); + symbol_table.add_function( "poly3", poly3); + symbol_table.add_function( "poly4", poly4); + symbol_table.add_function( "poly5", poly5); + symbol_table.add_function( "poly6", poly6); + symbol_table.add_function( "poly7", poly7); + symbol_table.add_function( "poly8", poly8); + symbol_table.add_function( "poly9", poly9); + symbol_table.add_function("poly10",poly10); + + expression_t expression; + expression.register_symbol_table(symbol_table); + + static const std::size_t rounds = 10000; + + for (std::size_t i = 0; i < rounds; ++i) + { + for (std::size_t j = 0; j < expression_string_size; ++j) + { + const std::string& expr_str = expression_string[j]; + { + exprtk::parser parser; + if (!parser.compile(expr_str,expression)) + { + std::cout << "run_test12() - Error: " << parser.error() << "\tExpression: " << expr_str << std::endl; + return false; + } + } + if (T(1.0) != expression.value()) + { + std::cout << "run_test12() - Error in evaluation! Expression: " << expr_str << std::endl; + return false; + } + } + } + return true; +} + int main() { return ( @@ -2161,7 +2284,8 @@ int main() run_test08() && run_test09() && run_test10() && - run_test11() + run_test11() && + run_test12() ) ? 0 : 1; } diff --git a/readme.txt b/readme.txt index 94c200a..19d7420 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ C++ Mathematical Expression Toolkit Library The C++ Mathematical Expression Library (ExprTk) is a simple to use, easy to integrate and extremely efficient mathematical expression parsing and evaluation engine. The parsing engine supports various -kinds of functional, logic processing semantics and is very easily +kinds of functional and logic processing semantics and is very easily extendible. @@ -48,7 +48,7 @@ expressions that can be parsed and evaluated using the ExprTk library. (06) ({1/1}*[1/2]+(1/3))-{1/4}^[1/5]+(1/6)-({1/7}+[1/8]*(1/9)) (07) a * exp(2 * t) + c (08) z := x + sin(2 * pi / y) -(09) u <- 2 * (pi * z) / (w := x + cos(y / pi)) +(09) u := 2 * (pi * z) / (w := x + cos(y / pi)) (10) 2x + 3y + 4z + 5w == 2 * x + 3 * y + 4 * z + 5 * w (11) 3(x + y) / 2 + 1 == 3 * (x + y) / 2 + 1 (12) (x + y)3 + 1 / 4 == (x + y) * 3 + 1 / 4 @@ -115,41 +115,54 @@ an expression and by also leveraging the compiler's ability to correctly optimize such expressions for a given architecture. 3-Parameter 4-Parameter - | Prototype | Operation | | Prototype | Operation | - +------------+-------------+ +--------------+------------------+ - sf00(x,y,z) | (x + y) / z sf26(x,y,z,w) | w + ((x + y) / z) - sf01(x,y,z) | (x + y) * z sf27(x,y,z,w) | w + ((x + y) * z) - sf02(x,y,z) | (x - y) / z sf28(x,y,z,w) | w + ((x - y) / z) - sf03(x,y,z) | (x - y) * z sf29(x,y,z,w) | w + ((x - y) * z) - sf04(x,y,z) | (x * y) + z sf30(x,y,z,w) | w + ((x * y) / z) - sf05(x,y,z) | (x * y) - z sf31(x,y,z,w) | w + ((x * y) * z) - sf06(x,y,z) | (x * y) / z sf32(x,y,z,w) | w + ((x / y) + z) - sf07(x,y,z) | (x * y) * z sf33(x,y,z,w) | w + ((x / y) / z) - sf08(x,y,z) | (x / y) + z sf34(x,y,z,w) | w + ((x / y) * z) - sf09(x,y,z) | (x / y) - z sf35(x,y,z,w) | w - ((x + y) / z) - sf10(x,y,z) | (x / y) / z sf36(x,y,z,w) | w - ((x + y) * z) - sf11(x,y,z) | (x / y) * z sf37(x,y,z,w) | w - ((x - y) / z) - sf12(x,y,z) | z / (x + y) sf38(x,y,z,w) | w - ((x - y) * z) - sf13(x,y,z) | z / (x - y) sf39(x,y,z,w) | w - ((x * y) / z) - sf14(x,y,z) | z / (x * y) sf40(x,y,z,w) | w - ((x * y) * z) - sf15(x,y,z) | z / (x / y) sf41(x,y,z,w) | w - ((x / y) / z) - sf16(x,y,z) | z - (x / y) sf42(x,y,z,w) | w - ((x / y) * z) - sf17(x,y,z) | z - (x / y) sf43(x,y,z,w) | ((x + y) * z) - w - sf18(x,y,z) | x * y^2 + z sf44(x,y,z,w) | ((x - y) * z) - w - sf19(x,y,z) | x * y^3 + z sf45(x,y,z,w) | ((x * y) * z) - w - sf20(x,y,z) | x * y^4 + z sf46(x,y,z,w) | ((x / y) * z) - w - sf21(x,y,z) | x * y^5 + z sf47(x,y,z,w) | ((x + y) / z) - w - sf22(x,y,z) | x * y^6 + z sf48(x,y,z,w) | ((x - y) / z) - w - sf23(x,y,z) | x * y^7 + z sf49(x,y,z,w) | ((x * y) / z) - w - sf24(x,y,z) | x * y^8 + z sf50(x,y,z,w) | ((x / y) / z) - w - sf25(x,y,z) | x * y^9 + z sf51(x,y,z,w) | x * y^2 + z * w^2 - sf52(x,y,z,w) | x * y^3 + z * w^3 - sf53(x,y,z,w) | x * y^4 + z * w^4 - sf54(x,y,z,w) | x * y^5 + z * w^5 - sf55(x,y,z,w) | x * y^6 + z * w^6 - sf56(x,y,z,w) | x * y^7 + z * w^7 - sf57(x,y,z,w) | x * y^8 + z * w^8 - sf58(x,y,z,w) | x * y^9 + z * w^9 + +------------+-------------+ +--------------+------------------+ + | Prototype | Operation | | Prototype | Operation | + +------------+-------------+ +--------------+------------------+ + sf00(x,y,z) | (x + y) / z sf35(x,y,z,w) | x + ((y + z) / w) + sf01(x,y,z) | (x + y) * z sf36(x,y,z,w) | x + ((y + z) * w) + sf02(x,y,z) | (x - y) / z sf37(x,y,z,w) | x + ((y - z) / w) + sf03(x,y,z) | (x - y) * z sf38(x,y,z,w) | x + ((y - z) * w) + sf04(x,y,z) | (x * y) + z sf39(x,y,z,w) | x + ((y * z) / w) + sf05(x,y,z) | (x * y) - z sf40(x,y,z,w) | x + ((y * z) * w) + sf06(x,y,z) | (x * y) / z sf41(x,y,z,w) | x + ((y / z) + w) + sf07(x,y,z) | (x * y) * z sf42(x,y,z,w) | x + ((y / z) / w) + sf08(x,y,z) | (x / y) + z sf43(x,y,z,w) | x + ((y / z) * w) + sf09(x,y,z) | (x / y) - z sf44(x,y,z,w) | x - ((y + z) / w) + sf10(x,y,z) | (x / y) / z sf45(x,y,z,w) | x - ((y + z) * w) + sf11(x,y,z) | (x / y) * z sf46(x,y,z,w) | x - ((y - z) / w) + sf12(x,y,z) | x / (y + z) sf47(x,y,z,w) | x - ((y - z) * w) + sf13(x,y,z) | x / (y - z) sf48(x,y,z,w) | x - ((y * z) / w) + sf14(x,y,z) | x / (y * z) sf49(x,y,z,w) | x - ((y * z) * w) + sf15(x,y,z) | x / (y / z) sf50(x,y,z,w) | x - ((y / z) / w) + sf16(x,y,z) | x - (y / z) sf51(x,y,z,w) | x - ((y / z) * w) + sf17(x,y,z) | x - (y / z) sf52(x,y,z,w) | ((x + y) * z) - w + sf18(x,y,z) | x * y^2 + z sf53(x,y,z,w) | ((x - y) * z) - w + sf19(x,y,z) | x * y^3 + z sf54(x,y,z,w) | ((x * y) * z) - w + sf20(x,y,z) | x * y^4 + z sf55(x,y,z,w) | ((x / y) * z) - w + sf21(x,y,z) | x * y^5 + z sf56(x,y,z,w) | ((x + y) / z) - w + sf22(x,y,z) | x * y^6 + z sf57(x,y,z,w) | ((x - y) / z) - w + sf23(x,y,z) | x * y^7 + z sf58(x,y,z,w) | ((x * y) / z) - w + sf24(x,y,z) | x * y^8 + z sf59(x,y,z,w) | ((x / y) / z) - w + sf25(x,y,z) | x * y^9 + z sf60(x,y,z,w) | (x * y) + (z * w) + sf26(x,y,z) | x * log(y)+z sf61(x,y,z,w) | (x * y) - (z * w) + sf27(x,y,z) | x * log(y)-z sf62(x,y,z,w) | (x / y) + (z / w) + sf28(x,y,z) | x * log10(y)+z sf63(x,y,z,w) | (x / y) - (z / w) + sf29(x,y,z) | x * log10(y)-z sf64(x,y,z,w) | x * y^2 + z * w^2 + sf30(x,y,z) | x * sin(y)+z sf65(x,y,z,w) | x * y^3 + z * w^3 + sf31(x,y,z) | x * sin(y)-z sf66(x,y,z,w) | x * y^4 + z * w^4 + sf32(x,y,z) | x * cos(y)+z sf67(x,y,z,w) | x * y^5 + z * w^5 + sf33(x,y,z) | x * cos(y)-z sf68(x,y,z,w) | x * y^6 + z * w^6 + sf34(x,y,z) | x ? y : z sf69(x,y,z,w) | x * y^7 + z * w^7 + sf70(x,y,z,w) | x * y^8 + z * w^8 + sf71(x,y,z,w) | x * y^9 + z * w^9 + sf72(x,y,z,w) | (x and y) ? z : w + sf73(x,y,z,w) | (x or y) ? z : w + sf74(x,y,z,w) | (x < y) ? z : w + sf75(x,y,z,w) | (x <= y) ? z : w + sf76(x,y,z,w) | (x > y) ? z : w + sf77(x,y,z,w) | (x >= y) ? z : w + sf78(x,y,z,w) | (x == y) ? z : w + sf79(x,y,z,w) | x*sin(y) + z*cos(w) @@ -164,6 +177,8 @@ and the ability to evaluate strings within expressions. (2) exprtk_disable_cardinal_pow_optimisation (3) exprtk_disable_extended_optimisations (4) exprtk_disable_extended_operator_optimizations +(5) exprtk_lean_and_mean +(6) exprtk_lean_and_mean_numeric_only (1) "exprtk_disable_string_capabilities" If defined, the macro will disable all string processing capabilities.