From 061d61ecc92a73a69f866028667a1c22dfe7022d Mon Sep 17 00:00:00 2001 From: Arash Partow Date: Mon, 17 Oct 2016 09:30:38 +1100 Subject: [PATCH] C++ Mathematical Expression Library (ExprTk) https://www.partow.net/programming/exprtk/index.html --- exprtk.hpp | 73 +++++++++++++++++++++++++++++++++++++++++++++---- exprtk_test.cpp | 6 ++++ readme.txt | 9 +++--- 3 files changed, 79 insertions(+), 9 deletions(-) diff --git a/exprtk.hpp b/exprtk.hpp index b2542ee..905694b 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -2436,7 +2436,7 @@ namespace exprtk /* Permit symbols that contain a 'dot' Allowed : abc.xyz, a123.xyz, abc.123, abc_.xyz a123_.xyz abc._123 - Disallowed: abc., abc. + Disallowed: abc., abc., abc. */ if ( !is_end(s_itr_ + 1) && @@ -4377,18 +4377,18 @@ namespace exprtk namespace loop_unroll { #ifndef exprtk_disable_superscalar_unroll - const std::size_t global_loop_batch_size = 16; + const unsigned int global_loop_batch_size = 16; #else - const std::size_t global_loop_batch_size = 4; + const unsigned int global_loop_batch_size = 4; #endif struct details { details(const std::size_t& vsize, - const std::size_t loop_batch_size = global_loop_batch_size) + const unsigned int loop_batch_size = global_loop_batch_size) : batch_size(loop_batch_size), remainder (vsize % batch_size), - upper_bound(static_cast(vsize - (remainder ? loop_batch_size : 0))) + upper_bound(static_cast(vsize) - (remainder ? loop_batch_size : 0)) {} int batch_size; @@ -36286,6 +36286,11 @@ namespace exprtk nthelement() : exprtk::igeneric_function("VT|VTTT") + /* + Overloads: + 0. VT - vector, nth-element + 1. VTTT - vector, nth-element, r0, r1 + */ {} inline T operator()(const std::size_t& ps_index, parameter_list_t parameters) @@ -36310,6 +36315,61 @@ namespace exprtk } }; + template + class iota : public exprtk::igeneric_function + { + public: + + typedef typename exprtk::igeneric_function igfun_t; + typedef typename igfun_t::parameter_list_t parameter_list_t; + typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; + typedef typename generic_type::vector_view vector_t; + + using exprtk::igeneric_function::operator(); + + iota() + : exprtk::igeneric_function("VT|VTT|VTTT|VTTTT") + /* + Overloads: + 0. VT - vector, increment + 1. VT - vector, increment, base + 2. VT - vector, increment, r0, r1 + 3. VT - vector, increment, base, r0, r1 + */ + {} + + inline T operator()(const std::size_t& ps_index, parameter_list_t parameters) + { + vector_t vec(parameters[0]); + + T increment = scalar_t(parameters[1])(); + T base = ((1 == ps_index) || (3 == ps_index))? scalar_t(parameters[2])() : T(0); + + std::size_t r0 = 0; + std::size_t r1 = vec.size() - 1; + + if ((2 == ps_index) && !details::load_vector_range::process(parameters,r0,r1,2,3)) + return std::numeric_limits::quiet_NaN(); + else if ((3 == ps_index) && !details::load_vector_range::process(parameters,r0,r1,3,4)) + return std::numeric_limits::quiet_NaN(); + + if (details::invalid_range(vec,r0,r1)) + return std::numeric_limits::quiet_NaN(); + else + { + long long j = 0; + + for (std::size_t i = r0; i <= r1; ++i, ++j) + { + vec[i] = base + (increment * j); + } + } + + return T(1); + } + }; + template class sumk : public exprtk::igeneric_function { @@ -36721,6 +36781,7 @@ namespace exprtk shift_right sr; sort st; nthelement ne; + iota ia; sumk sk; axpy b1_axpy; axpby b1_axpby; @@ -36760,6 +36821,8 @@ namespace exprtk return false; else if (!symtab.add_function("nth_element" ,ne)) return false; + else if (!symtab.add_function("iota" ,ia)) + return false; else if (!symtab.add_function("sumk" ,sk)) return false; else if (!symtab.add_function("axpy" ,b1_axpy)) diff --git a/exprtk_test.cpp b/exprtk_test.cpp index 5a9f423..def1d39 100644 --- a/exprtk_test.cpp +++ b/exprtk_test.cpp @@ -6556,6 +6556,12 @@ inline bool run_test18() "var v[9] := {7,8,9,1,2,3,4,5,6}; nth_element(v,trunc(v[] / 2)); sort(v,0,trunc(v[] / 2)); (v[v[] / 2] == 5) and (v[0] == 1)", "var v[9] := {7,8,9,1,2,3,4,5,6}; nth_element(v,trunc(v[] / 3)); sort(v,0,trunc(v[] / 3)); (v[v[] / 3] == 4) and (v[0] == 1)", + "var v[5]; iota(v,2); var r[5] := {0,2,4,6,8}; sum(v == r) == v[]", + "var v[5]; iota(v,2,1); var r[5] := {1,3,5,7,9}; sum(v == r) == v[]", + "var v[5]; iota(v,1,1,3); var r[5] := {0,0,1,2,0}; sum(v == r) == v[]", + "var v[5]; iota(v,2,2,1,3);var r[5] := {0,2,4,6,0}; sum(v == r) == v[]", + "var v[5]; iota(v,2,1,1,3);var r[5] := {0,1,3,5,0}; sum(v == r) == v[]", + " var a := 2; var x[3] := {1,2,3}; var y[3] := {1,2,3}; var r[3] := [0]; r := a * x + y; axpy(a,x,y); sum(y == r) == y[]", " var a := 2; var b := 3; var x[3] := {1,2,3}; var y[3] := {1,2,3}; var r[3] := [0]; r := a * x + b * y; axpby(a,x,b,y); sum(y == r) == y[]", diff --git a/readme.txt b/readme.txt index ed39952..f527a2b 100644 --- a/readme.txt +++ b/readme.txt @@ -2735,10 +2735,11 @@ file I/O package is made available for the given expression: (g) rotate-left (h) rotate-right (i) shift-left (j) shift-right (k) sort (l) nth_element - (m) sumk (n) axpy - (o) axpby (p) axpyz - (q) axpbyz (r) axpbz - (s) dot (t) dotk + (m) iota (n) sumk + (o) axpy (p) axpby + (q) axpyz (r) axpbyz + (s) axpbz (t) dot + (u) dotk ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~