C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
0d8601550f
commit
2a0be4d5a3
4
Makefile
4
Makefile
|
@ -43,8 +43,8 @@ strip_bin:
|
||||||
strip -s exprtk_benchmark
|
strip -s exprtk_benchmark
|
||||||
|
|
||||||
valgrind_check:
|
valgrind_check:
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes ./exprtk_test
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_test
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes ./exprtk_benchmark
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_benchmark
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f core.* *~ *.o *.bak *stackdump gmon.out *.gcda *.gcno *.gcnor *.gch
|
rm -f core.* *~ *.o *.bak *stackdump gmon.out *.gcda *.gcno *.gcnor *.gch
|
||||||
|
|
5982
exprtk.hpp
5982
exprtk.hpp
File diff suppressed because it is too large
Load Diff
|
@ -2,8 +2,8 @@
|
||||||
**************************************************************
|
**************************************************************
|
||||||
* C++ Mathematical Expression Toolkit Library *
|
* C++ Mathematical Expression Toolkit Library *
|
||||||
* *
|
* *
|
||||||
* Benchmarks *
|
* ExprTk vs Native Benchmarks *
|
||||||
* Author: Arash Partow (1999-2012) *
|
* Author: Arash Partow (1999-2013) *
|
||||||
* URL: http://www.partow.net/programming/exprtk/index.html *
|
* URL: http://www.partow.net/programming/exprtk/index.html *
|
||||||
* *
|
* *
|
||||||
* Copyright notice: *
|
* Copyright notice: *
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
|
@ -40,8 +41,17 @@ const std::string expression_list[] = {
|
||||||
"max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))",
|
"max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))",
|
||||||
"if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x"
|
"if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x"
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
|
const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
|
||||||
|
|
||||||
|
|
||||||
|
static const double lower_bound_x = -100.0;
|
||||||
|
static const double lower_bound_y = -100.0;
|
||||||
|
static const double upper_bound_x = +100.0;
|
||||||
|
static const double upper_bound_y = +100.0;
|
||||||
|
static const double delta = 0.0173;
|
||||||
|
|
||||||
|
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename Allocator,
|
typename Allocator,
|
||||||
template <typename,typename> class Sequence>
|
template <typename,typename> class Sequence>
|
||||||
|
@ -54,102 +64,95 @@ bool load_expression(exprtk::symbol_table<T>& symbol_table,
|
||||||
{
|
{
|
||||||
exprtk::expression<double> expression;
|
exprtk::expression<double> expression;
|
||||||
expression.register_symbol_table(symbol_table);
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
if (!parser.compile(expression_list[i],expression,opt_level))
|
if (!parser.compile(expression_list[i],expression,opt_level))
|
||||||
{
|
{
|
||||||
std::cout << "[load_expression] - Parser Error: " << parser.error() << "\tExpression: " << expression_list[i] << std::endl;
|
printf("[load_expression] - Parser Error: %s\tExpression: %s\n",
|
||||||
|
parser.error().c_str(),
|
||||||
|
expression_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_seq.push_back(expression);
|
expr_seq.push_back(expression);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void run_benchmark(T& x, T& y,
|
void run_exprtk_benchmark(T& x, T& y,
|
||||||
exprtk::expression<T>& expression,
|
exprtk::expression<T>& expression,
|
||||||
const std::string& expr_string)
|
const std::string& expr_string)
|
||||||
{
|
{
|
||||||
static const double lower_bound = -85.0;
|
|
||||||
static const double upper_bound = +85.0;
|
|
||||||
double delta = 0.01;
|
|
||||||
double total = 0.0;
|
double total = 0.0;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
exprtk::timer timer;
|
exprtk::timer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
for (x = lower_bound; x <= upper_bound; x += delta)
|
|
||||||
|
for (x = lower_bound_x; x <= upper_bound_x; x += delta)
|
||||||
{
|
{
|
||||||
for (y = lower_bound; y <= upper_bound; y += delta)
|
for (y = lower_bound_y; y <= upper_bound_y; y += delta)
|
||||||
{
|
{
|
||||||
total += expression.value();
|
total += expression.value();
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
||||||
if (T(0.0) != total)
|
if (T(0.0) != total)
|
||||||
printf("[exprtk] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n",
|
printf("[exprtk] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n",
|
||||||
timer.time(),
|
timer.time(),
|
||||||
count / timer.time(),
|
count / timer.time(),
|
||||||
expr_string.c_str());
|
expr_string.c_str());
|
||||||
else
|
else
|
||||||
std::cerr << "Error - expression: " << expr_string << "\n";
|
printf("run_exprtk_benchmark() - Error running benchmark for expression: %s\n",expr_string.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
const double pi = 3.14159265358979323846;
|
template <typename T> inline T func00(const T x, const T y);
|
||||||
|
template <typename T> inline T func01(const T x, const T y);
|
||||||
template <typename T>
|
template <typename T> inline T func02(const T x, const T y);
|
||||||
inline T avg(const T v1, const T v2)
|
template <typename T> inline T func03(const T x, const T y);
|
||||||
{
|
template <typename T> inline T func04(const T x, const T y);
|
||||||
return (v1 + v2) / T(2.0);
|
template <typename T> inline T func05(const T x, const T y);
|
||||||
}
|
template <typename T> inline T func06(const T x, const T y);
|
||||||
|
template <typename T> inline T func07(const T x, const T y);
|
||||||
template <typename T>
|
template <typename T> inline T func08(const T x, const T y);
|
||||||
inline T clamp(const T l, const T v, const T u)
|
template <typename T> inline T func09(const T x, const T y);
|
||||||
{
|
template <typename T> inline T func10(const T x, const T y);
|
||||||
return ((v < l) ? l : ((v > u) ? u : v));
|
template <typename T> inline T func11(const T x, const T y);
|
||||||
}
|
template <typename T> inline T func12(const T x, const T y);
|
||||||
|
template <typename T> inline T func13(const T x, const T y);
|
||||||
template <typename T> inline T func00(const T x, const T y) { return (y + x); }
|
template <typename T> inline T func14(const T x, const T y);
|
||||||
template <typename T> inline T func01(const T x, const T y) { return T(2.0) * (y + x); }
|
|
||||||
template <typename T> inline T func02(const T x, const T y) { return (T(2.0) * y + T(2.0) * x); }
|
|
||||||
template <typename T> inline T func03(const T x, const T y) { return (y + x / y) * (x - y / x); }
|
|
||||||
template <typename T> inline T func04(const T x, const T y) { return x / ((x + y) * (x - y)) / y; }
|
|
||||||
template <typename T> inline T func05(const T x, const T y) { return T(1.0) - ((x * y) + (y / x)) - T(3.0); }
|
|
||||||
template <typename T> 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 <typename T> inline T func07(const T x, const T y) { return std::sin(T(2.0) * x) + std::cos(pi / y); }
|
|
||||||
template <typename T> inline T func08(const T x, const T y) { return T(1.0) - std::sin(2.0 * x) + std::cos(pi / y); }
|
|
||||||
template <typename T> inline T func09(const T x, const T y) { return std::sqrt(T(111.111) - std::sin(T(2.0) * x) + std::cos(pi / y) / T(333.333)); }
|
|
||||||
template <typename T> inline T func10(const T x, const T y) { return (std::pow(x,T(2.0)) / std::sin(T(2.0) * pi / y)) -x / T(2.0); }
|
|
||||||
template <typename T> inline T func11(const T x, const T y) { return (x + (std::cos(y - std::sin(2 / x * pi)) - std::sin(x - std::cos(2 * y / pi))) - y); }
|
|
||||||
template <typename T> inline T func12(const T x, const T y) { return clamp(T(-1.0), std::sin(T(2.0) * pi * x) + std::cos(y / T(2.0) * pi), + T(1.0)); }
|
|
||||||
template <typename T> inline T func13(const T x, const T y) { return std::max(T(3.33), std::min(sqrt(T(1.0) - std::sin(T(2.0) * x) + std::cos(pi / y) / T(3.0)), T(1.11))); }
|
|
||||||
template <typename T> inline T func14(const T x, const T y) { return ((avg(x,y) <= x + y) ? x - y : x * y) + T(2.0) * pi / x; }
|
|
||||||
|
|
||||||
template <typename T, typename NativeFunction>
|
template <typename T, typename NativeFunction>
|
||||||
void run_native_benchmark(T& x, T& y, NativeFunction f, const std::string& expr_string)
|
void run_native_benchmark(T& x, T& y, NativeFunction f, const std::string& expr_string)
|
||||||
{
|
{
|
||||||
static const double lower_bound = -85.0;
|
|
||||||
static const double upper_bound = +85.0;
|
|
||||||
double delta = 0.01;
|
|
||||||
double total = 0.0;
|
double total = 0.0;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
exprtk::timer timer;
|
exprtk::timer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
for (x = lower_bound; x <= upper_bound; x += delta)
|
|
||||||
|
for (x = lower_bound_x; x <= upper_bound_x; x += delta)
|
||||||
{
|
{
|
||||||
for (y = lower_bound; y <= upper_bound; y += delta)
|
for (y = lower_bound_y; y <= upper_bound_y; y += delta)
|
||||||
{
|
{
|
||||||
total += f(x,y);
|
total += f(x,y);
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
||||||
if (T(0.0) != total)
|
if (T(0.0) != total)
|
||||||
printf("[native] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n",
|
printf("[native] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n",
|
||||||
timer.time(),
|
timer.time(),
|
||||||
count / timer.time(),
|
count / timer.time(),
|
||||||
expr_string.c_str());
|
expr_string.c_str());
|
||||||
else
|
else
|
||||||
std::cerr << "Error - expression: " << expr_string << "\n";
|
printf("run_native_benchmark() - Error running benchmark for expression: %s\n",expr_string.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -158,20 +161,28 @@ bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table)
|
||||||
static const std::size_t rounds = 1000000;
|
static const std::size_t rounds = 1000000;
|
||||||
exprtk::parser<double> parser;
|
exprtk::parser<double> parser;
|
||||||
exprtk::expression<double> expression;
|
exprtk::expression<double> expression;
|
||||||
|
|
||||||
expression.register_symbol_table(symbol_table);
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < expression_list_size; ++i)
|
for (std::size_t i = 0; i < expression_list_size; ++i)
|
||||||
{
|
{
|
||||||
exprtk::timer timer;
|
exprtk::timer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
for (std::size_t r = 0; r < rounds; ++r)
|
for (std::size_t r = 0; r < rounds; ++r)
|
||||||
{
|
{
|
||||||
if (!parser.compile(expression_list[i],expression))
|
if (!parser.compile(expression_list[i],expression))
|
||||||
{
|
{
|
||||||
std::cout << "[run_parse_benchmark] - Parser Error: " << parser.error() << "\tExpression: " << expression_list[i] << std::endl;
|
printf("[run_parse_benchmark] - Parser Error: %s\tExpression: %s\n",
|
||||||
|
parser.error().c_str(),
|
||||||
|
expression_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
||||||
printf("[parse] Total Time:%12.8f Rate:%14.3fparse/sec Expression: %s\n",
|
printf("[parse] Total Time:%12.8f Rate:%14.3fparse/sec Expression: %s\n",
|
||||||
timer.time(),
|
timer.time(),
|
||||||
rounds / timer.time(),
|
rounds / timer.time(),
|
||||||
|
@ -180,8 +191,12 @@ bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pgo_primer();
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
pgo_primer();
|
||||||
|
|
||||||
double x = 0;
|
double x = 0;
|
||||||
double y = 0;
|
double y = 0;
|
||||||
|
|
||||||
|
@ -204,16 +219,16 @@ int main()
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::cout << "--- EXPRTK [Opt All]---" << std::endl;
|
std::cout << "--- EXPRTK [All Optimisations] ---" << std::endl;
|
||||||
for (std::size_t i = 0; i < optimized_expr_list.size(); ++i)
|
for (std::size_t i = 0; i < optimized_expr_list.size(); ++i)
|
||||||
{
|
{
|
||||||
run_benchmark(x,y,optimized_expr_list[i],expression_list[i]);
|
run_exprtk_benchmark(x,y,optimized_expr_list[i],expression_list[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "--- EXPRTK [No Opt]---" << std::endl;
|
std::cout << "--- EXPRTK [No Optimisations] ---" << std::endl;
|
||||||
for (std::size_t i = 0; i < expr_list.size(); ++i)
|
for (std::size_t i = 0; i < expr_list.size(); ++i)
|
||||||
{
|
{
|
||||||
run_benchmark(x,y,expr_list[i],expression_list[i]);
|
run_exprtk_benchmark(x,y,expr_list[i],expression_list[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,3 +258,142 @@ int main()
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pgo_primer()
|
||||||
|
{
|
||||||
|
exprtk::pgo_primer<double>();
|
||||||
|
|
||||||
|
static const double lower_bound_x = -50.0;
|
||||||
|
static const double lower_bound_y = -50.0;
|
||||||
|
static const double upper_bound_x = +50.0;
|
||||||
|
static const double upper_bound_y = +50.0;
|
||||||
|
static const double delta = 0.03;
|
||||||
|
|
||||||
|
double total = 0.0;
|
||||||
|
|
||||||
|
for (double x = lower_bound_x; x <= upper_bound_x; x += delta)
|
||||||
|
{
|
||||||
|
for (double y = lower_bound_y; y <= upper_bound_y; y += delta)
|
||||||
|
{
|
||||||
|
total += func00<double>(x,y);
|
||||||
|
total += func01<double>(x,y);
|
||||||
|
total += func02<double>(x,y);
|
||||||
|
total += func03<double>(x,y);
|
||||||
|
total += func04<double>(x,y);
|
||||||
|
total += func05<double>(x,y);
|
||||||
|
total += func06<double>(x,y);
|
||||||
|
total += func07<double>(x,y);
|
||||||
|
total += func08<double>(x,y);
|
||||||
|
total += func09<double>(x,y);
|
||||||
|
total += func10<double>(x,y);
|
||||||
|
total += func11<double>(x,y);
|
||||||
|
total += func12<double>(x,y);
|
||||||
|
total += func13<double>(x,y);
|
||||||
|
total += func14<double>(x,y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const double pi = 3.14159265358979323846;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T avg(const T v1, const T v2)
|
||||||
|
{
|
||||||
|
return (v1 + v2) / T(2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T clamp(const T l, const T v, const T u)
|
||||||
|
{
|
||||||
|
return ((v < l) ? l : ((v > u) ? u : v));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func00(const T x, const T y)
|
||||||
|
{
|
||||||
|
return (y + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func01(const T x, const T y)
|
||||||
|
{
|
||||||
|
return T(2.0) * (y + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func02(const T x, const T y)
|
||||||
|
{
|
||||||
|
return (T(2.0) * y + T(2.0) * x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func03(const T x, const T y)
|
||||||
|
{
|
||||||
|
return (y + x / y) * (x - y / x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func04(const T x, const T y)
|
||||||
|
{
|
||||||
|
return x / ((x + y) * (x - y)) / y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func05(const T x, const T y)
|
||||||
|
{
|
||||||
|
return T(1.0) - ((x * y) + (y / x)) - T(3.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
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 <typename T>
|
||||||
|
inline T func07(const T x, const T y)
|
||||||
|
{
|
||||||
|
return std::sin(T(2.0) * x) + std::cos(pi / y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func08(const T x, const T y)
|
||||||
|
{
|
||||||
|
return T(1.0) - std::sin(2.0 * x) + std::cos(pi / y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func09(const T x, const T y)
|
||||||
|
{
|
||||||
|
return std::sqrt(T(111.111) - std::sin(T(2.0) * x) + std::cos(pi / y) / T(333.333));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func10(const T x, const T y)
|
||||||
|
{
|
||||||
|
return (std::pow(x,T(2.0)) / std::sin(T(2.0) * pi / y)) -x / T(2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func11(const T x, const T y)
|
||||||
|
{
|
||||||
|
return (x + (std::cos(y - std::sin(2 / x * pi)) - std::sin(x - std::cos(2 * y / pi))) - y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func12(const T x, const T y)
|
||||||
|
{
|
||||||
|
return clamp(T(-1.0), std::sin(T(2.0) * pi * x) + std::cos(y / T(2.0) * pi), + T(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func13(const T x, const T y)
|
||||||
|
{
|
||||||
|
return std::max(T(3.33), std::min(sqrt(T(1.0) - std::sin(T(2.0) * x) + std::cos(pi / y) / T(3.0)), T(1.11)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T func14(const T x, const T y)
|
||||||
|
{
|
||||||
|
return ((avg(x,y) <= x + y) ? x - y : x * y) + T(2.0) * pi / x;
|
||||||
|
}
|
||||||
|
|
479
exprtk_test.cpp
479
exprtk_test.cpp
File diff suppressed because it is too large
Load Diff
126
readme.txt
126
readme.txt
|
@ -17,14 +17,14 @@ operations, functions and processes:
|
||||||
|
|
||||||
(2) Functions: min, max, avg, sum, abs, ceil, floor, round,
|
(2) Functions: min, max, avg, sum, abs, ceil, floor, round,
|
||||||
roundn, exp, log, log10, logn, root, sqrt,
|
roundn, exp, log, log10, logn, root, sqrt,
|
||||||
clamp, inrange, sgn, erf, erfc
|
clamp, inrange, sgn, erf, erfc, frac, trunc
|
||||||
|
|
||||||
(3) Trigonometry: sin, cos, tan, acos, asin, atan, atan2, cosh,
|
(3) Trigonometry: sin, cos, tan, acos, asin, atan, atan2, cosh,
|
||||||
cot, csc, sec, sinh, tanh, rad2deg, deg2rad,
|
cot, csc, sec, sinh, tanh, rad2deg, deg2rad,
|
||||||
deg2grad, grad2deg, hyp
|
deg2grad, grad2deg, hyp
|
||||||
|
|
||||||
(4) Equalities &
|
(4) Equalities &
|
||||||
Inequalities: =, ==, <>, !=, <, <=, >, >=,
|
Inequalities: =, ==, <>, !=, <, <=, >, >=
|
||||||
|
|
||||||
(5) Boolean logic: and, or, xor, not, nand, nor, shr, shl, true,
|
(5) Boolean logic: and, or, xor, not, nand, nor, shr, shl, true,
|
||||||
false
|
false
|
||||||
|
@ -32,7 +32,11 @@ operations, functions and processes:
|
||||||
(6) Conditional &
|
(6) Conditional &
|
||||||
Loop statement: if-then-else, while
|
Loop statement: if-then-else, while
|
||||||
|
|
||||||
(7) Assigment: :=
|
(7) Assignment: :=
|
||||||
|
|
||||||
|
(8) Calculus: numerical integration and differentiation
|
||||||
|
|
||||||
|
Note: The trigonometry functions assume radians as input.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,6 +101,7 @@ Expression Library can be found at:
|
||||||
(*) GNU Compiler Collection (4.3+)
|
(*) GNU Compiler Collection (4.3+)
|
||||||
(*) Intel® C++ Compiler (9.x+)
|
(*) Intel® C++ Compiler (9.x+)
|
||||||
(*) Clang/LLVM (1.1+)
|
(*) Clang/LLVM (1.1+)
|
||||||
|
(*) PGI C++ (10.x+)
|
||||||
(*) Microsoft Visual Studio C++ Compiler (8.1+)
|
(*) Microsoft Visual Studio C++ Compiler (8.1+)
|
||||||
(*) Comeau C++ Compiler (4.3+)
|
(*) Comeau C++ Compiler (4.3+)
|
||||||
|
|
||||||
|
@ -115,9 +120,9 @@ an expression and by also leveraging the compiler's ability to
|
||||||
correctly optimize such expressions for a given architecture.
|
correctly optimize such expressions for a given architecture.
|
||||||
|
|
||||||
3-Parameter 4-Parameter
|
3-Parameter 4-Parameter
|
||||||
+------------+-------------+ +--------------+------------------+
|
+-------------+-------------+ +--------------+------------------+
|
||||||
| Prototype | Operation | | Prototype | Operation |
|
| Prototype | Operation | | Prototype | Operation |
|
||||||
+------------+-------------+ +--------------+------------------+
|
+-------------+-------------+ +--------------+------------------+
|
||||||
sf00(x,y,z) | (x + y) / z sf35(x,y,z,w) | x + ((y + z) / w)
|
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)
|
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)
|
sf02(x,y,z) | (x - y) / z sf37(x,y,z,w) | x + ((y - z) / w)
|
||||||
|
@ -145,24 +150,27 @@ correctly optimize such expressions for a given architecture.
|
||||||
sf24(x,y,z) | x * y^8 + z sf59(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)
|
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)
|
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)
|
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)
|
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
|
sf29(x,y,z) | x * log10(y)-z sf64(x,y,z,w) | (x / y) + (z / w)
|
||||||
sf30(x,y,z) | x * sin(y)+z sf65(x,y,z,w) | x * y^3 + z * w^3
|
sf30(x,y,z) | x * sin(y)+z sf65(x,y,z,w) | (x / y) - (z / w)
|
||||||
sf31(x,y,z) | x * sin(y)-z sf66(x,y,z,w) | x * y^4 + z * w^4
|
sf31(x,y,z) | x * sin(y)-z sf66(x,y,z,w) | (x / y) - (z * w)
|
||||||
sf32(x,y,z) | x * cos(y)+z sf67(x,y,z,w) | x * y^5 + z * w^5
|
sf32(x,y,z) | x * cos(y)+z sf67(x,y,z,w) | x * y^2 + z * w^2
|
||||||
sf33(x,y,z) | x * cos(y)-z sf68(x,y,z,w) | x * y^6 + z * w^6
|
sf33(x,y,z) | x * cos(y)-z sf68(x,y,z,w) | x * y^3 + z * w^3
|
||||||
sf34(x,y,z) | x ? y : z sf69(x,y,z,w) | x * y^7 + z * w^7
|
sf34(x,y,z) | x ? y : z sf69(x,y,z,w) | x * y^4 + z * w^4
|
||||||
sf70(x,y,z,w) | x * y^8 + z * w^8
|
sf70(x,y,z,w) | x * y^5 + z * w^5
|
||||||
sf71(x,y,z,w) | x * y^9 + z * w^9
|
sf71(x,y,z,w) | x * y^6 + z * w^6
|
||||||
sf72(x,y,z,w) | (x and y) ? z : w
|
sf72(x,y,z,w) | x * y^7 + z * w^7
|
||||||
sf73(x,y,z,w) | (x or y) ? z : w
|
sf73(x,y,z,w) | x * y^8 + z * w^8
|
||||||
sf74(x,y,z,w) | (x < y) ? z : w
|
sf74(x,y,z,w) | x * y^9 + z * w^9
|
||||||
sf75(x,y,z,w) | (x <= y) ? z : w
|
sf75(x,y,z,w) | (x and y) ? z : w
|
||||||
sf76(x,y,z,w) | (x > y) ? z : w
|
sf76(x,y,z,w) | (x or y) ? z : w
|
||||||
sf77(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
|
sf78(x,y,z,w) | (x <= y) ? z : w
|
||||||
sf79(x,y,z,w) | x*sin(y) + z*cos(w)
|
sf79(x,y,z,w) | (x > y) ? z : w
|
||||||
|
sf80(x,y,z,w) | (x >= y) ? z : w
|
||||||
|
sf81(x,y,z,w) | (x == y) ? z : w
|
||||||
|
sf82(x,y,z,w) | x*sin(y) + z*cos(w)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,6 +187,7 @@ and the ability to evaluate strings within expressions.
|
||||||
(4) exprtk_disable_extended_operator_optimizations
|
(4) exprtk_disable_extended_operator_optimizations
|
||||||
(5) exprtk_lean_and_mean
|
(5) exprtk_lean_and_mean
|
||||||
(6) exprtk_lean_and_mean_numeric_only
|
(6) exprtk_lean_and_mean_numeric_only
|
||||||
|
(7) exprtk_enable_all_optimizations
|
||||||
|
|
||||||
(1) "exprtk_disable_string_capabilities"
|
(1) "exprtk_disable_string_capabilities"
|
||||||
If defined, the macro will disable all string processing capabilities.
|
If defined, the macro will disable all string processing capabilities.
|
||||||
|
@ -218,12 +227,83 @@ both modes [3] and [4].
|
||||||
The mode when this macro is defined, is 'lean and mean' coupled with
|
The mode when this macro is defined, is 'lean and mean' coupled with
|
||||||
all string capabilities disabled [1].
|
all string capabilities disabled [1].
|
||||||
|
|
||||||
|
(7) "exprtk_enable_all_optimizations"
|
||||||
|
When defined all optimization mechanisms are turned on, including all
|
||||||
|
string processing related optimizations. In short nothing is disabled.
|
||||||
|
This mode will cause older C++ compilers and or compilers running on
|
||||||
|
slower machines with limited RAM to nearly come to a grinding halt as
|
||||||
|
per (3). This mode will however produce the most efficient and high
|
||||||
|
performance expression evaluation results. It is advised to have this
|
||||||
|
mode turned on for final builds and not to be used during the
|
||||||
|
development cycle.
|
||||||
|
|
||||||
Note: Foregoing a few extra clock cycles during compilation in
|
Note: Foregoing a few extra clock cycles during compilation in
|
||||||
exchange for a dramatic increase in performance during run-time is
|
exchange for a dramatic increase in performance during run-time is
|
||||||
always a worthy undertaking.
|
always a worthy undertaking.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[SIMPLE EXAMPLE]
|
||||||
|
--- snip ---
|
||||||
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "exprtk.hpp"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
typedef exprtk::symbol_table<double> symbol_table_t;
|
||||||
|
typedef exprtk::expression<double> expression_t;
|
||||||
|
typedef exprtk::parser<double> parser_t;
|
||||||
|
typedef exprtk::parser_error::type error_t;
|
||||||
|
|
||||||
|
std::string expression_str = "z := 2 [sin(x/pi)^3 + cos(pi/y)^4]";
|
||||||
|
|
||||||
|
double x = 1.1;
|
||||||
|
double y = 2.2;
|
||||||
|
double z = 3.3;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
expression_t expression;
|
||||||
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
|
parser_t parser;
|
||||||
|
|
||||||
|
if (!parser.compile(expression_str,expression))
|
||||||
|
{
|
||||||
|
printf("Error: %s\tExpression: %s\n",
|
||||||
|
parser.error().c_str(),
|
||||||
|
expression_str.c_str());
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < parser.error_count(); ++i)
|
||||||
|
{
|
||||||
|
error_t error = parser.get_error(i);
|
||||||
|
printf("Err: %02d Pos: %02d Type: [%s] Msg: %s Expr: %s\n",
|
||||||
|
static_cast<int>(i),
|
||||||
|
static_cast<int>(error.token.position),
|
||||||
|
exprtk::parser_error::to_str(error.mode).c_str(),
|
||||||
|
error.diagnostic.c_str(),
|
||||||
|
expression_str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
double result = expression.value();
|
||||||
|
|
||||||
|
printf("Result: %10.5f\n",result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--- snip ---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[FILES]
|
[FILES]
|
||||||
(00) Makefile
|
(00) Makefile
|
||||||
(01) readme.txt
|
(01) readme.txt
|
||||||
|
|
Loading…
Reference in New Issue