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

This commit is contained in:
Arash Partow 2014-04-21 11:16:33 +10:00
parent afc7c074fa
commit a2d640ed78
5 changed files with 1136 additions and 238 deletions

1130
exprtk.hpp

File diff suppressed because it is too large Load Diff

View File

@ -24,36 +24,33 @@
template<typename T> template<typename T>
void vector_function() void vector_function()
{ {
typedef exprtk::expression<T> expression_t; typedef exprtk::symbol_table<double> symbol_table_t;
std::string expression_string = "z := (3sin(x) + 2log(y))"; typedef exprtk::expression<double> expression_t;
typedef exprtk::parser<double> parser_t;
const std::size_t vec_size = 5; std::string expression_string =
" for (i := 0; i < min(x[],y[],z[]); i += 1) "
" { "
" z[i] := 3sin(x[i]) + 2log(y[i]); "
" } ";
T x[vec_size] = { T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) }; T x[] = { T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) };
T y[vec_size] = { T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) }; T y[] = { T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) };
T z[vec_size] = { T(0.0), T(0.0), T(0.0), T(0.0), T(0.0) }; T z[] = { T(0.0), T(0.0), T(0.0), T(0.0), T(0.0) };
T x_ = x[0]; symbol_table_t symbol_table;
T y_ = y[0]; symbol_table.add_vector("x",x);
T z_ = z[0]; symbol_table.add_vector("y",y);
symbol_table.add_vector("z",z);
exprtk::symbol_table<T> symbol_table;
symbol_table.add_variable("x",x_);
symbol_table.add_variable("y",y_);
symbol_table.add_variable("z",z_);
expression_t expression; expression_t expression;
expression.register_symbol_table(symbol_table); expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser; parser_t parser;
parser.compile(expression_string,expression); parser.compile(expression_string,expression);
for (std::size_t i = 0; i < vec_size; ++i)
{
x_ = x[i]; y_ = y[i]; z_ = z[i];
expression.value(); expression.value();
x[i] = x_; y[i] = y_; z[i] = z_;
}
} }
int main() int main()

View File

@ -53,7 +53,7 @@ void newton_sqrt()
" repeat " " repeat "
" if (equal(y * y,x), z := 0, 0);" " if (equal(y * y,x), z := 0, 0);"
" y := (1 / 2) * (y + (x / y)); " " y := (1 / 2) * (y + (x / y)); "
" until ((z := (z - 1)) <= 0) " " until ((z -= 1) <= 0) "
" }; " " }; "
"} ", "} ",
"x","y","z"); "x","y","z");

View File

@ -1684,6 +1684,85 @@ inline bool run_test01()
} }
} }
{
const std::string expr_list[] =
{
"((v[1] + x) == (x + v[1]))",
"((v[0] += x) == x)",
"((v[0] += x + y) == (x + y))",
"((v[0] -= x) == -x)",
"((v[0] -= (x + y)) == -(x + y))",
"((v[1] + v[2]) == (v[3 - 1] + v[2 * 1/2]))",
"(v[v[1]] == v[1])",
"(v[1] += v[1]) == v[1 + 1]",
"((v[i[1]] + x) == (x + v[i[1]]))",
"((v[i[0]] += x) == x)",
"((v[i[0]] += x + y) == (x + y))",
"((v[i[0]] -= x) == -x)",
"((v[i[0]] -= (x + y)) == -(x + y))",
"((v[i[1]] + v[2]) == (v[i[3] - i[1]] + v[i[2] * 1/2]))",
"(v[v[i[1]]] == v[i[1]])",
"(v[i[1]] += v[i[1]]) == v[i[1] + 1]"
};
const std::size_t expr_list_size = sizeof(expr_list) / sizeof(std::string);
const std::size_t rounds = 60;
for (std::size_t r = 0; r < rounds; ++r)
{
bool loop_result = true;
for (std::size_t i = 0; i < expr_list_size; ++i)
{
T v[] = { T(0.0), T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) };
T index[] = { T(0) , T(1) , T(2) , T(3) , T(4) , T(5) };
T x = T(6.6);
T y = T(7.7);
T z = T(8.8);
exprtk::symbol_table<T> symbol_table;
symbol_table.add_variable("x",x);
symbol_table.add_variable("y",y);
symbol_table.add_variable("z",z);
symbol_table.add_vector ("v",v);
symbol_table.add_vector ("i",index);
exprtk::expression<T> expression;
expression.register_symbol_table(symbol_table);
{
exprtk::parser<T> parser;
if (!parser.compile(expr_list[i],expression))
{
printf("run_test01() - Error: %s Expression: %s\n",
parser.error().c_str(),
expr_list[i].c_str());
loop_result = false;
continue;
}
}
T result = expression.value();
if (not_equal(result,T(1)))
{
printf("run_test01() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
expr_list[i].c_str(),
(double)1.0,
(double)result);
loop_result = false;
}
}
if (!loop_result)
{
return false;
}
}
}
return true; return true;
} }

View File

@ -53,7 +53,7 @@ expressions that can be parsed and evaluated using the ExprTk library.
(01) sqrt(1 - (3 / x^2)) (01) sqrt(1 - (3 / x^2))
(02) clamp(-1, sin(2 * pi * x) + cos(y / 2 * pi), +1) (02) clamp(-1, sin(2 * pi * x) + cos(y / 2 * pi), +1)
(03) sin(2.34e-3 * x) (03) sin(2.34e-3 * x)
(04) if(((x + 2) == 3) and ((y + 5) <= 9),1 + w, 2 / z) (04) if(((x[2] + 2) == 3) and ((y + 5) <= 9),1 + w, 2 / z)
(05) inrange(-2,m,+2) == if(({-2 <= m} and [m <= +2]),1,0) (05) inrange(-2,m,+2) == if(({-2 <= m} and [m <= +2]),1,0)
(06) ({1/1}*[1/2]+(1/3))-{1/4}^[1/5]+(1/6)-({1/7}+[1/8]*(1/9)) (06) ({1/1}*[1/2]+(1/3))-{1/4}^[1/5]+(1/6)-({1/7}+[1/8]*(1/9))
(07) a * exp(2.2 / 3.3 * t) + c (07) a * exp(2.2 / 3.3 * t) + c
@ -62,12 +62,12 @@ expressions that can be parsed and evaluated using the ExprTk library.
(10) 2x + 3y + 4z + 5w == 2 * x + 3 * y + 4 * z + 5 * w (10) 2x + 3y + 4z + 5w == 2 * x + 3 * y + 4 * z + 5 * w
(11) 3(x + y) / 2.9 + 1.234e+12 == 3 * (x + y) / 2.9 + 1.234e+12 (11) 3(x + y) / 2.9 + 1.234e+12 == 3 * (x + y) / 2.9 + 1.234e+12
(12) (x + y)3.3 + 1 / 4.5 == [x + y] * 3.3 + 1 / 4.5 (12) (x + y)3.3 + 1 / 4.5 == [x + y] * 3.3 + 1 / 4.5
(13) (x + y)z + 1.1 / 2.7 == (x + y) * z + 1.1 / 2.7 (13) (x + y[i])z + 1.1 / 2.7 == (x + y[i]) * z + 1.1 / 2.7
(14) (sin(x / pi) cos(2y) + 1) == (sin(x / pi) * cos(2 * y) + 1) (14) (sin(x / pi) cos(2y) + 1) == (sin(x / pi) * cos(2 * y) + 1)
(15) 75x^17 + 25.1x^5 - 35x^4 - 15.2x^3 + 40x^2 - 15.3x + 1 (15) 75x^17 + 25.1x^5 - 35x^4 - 15.2x^3 + 40x^2 - 15.3x + 1
(16) (avg(x,y) <= x + y ? x - y : x * y) + 2.345 * pi / x (16) (avg(x,y) <= x + y ? x - y : x * y) + 2.345 * pi / x
(17) fib_i := fib_i + (x := y + 0 * (fib_i := x + (y := fib_i))) (17) fib_i := fib_i + (x := y + 0 * (fib_i := x + (y := fib_i)))
(18) while (x <= 100) { x := x + 1 } (18) while (x <= 100) { x -= 1; }
(19) x <= 'abc123' and (y in 'AString') or ('1x2y3z' != z) (19) x <= 'abc123' and (y in 'AString') or ('1x2y3z' != z)
(20) (x like '*123*') or ('a123b' ilike y) (20) (x like '*123*') or ('a123b' ilike y)
@ -130,31 +130,31 @@ include path (e.g: /usr/include/).
+----------+---------------------------------------------------------+ +----------+---------------------------------------------------------+
| * | Multiplication between x and y. (eg: x * y) | | * | Multiplication between x and y. (eg: x * y) |
+----------+---------------------------------------------------------+ +----------+---------------------------------------------------------+
| / | Division between x and y (eg: x / y) | | / | Division between x and y. (eg: x / y) |
+----------+---------------------------------------------------------+ +----------+---------------------------------------------------------+
| % | Modulus of x with respect to y. (eg: x % y) | | % | Modulus of x with respect to y. (eg: x % y) |
+----------+---------------------------------------------------------+ +----------+---------------------------------------------------------+
| ^ | x to the power of y. (eg: x ^ y) | | ^ | x to the power of y. (eg: x ^ y) |
+----------+---------------------------------------------------------+ +----------+---------------------------------------------------------+
| := | Assign the value of x to y. (eg: y := x) | | := | Assign the value of x to y. Where y is either a variable|
| | Where y is a variable type. | | | or vector type. (eg: y := x) |
+----------+---------------------------------------------------------+ +----------+---------------------------------------------------------+
| += | Increment x to by the value of the expression on the | | += | Increment x to by the value of the expression on the |
| | right-hand side. Where x is a variable type. | | | right-hand side. Where x is either a variable or vector |
| | (eg: x += abs(y - z)) | | | type. (eg: x += abs(y - z)) |
+----------+---------------------------------------------------------+ +----------+---------------------------------------------------------+
| -= | Decrement x to by the value of the expression on the | | -= | Decrement x to by the value of the expression on the |
| | right-hand side. Where x is a variable type. | | | right-hand side. Where x is either a variable or vector |
| | (eg: x -= abs(y + z)) | | | type. (eg: x[i] -= abs(y + z)) |
+----------+---------------------------------------------------------+ +----------+---------------------------------------------------------+
| *= | Assign the multiplication of x by the value of the | | *= | Assign the multiplication of x by the value of the |
| | expression on the right-hand side to x. Where x is a | | | expression on the righthand side to x. Where x is either|
| | variable type. | | | variable or vector type. |
| | (eg: x *= abs(y / z)) | | | (eg: x *= abs(y / z)) |
+----------+---------------------------------------------------------+ +----------+---------------------------------------------------------+
| /= | Assign the division of x by the value of the expression | | /= | Assign the division of x by the value of the expression |
| | on the right-hand side to x. Where x is a variable type.| | | on the right-hand side to x. Where x is either a |
| | (eg: x /= abs(y * z)) | | | variable or vector type. (eg: x[i+j] /= abs(y * z)) |
+----------+---------------------------------------------------------+ +----------+---------------------------------------------------------+
(1) Equalities & Inequalities (1) Equalities & Inequalities
@ -442,7 +442,7 @@ include path (e.g: /usr/include/).
| | repeat | | | repeat |
| | y := x + z; | | | y := x + z; |
| | w := u + y; | | | w := u + y; |
| | until ((x - 1) <= 0) | | | until ((x += 1) > 100) |
+----------+---------------------------------------------------------+ +----------+---------------------------------------------------------+
| for | The structure will repeatedly evaluate the internal | | for | The structure will repeatedly evaluate the internal |
| | statement(s) while the condition is true. On each loop | | | statement(s) while the condition is true. On each loop |
@ -450,7 +450,7 @@ include path (e.g: /usr/include/).
| | The conditional is mandatory whereas the initializer | | | The conditional is mandatory whereas the initializer |
| | and incrementing expressions are optional. | | | and incrementing expressions are optional. |
| | eg: | | | eg: |
| | for (x := 0; x < n && (x != y); x := x + 1) | | | for (x := 0; x < n && (x != y); x += 1) |
| | { | | | { |
| | y := y + x / 2 - z; | | | y := y + x / 2 - z; |
| | w := u + y; | | | w := u + y; |
@ -487,7 +487,8 @@ appropriate may represent any of one the following:
1. Literal numeric/string value 1. Literal numeric/string value
2. A variable 2. A variable
3. An expression comprised of [1] or [2] (eg: 2 + x) 3. A vector element
3. An expression comprised of [1], [2] or [3] (eg: 2 + x / vec[3])
@ -511,10 +512,11 @@ types a symbol table can handle:
(a) Numeric variables (a) Numeric variables
(b) Numeric constants (b) Numeric constants
(c) String variables (c) Numeric vector elements
(d) String constants (d) String variables
(e) Functions (e) String constants
(f) Vararg functions (f) Functions
(g) Vararg functions
During the compilation process if an expression is found to require During the compilation process if an expression is found to require
any of the elements noted above, the expression's associated any of the elements noted above, the expression's associated
@ -638,12 +640,18 @@ properly resolved the original form will cause a compilation error.
The following is a listing of the scenarios that the joiner can The following is a listing of the scenarios that the joiner can
handle: handle:
(a) ':' '=' ---> ':=' (assignment) (a) '>' '=' ---> '>=' (gte)
(b) '>' '=' ---> '>=' (gte) (b) '<' '=' ---> '<=' (lte)
(c) '<' '=' ---> '<=' (lte) (c) '=' '=' ---> '==' (equal)
(d) '=' '=' ---> '==' (equal) (d) '!' '=' ---> '!=' (not-equal)
(e) '!' '=' ---> '!=' (not-equal) (e) '<' '>' ---> '<>' (not-equal)
(f) '<' '>' ---> '<>' (not-equal) (f) ':' '=' ---> ':=' (assignment)
(g) '+' '=' ---> '+=' (addition assignment)
(h) '-' '=' ---> '-=' (subtraction assignment)
(i) '*' '=' ---> '*=' (multiplication assignment)
(j) '/' '=' ---> '/=' (division assignment)
An example of the transformation that takes place is as follows: An example of the transformation that takes place is as follows: