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

This commit is contained in:
Arash Partow 2013-03-05 00:21:28 +11:00
parent 2a0be4d5a3
commit 6431bf3b0e
5 changed files with 5510 additions and 2338 deletions

View File

@ -2,7 +2,7 @@
# ************************************************************** # **************************************************************
# * C++ Mathematical Expression Toolkit Library * # * C++ Mathematical Expression Toolkit Library *
# * * # * *
# * 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: *

6703
exprtk.hpp

File diff suppressed because it is too large Load Diff

View File

@ -28,8 +28,9 @@ const std::string expression_list[] = {
"(y + x)", "(y + x)",
"2 * (y + x)", "2 * (y + x)",
"(2 * y + 2 * x)", "(2 * y + 2 * x)",
"((1.23 * x^2) / y) - 123.123",
"(y + x / y) * (x - y / x)", "(y + x / y) * (x - y / x)",
"x / ((x + y) * (x - y)) / y", "x / ((x + y) + (x - y)) / y",
"1 - ((x * y) + (y / x)) - 3", "1 - ((x * y) + (y / x)) - 3",
"1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^15 - 5.5x^23 + 6.6y^55", "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^15 - 5.5x^23 + 6.6y^55",
"sin(2 * x) + cos(pi / y)", "sin(2 * x) + cos(pi / y)",
@ -49,31 +50,27 @@ static const double lower_bound_x = -100.0;
static const double lower_bound_y = -100.0; static const double lower_bound_y = -100.0;
static const double upper_bound_x = +100.0; static const double upper_bound_x = +100.0;
static const double upper_bound_y = +100.0; static const double upper_bound_y = +100.0;
static const double delta = 0.0173; static const double delta = 0.0111;
template <typename T, template <typename T,
typename Allocator, typename Allocator,
template <typename,typename> class Sequence> template <typename,typename> class Sequence>
bool load_expression(exprtk::symbol_table<T>& symbol_table, bool load_expression(exprtk::symbol_table<T>& symbol_table,
Sequence<exprtk::expression<T>,Allocator>& expr_seq, Sequence<exprtk::expression<T>,Allocator>& expr_seq)
const typename exprtk::parser<T>::optimization_level& opt_level)
{ {
exprtk::parser<double> parser; exprtk::parser<double> parser;
for (std::size_t i = 0; i < expression_list_size; ++i) for (std::size_t i = 0; i < expression_list_size; ++i)
{ {
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))
if (!parser.compile(expression_list[i],expression,opt_level))
{ {
printf("[load_expression] - Parser Error: %s\tExpression: %s\n", printf("[load_expression] - Parser Error: %s\tExpression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expression_list[i].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;
@ -84,12 +81,10 @@ 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)
{ {
double total = 0.0; T 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; x <= upper_bound_x; x += delta) for (x = lower_bound_x; x <= upper_bound_x; x += delta)
{ {
for (y = lower_bound_y; y <= upper_bound_y; y += delta) for (y = lower_bound_y; y <= upper_bound_y; y += delta)
@ -98,9 +93,7 @@ void run_exprtk_benchmark(T& x, T& y,
++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(),
@ -110,31 +103,15 @@ void run_exprtk_benchmark(T& x, T& y,
printf("run_exprtk_benchmark() - Error running benchmark for expression: %s\n",expr_string.c_str()); printf("run_exprtk_benchmark() - Error running benchmark for expression: %s\n",expr_string.c_str());
} }
template <typename T> inline T func00(const T x, const T y); template <typename T> struct native;
template <typename T> inline T func01(const T x, const T y);
template <typename T> inline T func02(const T x, const T y);
template <typename T> inline T func03(const T x, const T y);
template <typename T> inline T func04(const T x, const T y);
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> inline T func08(const T x, const T y);
template <typename T> inline T func09(const T x, const T y);
template <typename T> inline T func10(const T x, const T y);
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 func14(const T x, const T y);
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)
{ {
double total = 0.0; T 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; x <= upper_bound_x; x += delta) for (x = lower_bound_x; x <= upper_bound_x; x += delta)
{ {
for (y = lower_bound_y; y <= upper_bound_y; y += delta) for (y = lower_bound_y; y <= upper_bound_y; y += delta)
@ -143,9 +120,7 @@ void run_native_benchmark(T& x, T& y, NativeFunction f, const std::string& expr_
++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(),
@ -158,7 +133,7 @@ void run_native_benchmark(T& x, T& y, NativeFunction f, const std::string& expr_
template <typename T> template <typename T>
bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table) bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table)
{ {
static const std::size_t rounds = 1000000; static const std::size_t rounds = 100000;
exprtk::parser<double> parser; exprtk::parser<double> parser;
exprtk::expression<double> expression; exprtk::expression<double> expression;
@ -168,7 +143,6 @@ bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table)
{ {
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))
@ -176,13 +150,10 @@ bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table)
printf("[run_parse_benchmark] - Parser Error: %s\tExpression: %s\n", printf("[run_parse_benchmark] - Parser Error: %s\tExpression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expression_list[i].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(),
@ -191,6 +162,105 @@ bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table)
return true; return true;
} }
const double pi = 3.14159265358979323846;
template <typename T>
struct native
{
typedef typename exprtk::details::functor_t<T> functor_t;
typedef typename functor_t::Type Type;
static inline T avg(Type x, Type y)
{
return (x + y) / T(2.0);
}
static inline T clamp(const Type l, const Type v, const Type u)
{
return ((v < l) ? l : ((v > u) ? u : v));
}
static inline T func00(Type x, Type y)
{
return (y + x);
}
static inline T func01(Type x, Type y)
{
return T(2.0) * (y + x);
}
static inline T func02(Type x, Type y)
{
return (T(2.0) * y + T(2.0) * x);
}
static inline T func03(Type x, Type y)
{
return ((T(1.23) * (x * x)) / y) - T(123.123);
}
static inline T func04(Type x, Type y)
{
return (y + x / y) * (x - y / x);
}
static inline T func05(Type x, Type y)
{
return x / ((x + y) + (x - y)) / y;
}
static inline T func06(Type x, Type y)
{
return T(1.0) - ((x * y) + (y / x)) - T(3.0);
}
static inline T func07(Type x, Type 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)));
}
static inline T func08(Type x, Type y)
{
return std::sin(T(2.0) * x) + std::cos(pi / y);
}
static inline T func09(Type x, Type y)
{
return T(1.0) - std::sin(2.0 * x) + std::cos(pi / y);
}
static inline T func10(Type x, Type y)
{
return std::sqrt(T(111.111) - std::sin(T(2.0) * x) + std::cos(pi / y) / T(333.333));
}
static inline T func11(Type x, Type y)
{
return ((x * x) / std::sin(T(2.0) * pi / y)) -x / T(2.0);
}
static inline T func12(Type x, Type y)
{
return (x + (std::cos(y - std::sin(2 / x * pi)) - std::sin(x - std::cos(2 * y / pi))) - y);
}
static inline T func13(Type x, Type y)
{
return clamp(T(-1.0), std::sin(T(2.0) * pi * x) + std::cos(y / T(2.0) * pi), + T(1.0));
}
static inline T func14(Type x, Type 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)));
}
static inline T func15(Type x, Type y)
{
return ((avg(x,y) <= x + y) ? x - y : x * y) + T(2.0) * pi / x;
}
};
void pgo_primer(); void pgo_primer();
int main() int main()
@ -205,27 +275,15 @@ int main()
symbol_table.add_variable("x",x); symbol_table.add_variable("x",x);
symbol_table.add_variable("y",y); symbol_table.add_variable("y",y);
std::deque<exprtk::expression<double> > optimized_expr_list;
std::deque<exprtk::expression<double> > expr_list; std::deque<exprtk::expression<double> > expr_list;
if (!load_expression(symbol_table,optimized_expr_list,exprtk::parser<double>::e_all)) if (!load_expression(symbol_table,expr_list))
{
return 1;
}
if (!load_expression(symbol_table,expr_list,exprtk::parser<double>::e_none))
{ {
return 1; return 1;
} }
{ {
std::cout << "--- EXPRTK [All Optimisations] ---" << std::endl; std::cout << "--- EXPRTK ---" << std::endl;
for (std::size_t i = 0; i < optimized_expr_list.size(); ++i)
{
run_exprtk_benchmark(x,y,optimized_expr_list[i],expression_list[i]);
}
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_exprtk_benchmark(x,y,expr_list[i],expression_list[i]); run_exprtk_benchmark(x,y,expr_list[i],expression_list[i]);
@ -234,21 +292,22 @@ int main()
{ {
std::cout << "--- NATIVE ---" << std::endl; std::cout << "--- NATIVE ---" << std::endl;
run_native_benchmark(x,y,func00<double>,expression_list[ 0]); run_native_benchmark(x,y,native<double>::func00,expression_list[ 0]);
run_native_benchmark(x,y,func01<double>,expression_list[ 1]); run_native_benchmark(x,y,native<double>::func01,expression_list[ 1]);
run_native_benchmark(x,y,func02<double>,expression_list[ 2]); run_native_benchmark(x,y,native<double>::func02,expression_list[ 2]);
run_native_benchmark(x,y,func03<double>,expression_list[ 3]); run_native_benchmark(x,y,native<double>::func03,expression_list[ 3]);
run_native_benchmark(x,y,func04<double>,expression_list[ 4]); run_native_benchmark(x,y,native<double>::func04,expression_list[ 4]);
run_native_benchmark(x,y,func05<double>,expression_list[ 5]); run_native_benchmark(x,y,native<double>::func05,expression_list[ 5]);
run_native_benchmark(x,y,func06<double>,expression_list[ 6]); run_native_benchmark(x,y,native<double>::func06,expression_list[ 6]);
run_native_benchmark(x,y,func07<double>,expression_list[ 7]); run_native_benchmark(x,y,native<double>::func07,expression_list[ 7]);
run_native_benchmark(x,y,func08<double>,expression_list[ 8]); run_native_benchmark(x,y,native<double>::func08,expression_list[ 8]);
run_native_benchmark(x,y,func09<double>,expression_list[ 9]); run_native_benchmark(x,y,native<double>::func09,expression_list[ 9]);
run_native_benchmark(x,y,func10<double>,expression_list[10]); run_native_benchmark(x,y,native<double>::func10,expression_list[10]);
run_native_benchmark(x,y,func11<double>,expression_list[11]); run_native_benchmark(x,y,native<double>::func11,expression_list[11]);
run_native_benchmark(x,y,func12<double>,expression_list[12]); run_native_benchmark(x,y,native<double>::func12,expression_list[12]);
run_native_benchmark(x,y,func13<double>,expression_list[13]); run_native_benchmark(x,y,native<double>::func13,expression_list[13]);
run_native_benchmark(x,y,func14<double>,expression_list[14]); run_native_benchmark(x,y,native<double>::func14,expression_list[14]);
run_native_benchmark(x,y,native<double>::func15,expression_list[15]);
} }
{ {
@ -267,7 +326,7 @@ void pgo_primer()
static const double lower_bound_y = -50.0; static const double lower_bound_y = -50.0;
static const double upper_bound_x = +50.0; static const double upper_bound_x = +50.0;
static const double upper_bound_y = +50.0; static const double upper_bound_y = +50.0;
static const double delta = 0.03; static const double delta = 0.07;
double total = 0.0; double total = 0.0;
@ -275,125 +334,23 @@ void pgo_primer()
{ {
for (double y = lower_bound_y; y <= upper_bound_y; y += delta) for (double y = lower_bound_y; y <= upper_bound_y; y += delta)
{ {
total += func00<double>(x,y); total += native<double>::func00(x,y);
total += func01<double>(x,y); total += native<double>::func01(x,y);
total += func02<double>(x,y); total += native<double>::func02(x,y);
total += func03<double>(x,y); total += native<double>::func03(x,y);
total += func04<double>(x,y); total += native<double>::func04(x,y);
total += func05<double>(x,y); total += native<double>::func05(x,y);
total += func06<double>(x,y); total += native<double>::func06(x,y);
total += func07<double>(x,y); total += native<double>::func07(x,y);
total += func08<double>(x,y); total += native<double>::func08(x,y);
total += func09<double>(x,y); total += native<double>::func09(x,y);
total += func10<double>(x,y); total += native<double>::func10(x,y);
total += func11<double>(x,y); total += native<double>::func11(x,y);
total += func12<double>(x,y); total += native<double>::func12(x,y);
total += func13<double>(x,y); total += native<double>::func13(x,y);
total += func14<double>(x,y); total += native<double>::func14(x,y);
total += native<double>::func15(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;
}

View File

@ -20,6 +20,7 @@
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>
#include <deque> #include <deque>
#include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
@ -365,16 +366,16 @@ static const test_t test_list[] =
test_t("1.1^(1.1 * 2.2)", 1.25941916576299080582), test_t("1.1^(1.1 * 2.2)", 1.25941916576299080582),
test_t("2.2^(1.1 * 3.3)",17.49823848953534759743), test_t("2.2^(1.1 * 3.3)",17.49823848953534759743),
test_t("3.3^(1.1 * 2.2)",17.98058156638874965269), test_t("3.3^(1.1 * 2.2)",17.98058156638874965269),
test_t("1.23^3 == (1.23 * 1.23 * 1.23)",1.0), test_t("equal(1.23^3,(1.23 * 1.23 * 1.23))",1.0),
test_t("equal(1.23^-3,1/(1.23 * 1.23 * 1.23))",1.0), test_t("equal(1.23^-3,1/(1.23 * 1.23 * 1.23))",1.0),
test_t("(2.1 + 1.23^3) == (2.1 + [1.23 * 1.23 * 1.23])",1.0), test_t("equal((2.1 + 1.23^3),(2.1 + [1.23 * 1.23 * 1.23]))",1.0),
test_t("(2.1 - 1.23^3) == (2.1 - [1.23 * 1.23 * 1.23])",1.0), test_t("equal((2.1 - 1.23^3),(2.1 - [1.23 * 1.23 * 1.23]))",1.0),
test_t("(2.1 * 1.23^3) == (2.1 * [1.23 * 1.23 * 1.23])",1.0), test_t("equal((2.1 * 1.23^3),(2.1 * [1.23 * 1.23 * 1.23]))",1.0),
test_t("(2.1 / 1.23^3) == (2.1 / [1.23 * 1.23 * 1.23])",1.0), test_t("equal((2.1 / 1.23^3),(2.1 / [1.23 * 1.23 * 1.23]))",1.0),
test_t("(1.23^3 + 2.1) == ({1.23 * 1.23 * 1.23} + 2.1)",1.0), test_t("equal((1.23^3 + 2.1),({1.23 * 1.23 * 1.23} + 2.1))",1.0),
test_t("(1.23^3 - 2.1) == ({1.23 * 1.23 * 1.23} - 2.1)",1.0), test_t("equal((1.23^3 - 2.1),({1.23 * 1.23 * 1.23} - 2.1))",1.0),
test_t("(1.23^3 * 2.1) == ({1.23 * 1.23 * 1.23} * 2.1)",1.0), test_t("equal((1.23^3 * 2.1),({1.23 * 1.23 * 1.23} * 2.1))",1.0),
test_t("(1.23^3 / 2.1) == ({1.23 * 1.23 * 1.23} / 2.1)",1.0), test_t("equal((1.23^3 / 2.1),({1.23 * 1.23 * 1.23} / 2.1))",1.0),
test_t("equal(1.0^(1.0/2.0),sqrt(1.0))",1.0), test_t("equal(1.0^(1.0/2.0),sqrt(1.0))",1.0),
test_t("equal(1.0^(1.0/2.0),root(1.0,2.0))",1.0), test_t("equal(1.0^(1.0/2.0),root(1.0,2.0))",1.0),
test_t("equal(1.0^(1.0/3.0),root(1.0,3.0))",1.0), test_t("equal(1.0^(1.0/3.0),root(1.0,3.0))",1.0),
@ -646,87 +647,102 @@ static const test_t test_list[] =
test_t("sgn(-3)",-1.0), test_t("sgn(-3)",-1.0),
test_t("equal($f00(1.1,2.2,3.3),((1.1+2.2)/3.3))",1.0), test_t("equal($f00(1.1,2.2,3.3),((1.1+2.2)/3.3))",1.0),
test_t("equal($f01(1.1,2.2,3.3),((1.1+2.2)*3.3))",1.0), test_t("equal($f01(1.1,2.2,3.3),((1.1+2.2)*3.3))",1.0),
test_t("equal($f02(1.1,2.2,3.3),((1.1-2.2)/3.3))",1.0), test_t("equal($f02(1.1,2.2,3.3),((1.1+2.2)-3.3))",1.0),
test_t("equal($f03(1.1,2.2,3.3),((1.1-2.2)*3.3))",1.0), test_t("equal($f03(1.1,2.2,3.3),((1.1+2.2)+3.3))",1.0),
test_t("equal($f04(1.1,2.2,3.3),((1.1*2.2)+3.3))",1.0), test_t("equal($f04(1.1,2.2,3.3),((1.1-2.2)/3.3))",1.0),
test_t("equal($f05(1.1,2.2,3.3),((1.1*2.2)-3.3))",1.0), test_t("equal($f05(1.1,2.2,3.3),((1.1-2.2)*3.3))",1.0),
test_t("equal($f06(1.1,2.2,3.3),((1.1*2.2)/3.3))",1.0), test_t("equal($f06(1.1,2.2,3.3),((1.1*2.2)+3.3))",1.0),
test_t("equal($f07(1.1,2.2,3.3),((1.1*2.2)*3.3))",1.0), test_t("equal($f07(1.1,2.2,3.3),((1.1*2.2)-3.3))",1.0),
test_t("equal($f08(1.1,2.2,3.3),((1.1/2.2)+3.3))",1.0), test_t("equal($f08(1.1,2.2,3.3),((1.1*2.2)/3.3))",1.0),
test_t("equal($f09(1.1,2.2,3.3),((1.1/2.2)-3.3))",1.0), 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($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($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),(1.1/(2.2+3.3)))",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($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($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($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($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($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($f18(1.1,2.2,3.3),(1.1*(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($f19(1.1,2.2,3.3),(1.1*(2.2-3.3)))",1.0),
test_t("equal($f20(1.1,2.2,3.3),(1.1*2.2^4+3.3))",1.0), test_t("equal($f20(1.1,2.2,3.3),(1.1*(2.2*3.3)))",1.0),
test_t("equal($f21(1.1,2.2,3.3),(1.1*2.2^5+3.3))",1.0), test_t("equal($f21(1.1,2.2,3.3),(1.1*(2.2/3.3)))",1.0),
test_t("equal($f22(1.1,2.2,3.3),(1.1*2.2^6+3.3))",1.0), test_t("equal($f22(1.1,2.2,3.3),(1.1-(2.2/3.3)))",1.0),
test_t("equal($f23(1.1,2.2,3.3),(1.1*2.2^7+3.3))",1.0), test_t("equal($f23(1.1,2.2,3.3),(1.1-(2.2/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($f24(1.1,2.2,3.3),(1.1-(2.2*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($f25(1.1,2.2,3.3),(1.1+(2.2*3.3)))",1.0),
test_t("equal($f26(1.1,2.2,3.3),(1.1*log(2.2)+3.3))",1.0), test_t("equal($f26(1.1,2.2,3.3),(1.1+(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($f27(1.1,2.2,3.3),(1.1+(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($f28(1.1,2.2,3.3),(1.1+(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($f29(1.1,2.2,3.3),(1.1*2.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($f30(1.1,2.2,3.3),(1.1*2.2^3+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($f31(1.1,2.2,3.3),(1.1*2.2^4+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($f32(1.1,2.2,3.3),(1.1*2.2^5+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($f33(1.1,2.2,3.3),(1.1*2.2^6+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($f34(1.1,2.2,3.3),(1.1*2.2^7+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($f35(1.1,2.2,3.3),(1.1*2.2^8+3.3))",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($f36(1.1,2.2,3.3),(1.1*2.2^9+3.3))",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($f37(1.1,2.2,3.3),(1.1*log(2.2)+3.3))",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($f38(1.1,2.2,3.3),(1.1*log(2.2)-3.3))",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($f39(1.1,2.2,3.3),(1.1*log10(2.2)+3.3))",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($f40(1.1,2.2,3.3),(1.1*log10(2.2)-3.3))",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($f41(1.1,2.2,3.3),(1.1*sin(2.2)+3.3))",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($f42(1.1,2.2,3.3),(1.1*sin(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($f43(1.1,2.2,3.3),(1.1*cos(2.2)+3.3))",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($f44(1.1,2.2,3.3),(1.1*cos(2.2)-3.3))",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($f45(1.1,2.2,3.3),if((0 != 1.1),2.2,3.3))",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($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($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($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($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($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($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($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($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($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($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($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($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($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($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($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($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($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($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($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($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($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^2+3.3*4.4^2))",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^3+3.3*4.4^3))",1.0), test_t("equal($f68(1.1,2.2,3.3,4.4),(((1.1-2.2)/3.3)-4.4))",1.0),
test_t("equal($f69(1.1,2.2,3.3,4.4),(1.1*2.2^4+3.3*4.4^4))",1.0), test_t("equal($f69(1.1,2.2,3.3,4.4),(((1.1*2.2)/3.3)-4.4))",1.0),
test_t("equal($f70(1.1,2.2,3.3,4.4),(1.1*2.2^5+3.3*4.4^5))",1.0), test_t("equal($f70(1.1,2.2,3.3,4.4),(((1.1/2.2)/3.3)-4.4))",1.0),
test_t("equal($f71(1.1,2.2,3.3,4.4),(1.1*2.2^6+3.3*4.4^6))",1.0), test_t("equal($f71(1.1,2.2,3.3,4.4),(1.1*2.2)+(3.3*4.4))",1.0),
test_t("equal($f72(1.1,2.2,3.3,4.4),(1.1*2.2^7+3.3*4.4^7))",1.0), test_t("equal($f72(1.1,2.2,3.3,4.4),(1.1*2.2)-(3.3*4.4))",1.0),
test_t("equal($f73(1.1,2.2,3.3,4.4),(1.1*2.2^8+3.3*4.4^8))",1.0), test_t("equal($f73(1.1,2.2,3.3,4.4),(1.1*2.2)+(3.3/4.4))",1.0),
test_t("equal($f74(1.1,2.2,3.3,4.4),(1.1*2.2^9+3.3*4.4^9))",1.0), test_t("equal($f74(1.1,2.2,3.3,4.4),(1.1*2.2)-(3.3/4.4))",1.0),
test_t("equal($f75(1.1,2.2,3.3,4.4),if(1.1 and 2.2,3.3,4.4))",1.0), test_t("equal($f75(1.1,2.2,3.3,4.4),(1.1/2.2)+(3.3/4.4))",1.0),
test_t("equal($f76(1.1,2.2,3.3,4.4),if(1.1 or 2.2,3.3,4.4))",1.0), test_t("equal($f76(1.1,2.2,3.3,4.4),(1.1/2.2)-(3.3/4.4))",1.0),
test_t("equal($f77(1.1,2.2,3.3,4.4),if(1.1 < 2.2,3.3,4.4))",1.0), test_t("equal($f77(1.1,2.2,3.3,4.4),(1.1/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($f78(1.1,2.2,3.3,4.4),(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($f79(1.1,2.2,3.3,4.4),(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($f80(1.1,2.2,3.3,4.4),(1.1*(2.2+(3.3*4.4))))",1.0),
test_t("equal($f81(1.1,2.2,3.3,4.4),if(equal(1.1,2.2),3.3,4.4))",1.0), test_t("equal($f81(1.1,2.2,3.3,4.4),(1.1*(2.2-(3.3*4.4))))",1.0),
test_t("equal($f82(1.1,2.2,3.3,4.4),1.1*sin(2.2)+3.3*cos(4.4))",1.0), test_t("equal($f82(1.1,2.2,3.3,4.4),(1.1*2.2^2+3.3*4.4^2))",1.0),
test_t("equal($f83(1.1,2.2,3.3,4.4),(1.1*2.2^3+3.3*4.4^3))",1.0),
test_t("equal($f84(1.1,2.2,3.3,4.4),(1.1*2.2^4+3.3*4.4^4))",1.0),
test_t("equal($f85(1.1,2.2,3.3,4.4),(1.1*2.2^5+3.3*4.4^5))",1.0),
test_t("equal($f86(1.1,2.2,3.3,4.4),(1.1*2.2^6+3.3*4.4^6))",1.0),
test_t("equal($f87(1.1,2.2,3.3,4.4),(1.1*2.2^7+3.3*4.4^7))",1.0),
test_t("equal($f88(1.1,2.2,3.3,4.4),(1.1*2.2^8+3.3*4.4^8))",1.0),
test_t("equal($f89(1.1,2.2,3.3,4.4),(1.1*2.2^9+3.3*4.4^9))",1.0),
test_t("equal($f90(1.1,2.2,3.3,4.4),if(1.1 and 2.2,3.3,4.4))",1.0),
test_t("equal($f91(1.1,2.2,3.3,4.4),if(1.1 or 2.2,3.3,4.4))",1.0),
test_t("equal($f92(1.1,2.2,3.3,4.4),if(1.1 < 2.2,3.3,4.4))",1.0),
test_t("equal($f93(1.1,2.2,3.3,4.4),if(1.1 <= 2.2,3.3,4.4))",1.0),
test_t("equal($f94(1.1,2.2,3.3,4.4),if(1.1 > 2.2,3.3,4.4))",1.0),
test_t("equal($f95(1.1,2.2,3.3,4.4),if(1.1 >= 2.2,3.3,4.4))",1.0),
test_t("equal($f96(1.1,2.2,3.3,4.4),if(equal(1.1,2.2),3.3,4.4))",1.0),
test_t("equal($f97(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 + 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), test_t("1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + 0.0",45.0),
@ -758,7 +774,7 @@ static const test_t test_list[] =
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_t); static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_t);
template <typename T> template <typename T>
inline bool not_equal(const T& t1, inline bool not_equal_impl(const T& t1,
const T& t2, const T& t2,
const T& epsilon = 0.0000000001/*std::numeric_limits<T>::epsilon()*/) const T& epsilon = 0.0000000001/*std::numeric_limits<T>::epsilon()*/)
{ {
@ -769,6 +785,18 @@ inline bool not_equal(const T& t1,
return diff > eps_norm; return diff > eps_norm;
} }
template <typename T>
inline bool not_equal(const T& t0, const T& t1,
const T& epsilon = T(0.0000000001))
{
return not_equal_impl(t0,t1,epsilon);
}
inline bool not_equal(const float& t0, const float& t1, const float& epsilon = 0.000001f)
{
return not_equal_impl(t0,t1,epsilon);
}
template <typename T> template <typename T>
inline bool test_expression(const std::string& expression_string, const T& expected_result) inline bool test_expression(const std::string& expression_string, const T& expected_result)
{ {
@ -786,7 +814,6 @@ inline bool test_expression(const std::string& expression_string, const T& expec
printf("test_expression() - Error: %s Expression: %s\n", printf("test_expression() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expression_string.c_str()); expression_string.c_str());
return false; return false;
} }
} }
@ -795,19 +822,17 @@ inline bool test_expression(const std::string& expression_string, const T& expec
{ {
printf("test_expression() - Error: Expression did not compile to a constant! Expression: %s\n", printf("test_expression() - Error: Expression did not compile to a constant! Expression: %s\n",
expression_string.c_str()); expression_string.c_str());
return false; return false;
} }
T result = expression.value(); T result = expression.value();
if (not_equal<T>(result,expected_result)) if (not_equal(result,expected_result))
{ {
printf("Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n", printf("test_expression() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
expression_string.c_str(), expression_string.c_str(),
expected_result, expected_result,
result); result);
return false; return false;
} }
@ -817,16 +842,17 @@ inline bool test_expression(const std::string& expression_string, const T& expec
template <typename T> template <typename T>
inline bool run_test00() inline bool run_test00()
{ {
const std::size_t rounds = 40; const std::size_t rounds = 10;
for (std::size_t r = 0; r < rounds; ++r) for (std::size_t r = 0; r < rounds; ++r)
{ {
for (std::size_t i = 0; i < test_list_size; ++i) for (std::size_t i = 0; i < test_list_size; ++i)
{ {
if (!test_expression<T>(test_list[i].first,T(test_list[i].second))) if (!test_expression<T>(test_list[i].first,T(test_list[i].second)))
{
return false; return false;
} }
} }
}
return true; return true;
} }
@ -1037,20 +1063,18 @@ inline bool run_test01()
printf("run_test01() - Error: %s Expression: %s\n", printf("run_test01() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
test.expr.c_str()); test.expr.c_str());
return false; return false;
} }
} }
T result = expression.value(); T result = expression.value();
if (not_equal<T>(result,test.result)) if (not_equal(result,test.result))
{ {
printf("run_test01() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n", printf("run_test01() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
test.expr.c_str(), test.expr.c_str(),
test.result, test.result,
result); result);
return false; return false;
} }
} }
@ -1173,20 +1197,18 @@ inline bool run_test02()
printf("run_test02() - Error: %s Expression: %s\n", printf("run_test02() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
test.expr.c_str()); test.expr.c_str());
return false; return false;
} }
} }
T result = expression.value(); T result = expression.value();
if (not_equal<T>(result,test.result)) if (not_equal(result,test.result))
{ {
printf("run_test02() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n", printf("run_test02() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
test.expr.c_str(), test.expr.c_str(),
test.result, test.result,
result); result);
return false; return false;
} }
} }
@ -1247,7 +1269,7 @@ inline bool run_test03()
for (std::size_t i = 0; i < variable_list_size; ++i) for (std::size_t i = 0; i < variable_list_size; ++i)
{ {
v[i] = i; v[i] = T(i);
symbol_table.add_variable(variable_list[i],v[i]); symbol_table.add_variable(variable_list[i],v[i]);
} }
@ -1262,7 +1284,6 @@ inline bool run_test03()
printf("run_test03() - Error: %s Expression: %s\n", printf("run_test03() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expression_string.c_str()); expression_string.c_str());
return false; return false;
} }
@ -1303,7 +1324,6 @@ inline bool run_test04()
printf("run_test04() - Error: %s Expression: %s\n", printf("run_test04() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expression_string.c_str()); expression_string.c_str());
return false; return false;
} }
} }
@ -1316,7 +1336,7 @@ inline bool run_test04()
T result1 = expression.value(); T result1 = expression.value();
T result2 = clamp<T>(-1.0,std::sin(2 * pi * x) + std::cos(y / 2 * pi),+1.0); T result2 = clamp<T>(-1.0,std::sin(2 * pi * x) + std::cos(y / 2 * pi),+1.0);
if (not_equal<T>(result1,result2)) if (not_equal(result1,result2))
{ {
printf("run_test04() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\n", printf("run_test04() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\n",
expression_string.c_str(), expression_string.c_str(),
@ -1324,7 +1344,6 @@ inline bool run_test04()
result2, result2,
x, x,
y); y);
return false; return false;
} }
@ -1363,7 +1382,6 @@ inline bool run_test05()
printf("run_test05() - Error: %s Expression: %s\n", printf("run_test05() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expression_string.c_str()); expression_string.c_str());
return false; return false;
} }
@ -1383,7 +1401,7 @@ inline bool run_test05()
T result = expr.value(); T result = expr.value();
if (not_equal<T>(result,real_result)) if (not_equal(result,real_result))
{ {
printf("run_test05() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\tIndex:%d\n", printf("run_test05() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\tIndex:%d\n",
expression_string.c_str(), expression_string.c_str(),
@ -1392,7 +1410,6 @@ inline bool run_test05()
x, x,
y, y,
static_cast<unsigned int>(i)); static_cast<unsigned int>(i));
return false; return false;
} }
} }
@ -1425,7 +1442,6 @@ inline bool run_test06()
printf("run_test06() - Error: %s Expression: %s\n", printf("run_test06() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expression_string.c_str()); expression_string.c_str());
return false; return false;
} }
@ -1433,13 +1449,13 @@ inline bool run_test06()
T total_area2 = exprtk::integrate(expression,"x",T(-1.0),T(1.0)); T total_area2 = exprtk::integrate(expression,"x",T(-1.0),T(1.0));
const T pi = T(3.14159265358979323846); const T pi = T(3.14159265358979323846);
if (not_equal<T>(total_area1,total_area2,0.000001)) if (not_equal(total_area1,total_area2,T(0.000001)))
{ {
printf("run_test06() - Integration Error: area1 != area2\n"); printf("run_test06() - Integration Error: area1 != area2\n");
return false; return false;
} }
if (not_equal<T>(total_area1,pi/T(2.0),0.000001)) if (not_equal(total_area1,T(pi)/T(2.0),T(0.000001)))
{ {
printf("run_test06() - Integration Error: Expected: %19.15f\tResult: %19.15f\n", printf("run_test06() - Integration Error: Expected: %19.15f\tResult: %19.15f\n",
pi/T(2.0), pi/T(2.0),
@ -1475,26 +1491,24 @@ inline bool run_test07()
return false; return false;
} }
for (x = -200.0; x < 200; x+=0.0001) for (x = T(-200.0); x < T(200); x+=T(0.0001))
{ {
T result1 = exprtk::derivative(expression,x); T result1 = exprtk::derivative(expression,x);
T result2 = exprtk::derivative(expression,"x"); T result2 = exprtk::derivative(expression,"x");
T real_result = T(2.0) * std::cos(T(2.0) * x + T(1.0/3.0)); T real_result = T(2.0) * std::cos(T(2.0) * x + T(1.0/3.0));
if (not_equal<T>(result1,result2,0.000000001)) if (not_equal(result1,result2,T(0.000000001)))
{ {
printf("run_test07() - Derivative Error: result1 != result2\n"); printf("run_test07() - Derivative Error: result1 != result2\n");
return false; return false;
} }
if (not_equal<T>(result1,real_result,0.000000001)) if (not_equal(result1,real_result,T(0.000000001)))
{ {
printf("run_test07() - Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n", printf("run_test07() - Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n",
x, x,
real_result, real_result,
result1); result1);
return false; return false;
} }
} }
@ -1538,87 +1552,102 @@ inline bool run_test08()
"(sgn(sin(x))cos(sgn(y))+1)==(sgn(sin(x))*cos(sgn(y))+1)", "(sgn(sin(x))cos(sgn(y))+1)==(sgn(sin(x))*cos(sgn(y))+1)",
"equal($f00(x,y,z),((x+y)/z))", "equal($f00(x,y,z),((x+y)/z))",
"equal($f01(x,y,z),((x+y)*z))", "equal($f01(x,y,z),((x+y)*z))",
"equal($f02(x,y,z),((x-y)/z))", "equal($f02(x,y,z),((x+y)-z))",
"equal($f03(x,y,z),((x-y)*z))", "equal($f03(x,y,z),((x+y)+z))",
"equal($f04(x,y,z),((x*y)+z))", "equal($f04(x,y,z),((x-y)/z))",
"equal($f05(x,y,z),((x*y)-z))", "equal($f05(x,y,z),((x-y)*z))",
"equal($f06(x,y,z),((x*y)/z))", "equal($f06(x,y,z),((x*y)+z))",
"equal($f07(x,y,z),((x*y)*z))", "equal($f07(x,y,z),((x*y)-z))",
"equal($f08(x,y,z),((x/y)+z))", "equal($f08(x,y,z),((x*y)/z))",
"equal($f09(x,y,z),((x/y)-z))", "equal($f09(x,y,z),((x*y)*z))",
"equal($f10(x,y,z),((x/y)/z))", "equal($f10(x,y,z),((x/y)+z))",
"equal($f11(x,y,z),((x/y)*z))", "equal($f11(x,y,z),((x/y)-z))",
"equal($f12(x,y,z),(x/(y+z)))", "equal($f12(x,y,z),((x/y)/z))",
"equal($f13(x,y,z),(x/(y-z)))", "equal($f13(x,y,z),((x/y)*z))",
"equal($f14(x,y,z),(x/(y*z)))", "equal($f14(x,y,z),(x/(y+z)))",
"equal($f15(x,y,z),(x/(y/z)))", "equal($f15(x,y,z),(x/(y-z)))",
"equal($f16(x,y,z),(x-(y/z)))", "equal($f16(x,y,z),(x/(y*z)))",
"equal($f17(x,y,z),(x-(y/z)))", "equal($f17(x,y,z),(x/(y/z)))",
"equal($f18(x,y,z),(x*y^2+z))", "equal($f18(x,y,z),(x*(y+z)))",
"equal($f19(x,y,z),(x*y^3+z))", "equal($f19(x,y,z),(x*(y-z)))",
"equal($f20(x,y,z),(x*y^4+z))", "equal($f20(x,y,z),(x*(y*z)))",
"equal($f21(x,y,z),(x*y^5+z))", "equal($f21(x,y,z),(x*(y/z)))",
"equal($f22(x,y,z),(x*y^6+z))", "equal($f22(x,y,z),(x-(y/z)))",
"equal($f23(x,y,z),(x*y^7+z))", "equal($f23(x,y,z),(x-(y/z)))",
"equal($f24(x,y,z),(x*y^8+z))", "equal($f24(x,y,z),(x-(y*z)))",
"equal($f25(x,y,z),(x*y^9+z))", "equal($f25(x,y,z),(x+(y*z)))",
"equal($f26(x,y,z),(x*log(y)+z))", "equal($f26(x,y,z),(x+(y/z)))",
"equal($f27(x,y,z),(x*log(y)-z))", "equal($f27(x,y,z),(x+(y+z)))",
"equal($f28(x,y,z),(x*log10(y)+z))", "equal($f28(x,y,z),(x+(y-z)))",
"equal($f29(x,y,z),(x*log10(y)-z))", "equal($f29(x,y,z),(x*y^2+z))",
"equal($f30(x,y,z),(x*sin(y)+z))", "equal($f30(x,y,z),(x*y^3+z))",
"equal($f31(x,y,z),(x*sin(y)-z))", "equal($f31(x,y,z),(x*y^4+z))",
"equal($f32(x,y,z),(x*cos(y)+z))", "equal($f32(x,y,z),(x*y^5+z))",
"equal($f33(x,y,z),(x*cos(y)-z))", "equal($f33(x,y,z),(x*y^6+z))",
"equal($f34(x,y,z),if((0 != x),y,z))", "equal($f34(x,y,z),(x*y^7+z))",
"equal($f35(x,y,z,w),(x+((y+z)/w)))", "equal($f35(x,y,z),(x*y^8+z))",
"equal($f36(x,y,z,w),(x+((y+z)*w)))", "equal($f36(x,y,z),(x*y^9+z))",
"equal($f37(x,y,z,w),(x+((y-z)/w)))", "equal($f37(x,y,z),(x*log(y)+z))",
"equal($f38(x,y,z,w),(x+((y-z)*w)))", "equal($f38(x,y,z),(x*log(y)-z))",
"equal($f39(x,y,z,w),(x+((y*z)/w)))", "equal($f39(x,y,z),(x*log10(y)+z))",
"equal($f40(x,y,z,w),(x+((y*z)*w)))", "equal($f40(x,y,z),(x*log10(y)-z))",
"equal($f41(x,y,z,w),(x+((y/z)+w)))", "equal($f41(x,y,z),(x*sin(y)+z))",
"equal($f42(x,y,z,w),(x+((y/z)/w)))", "equal($f42(x,y,z),(x*sin(y)-z))",
"equal($f43(x,y,z,w),(x+((y/z)*w)))", "equal($f43(x,y,z),(x*cos(y)+z))",
"equal($f44(x,y,z,w),(x-((y+z)/w)))", "equal($f44(x,y,z),(x*cos(y)-z))",
"equal($f45(x,y,z,w),(x-((y+z)*w)))", "equal($f45(x,y,z),if((0 != x),y,z))",
"equal($f46(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($f47(x,y,z,w),(x+((y+z)*w)))",
"equal($f48(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($f49(x,y,z,w),(x+((y-z)*w)))",
"equal($f50(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($f51(x,y,z,w),(x+((y*z)*w)))",
"equal($f52(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($f53(x,y,z,w),(x+((y/z)/w)))",
"equal($f54(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($f55(x,y,z,w),(x-((y+z)/w)))",
"equal($f56(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($f57(x,y,z,w),(x-((y-z)/w)))",
"equal($f58(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($f59(x,y,z,w),(x-((y*z)/w)))",
"equal($f60(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($f61(x,y,z,w),(x-((y/z)/w)))",
"equal($f62(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($f63(x,y,z,w),(((x+y)*z)-w))",
"equal($f64(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($f65(x,y,z,w),(((x*y)*z)-w))",
"equal($f66(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^2+z*w^2))", "equal($f67(x,y,z,w),(((x+y)/z)-w))",
"equal($f68(x,y,z,w),(x*y^3+z*w^3))", "equal($f68(x,y,z,w),(((x-y)/z)-w))",
"equal($f69(x,y,z,w),(x*y^4+z*w^4))", "equal($f69(x,y,z,w),(((x*y)/z)-w))",
"equal($f70(x,y,z,w),(x*y^5+z*w^5))", "equal($f70(x,y,z,w),(((x/y)/z)-w))",
"equal($f71(x,y,z,w),(x*y^6+z*w^6))", "equal($f71(x,y,z,w),(x*y)+(z*w))",
"equal($f72(x,y,z,w),(x*y^7+z*w^7))", "equal($f72(x,y,z,w),(x*y)-(z*w))",
"equal($f73(x,y,z,w),(x*y^8+z*w^8))", "equal($f73(x,y,z,w),(x*y)+(z/w))",
"equal($f74(x,y,z,w),(x*y^9+z*w^9))", "equal($f74(x,y,z,w),(x*y)-(z/w))",
"equal($f75(x,y,z,w),if(x and y,z,w))", "equal($f75(x,y,z,w),(x/y)+(z/w))",
"equal($f76(x,y,z,w),if(x or y,z,w))", "equal($f76(x,y,z,w),(x/y)-(z/w))",
"equal($f77(x,y,z,w),if(x < y,z,w))", "equal($f77(x,y,z,w),(x/y)-(z*w))",
"equal($f78(x,y,z,w),if(x <= y,z,w))", "equal($f78(x,y,z,w),(x/(y+(z*w))))",
"equal($f79(x,y,z,w),if(x > y,z,w))", "equal($f79(x,y,z,w),(x/(y-(z*w))))",
"equal($f80(x,y,z,w),if(x >= y,z,w))", "equal($f80(x,y,z,w),(x*(y+(z*w))))",
"equal($f81(x,y,z,w),if(equal(x,y),z,w))", "equal($f81(x,y,z,w),(x*(y-(z*w))))",
"equal($f82(x,y,z,w),x*sin(y)+z*cos(w))" "equal($f82(x,y,z,w),(x*y^2+z*w^2))",
"equal($f83(x,y,z,w),(x*y^3+z*w^3))",
"equal($f84(x,y,z,w),(x*y^4+z*w^4))",
"equal($f85(x,y,z,w),(x*y^5+z*w^5))",
"equal($f86(x,y,z,w),(x*y^6+z*w^6))",
"equal($f87(x,y,z,w),(x*y^7+z*w^7))",
"equal($f88(x,y,z,w),(x*y^8+z*w^8))",
"equal($f89(x,y,z,w),(x*y^9+z*w^9))",
"equal($f90(x,y,z,w),if(x and y,z,w))",
"equal($f91(x,y,z,w),if(x or y,z,w))",
"equal($f92(x,y,z,w),if(x < y,z,w))",
"equal($f93(x,y,z,w),if(x <= y,z,w))",
"equal($f94(x,y,z,w),if(x > y,z,w))",
"equal($f95(x,y,z,w),if(x >= y,z,w))",
"equal($f96(x,y,z,w),if(equal(x,y),z,w))",
"equal($f97(x,y,z,w),x*sin(y)+z*cos(w))"
}; };
static const std::size_t expr_str_size = sizeof(expr_str) / sizeof(std::string); static const std::size_t expr_str_size = sizeof(expr_str) / sizeof(std::string);
@ -1653,7 +1682,6 @@ inline bool run_test08()
printf("run_test08() - Error: %s Expression: %s\n", printf("run_test08() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expr_str[j].c_str()); expr_str[j].c_str());
return false; return false;
} }
@ -1703,8 +1731,8 @@ inline bool run_test09()
"myfunc6(sin(x*pi),y/2)+myfunc7(sin(x*pi),y/2)+" "myfunc6(sin(x*pi),y/2)+myfunc7(sin(x*pi),y/2)+"
"myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)"; "myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)";
T x = T(1.0) + (i/10000.0); T x = T(1.0) + (i/T(10000.0));
T y = T(2.0) + (i/10000.0); T y = T(2.0) + (i/T(10000.0));
myfunc<T> mf; myfunc<T> mf;
exprtk::symbol_table<T> symbol_table; exprtk::symbol_table<T> symbol_table;
@ -1732,7 +1760,6 @@ inline bool run_test09()
printf("run_test09() - Error: %s Expression: %s\n", printf("run_test09() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expression_string.c_str()); expression_string.c_str());
return false; return false;
} }
@ -1742,19 +1769,19 @@ inline bool run_test09()
T expected = T(4.0) * T expected = T(4.0) *
( (
mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/T(2.0)) +
mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/T(2.0)) +
mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/T(2.0)) +
mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/T(2.0)) +
mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/T(2.0)) +
mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/T(2.0)) +
mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/T(2.0)) +
mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/T(2.0)) +
mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/T(2.0)) +
mf(sin(x*pi),y/2.0) mf(sin(x*pi),y/T(2.0))
); );
if (not_equal<T>(result,expected,0.0000001)) if (not_equal(result,expected,T(0.0000001)))
{ {
printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n", printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n",
expected, expected,
@ -1789,7 +1816,7 @@ inline bool run_test10()
{ {
exprtk::details::variable_node<T>* var = symbol_table.get_variable(variable_name); exprtk::details::variable_node<T>* var = symbol_table.get_variable(variable_name);
if (var) if (var)
return (!not_equal<T>(var->ref(),value)); return (!not_equal(var->ref(),value));
else else
return false; return false;
} }
@ -2188,7 +2215,6 @@ inline bool run_test10()
printf("run_test10() - Error: %s Expression: %s\n", printf("run_test10() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expression_string.c_str()); expression_string.c_str());
return false; return false;
} }
} }
@ -2205,7 +2231,6 @@ inline bool run_test10()
printf("run_test10() - Error: %s Expression: %s\n", printf("run_test10() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expression_string.c_str()); expression_string.c_str());
return false; return false;
} }
} }
@ -2213,7 +2238,6 @@ inline bool run_test10()
st1.remove_variable("x0"); st1.remove_variable("x0");
st1.remove_variable("y0"); st1.remove_variable("y0");
st1.remove_variable("z0"); st1.remove_variable("z0");
} }
} }
} }
@ -2248,12 +2272,11 @@ inline bool run_test11()
printf("run_test11() - Error: %s Expression: %s\n", printf("run_test11() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expression_string.c_str()); expression_string.c_str());
return false; return false;
} }
} }
if (not_equal<T>(expression.value(),(x + y)/T(3.0),0.000001)) if (not_equal(expression.value(),(x + y)/T(3.0),T(0.000001)))
{ {
printf("run_test11() - Error in evaluation!(1)\n"); printf("run_test11() - Error in evaluation!(1)\n");
return false; return false;
@ -2281,7 +2304,7 @@ inline bool run_test11()
expression.value(); expression.value();
if (not_equal<T>(expression.value(),(x + y)/T(3.0),0.000001)) if (not_equal(expression.value(),(x + y)/T(3.0),T(0.000001)))
{ {
printf("run_test11() - Error in evaluation!(3)\n"); printf("run_test11() - Error in evaluation!(3)\n");
return false; return false;
@ -2360,7 +2383,6 @@ inline bool run_test12()
printf("run_test12() - Error: %s Expression: %s\n", printf("run_test12() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expr_str.c_str()); expr_str.c_str());
return false; return false;
} }
} }
@ -2368,7 +2390,6 @@ inline bool run_test12()
if (T(1.0) != expression.value()) if (T(1.0) != expression.value())
{ {
printf("run_test12() - Error in evaluation! Expression: %s\n",expr_str.c_str()); printf("run_test12() - Error in evaluation! Expression: %s\n",expr_str.c_str());
return false; return false;
} }
} }
@ -2384,7 +2405,7 @@ struct sine_deg : public exprtk::ifunction<T>
inline T operator()(const T& v) inline T operator()(const T& v)
{ {
return std::sin((v * exprtk::details::numeric::constant::pi)/T(180.0)); return std::sin((v * T(exprtk::details::numeric::constant::pi))/T(180.0));
} }
}; };
@ -2395,7 +2416,7 @@ struct cosine_deg : public exprtk::ifunction<T>
inline T operator()(const T& v) inline T operator()(const T& v)
{ {
return std::cos((v * exprtk::details::numeric::constant::pi)/T(180.0)); return std::cos((v * T(exprtk::details::numeric::constant::pi))/T(180.0));
} }
}; };
@ -2452,7 +2473,6 @@ inline bool run_test13()
printf("run_test13() - Error: %s Expression: %s\n", printf("run_test13() - Error: %s Expression: %s\n",
parser.error().c_str(), parser.error().c_str(),
expr_str.c_str()); expr_str.c_str());
return false; return false;
} }
} }
@ -2460,7 +2480,6 @@ inline bool run_test13()
if (T(1.0) != expression.value()) if (T(1.0) != expression.value())
{ {
printf("run_test13() - Error in evaluation! Expression: %s\n",expr_str.c_str()); printf("run_test13() - Error in evaluation! Expression: %s\n",expr_str.c_str());
return false; return false;
} }
} }
@ -2471,33 +2490,36 @@ inline bool run_test13()
int main() int main()
{ {
#define perform_test(Number)\ #define perform_test(Type,Number) \
{ \ { \
exprtk::timer timer; \ exprtk::timer timer; \
timer.start(); \ timer.start(); \
if (!run_test##Number<double>()) \ if (!run_test##Number<Type>()) \
{ \ { \
printf("run_test"#Number" *** FAILED! ***\n"); \ printf("run_test"#Number" ("#Type") *** FAILED! ***\n"); \
return 1; \
} \ } \
else \
{ \
timer.stop(); \ timer.stop(); \
printf("run_test"#Number" - Time: %8.4fsec\n",timer.time()); \ printf("run_test"#Number" ("#Type") - Result: SUCCESS Time: %8.4fsec\n",timer.time()); \
} } \
} \
perform_test(double,00)
perform_test(double,01)
perform_test(double,02)
perform_test(double,03)
perform_test(double,04)
perform_test(double,05)
perform_test(double,06)
perform_test(double,07)
perform_test(double,08)
perform_test(double,09)
perform_test(double,10)
perform_test(double,11)
perform_test(double,12)
perform_test(double,13)
perform_test(00)
perform_test(01)
perform_test(02)
perform_test(03)
perform_test(04)
perform_test(05)
perform_test(06)
perform_test(07)
perform_test(08)
perform_test(09)
perform_test(10)
perform_test(11)
perform_test(12)
perform_test(13)
#undef perform_test #undef perform_test
return 0; return 0;

View File

@ -36,7 +36,8 @@ operations, functions and processes:
(8) Calculus: numerical integration and differentiation (8) Calculus: numerical integration and differentiation
Note: The trigonometry functions assume radians as input. Note 1: Normal mathematical operator precedence is applied (BEDMAS).
Note 2: The trigonometry functions assume radians as input.
@ -123,123 +124,58 @@ correctly optimize such expressions for a given architecture.
+-------------+-------------+ +--------------+------------------+ +-------------+-------------+ +--------------+------------------+
| Prototype | Operation | | Prototype | Operation | | Prototype | Operation | | Prototype | Operation |
+-------------+-------------+ +--------------+------------------+ +-------------+-------------+ +--------------+------------------+
sf00(x,y,z) | (x + y) / z sf35(x,y,z,w) | x + ((y + z) / w) $f00(x,y,z) | (x + y) / z $f46(x,y,z,w) | x + ((y + z) / w)
sf01(x,y,z) | (x + y) * z sf36(x,y,z,w) | x + ((y + z) * w) $f01(x,y,z) | (x + y) * z $f47(x,y,z,w) | x + ((y + z) * w)
sf02(x,y,z) | (x - y) / z sf37(x,y,z,w) | x + ((y - z) / w) $f02(x,y,z) | (x + y) - z $f48(x,y,z,w) | x + ((y - z) / w)
sf03(x,y,z) | (x - y) * z sf38(x,y,z,w) | x + ((y - z) * w) $f03(x,y,z) | (x + y) + z $f49(x,y,z,w) | x + ((y - z) * w)
sf04(x,y,z) | (x * y) + z sf39(x,y,z,w) | x + ((y * z) / w) $f04(x,y,z) | (x - y) / z $f50(x,y,z,w) | x + ((y * z) / w)
sf05(x,y,z) | (x * y) - z sf40(x,y,z,w) | x + ((y * z) * w) $f05(x,y,z) | (x - y) * z $f51(x,y,z,w) | x + ((y * z) * w)
sf06(x,y,z) | (x * y) / z sf41(x,y,z,w) | x + ((y / z) + w) $f06(x,y,z) | (x * y) + z $f52(x,y,z,w) | x + ((y / z) + w)
sf07(x,y,z) | (x * y) * z sf42(x,y,z,w) | x + ((y / z) / w) $f07(x,y,z) | (x * y) - z $f53(x,y,z,w) | x + ((y / z) / w)
sf08(x,y,z) | (x / y) + z sf43(x,y,z,w) | x + ((y / z) * w) $f08(x,y,z) | (x * y) / z $f54(x,y,z,w) | x + ((y / z) * w)
sf09(x,y,z) | (x / y) - z sf44(x,y,z,w) | x - ((y + z) / w) $f09(x,y,z) | (x * y) * z $f55(x,y,z,w) | x - ((y + z) / w)
sf10(x,y,z) | (x / y) / z sf45(x,y,z,w) | x - ((y + z) * w) $f10(x,y,z) | (x / y) + z $f56(x,y,z,w) | x - ((y + z) * w)
sf11(x,y,z) | (x / y) * z sf46(x,y,z,w) | x - ((y - z) / w) $f11(x,y,z) | (x / y) - z $f57(x,y,z,w) | x - ((y - z) / w)
sf12(x,y,z) | x / (y + z) sf47(x,y,z,w) | x - ((y - z) * w) $f12(x,y,z) | (x / y) / z $f58(x,y,z,w) | x - ((y - z) * w)
sf13(x,y,z) | x / (y - z) sf48(x,y,z,w) | x - ((y * z) / w) $f13(x,y,z) | (x / y) * z $f59(x,y,z,w) | x - ((y * z) / w)
sf14(x,y,z) | x / (y * z) sf49(x,y,z,w) | x - ((y * z) * w) $f14(x,y,z) | x / (y + z) $f60(x,y,z,w) | x - ((y * z) * w)
sf15(x,y,z) | x / (y / z) sf50(x,y,z,w) | x - ((y / z) / w) $f15(x,y,z) | x / (y - z) $f61(x,y,z,w) | x - ((y / z) / w)
sf16(x,y,z) | x - (y / z) sf51(x,y,z,w) | x - ((y / z) * w) $f16(x,y,z) | x / (y * z) $f62(x,y,z,w) | x - ((y / z) * w)
sf17(x,y,z) | x - (y / z) sf52(x,y,z,w) | ((x + y) * z) - w $f17(x,y,z) | x / (y / z) $f63(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 $f18(x,y,z) | x * (y + z) $f64(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 $f19(x,y,z) | x * (y - z) $f65(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 $f20(x,y,z) | x * (y * z) $f66(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 $f21(x,y,z) | x * (y / z) $f67(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 $f22(x,y,z) | x - (y / z) $f68(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 $f23(x,y,z) | x - (y / z) $f69(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 $f24(x,y,z) | x - (y * z) $f70(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) $f25(x,y,z) | x + (y * z) $f71(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) $f26(x,y,z) | x + (y / z) $f72(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) $f27(x,y,z) | x + (y + z) $f73(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) $f28(x,y,z) | x + (y - z) $f74(x,y,z,w) | (x * y) - (z / w)
sf29(x,y,z) | x * log10(y)-z sf64(x,y,z,w) | (x / y) + (z / w) $f29(x,y,z) | x * y^2 + z $f75(x,y,z,w) | (x / y) + (z / w)
sf30(x,y,z) | x * sin(y)+z sf65(x,y,z,w) | (x / y) - (z / w) $f30(x,y,z) | x * y^3 + z $f76(x,y,z,w) | (x / y) - (z / w)
sf31(x,y,z) | x * sin(y)-z sf66(x,y,z,w) | (x / y) - (z * w) $f31(x,y,z) | x * y^4 + z $f77(x,y,z,w) | (x / y) - (z * w)
sf32(x,y,z) | x * cos(y)+z sf67(x,y,z,w) | x * y^2 + z * w^2 $f32(x,y,z) | x * y^5 + z $f78(x,y,z,w) | x / (y + (z * w))
sf33(x,y,z) | x * cos(y)-z sf68(x,y,z,w) | x * y^3 + z * w^3 $f33(x,y,z) | x * y^6 + z $f79(x,y,z,w) | x / (y - (z * w))
sf34(x,y,z) | x ? y : z sf69(x,y,z,w) | x * y^4 + z * w^4 $f34(x,y,z) | x * y^7 + z $f80(x,y,z,w) | x * (y + (z * w))
sf70(x,y,z,w) | x * y^5 + z * w^5 $f35(x,y,z) | x * y^8 + z $f81(x,y,z,w) | x * (y - (z * w))
sf71(x,y,z,w) | x * y^6 + z * w^6 $f36(x,y,z) | x * y^9 + z $f82(x,y,z,w) | x * y^2 + z * w^2
sf72(x,y,z,w) | x * y^7 + z * w^7 $f37(x,y,z) | x * log(y)+z $f83(x,y,z,w) | x * y^3 + z * w^3
sf73(x,y,z,w) | x * y^8 + z * w^8 $f38(x,y,z) | x * log(y)-z $f84(x,y,z,w) | x * y^4 + z * w^4
sf74(x,y,z,w) | x * y^9 + z * w^9 $f39(x,y,z) | x * log10(y)+z $f85(x,y,z,w) | x * y^5 + z * w^5
sf75(x,y,z,w) | (x and y) ? z : w $f40(x,y,z) | x * log10(y)-z $f86(x,y,z,w) | x * y^6 + z * w^6
sf76(x,y,z,w) | (x or y) ? z : w $f41(x,y,z) | x * sin(y)+z $f87(x,y,z,w) | x * y^7 + z * w^7
sf77(x,y,z,w) | (x < y) ? z : w $f42(x,y,z) | x * sin(y)-z $f88(x,y,z,w) | x * y^8 + z * w^8
sf78(x,y,z,w) | (x <= y) ? z : w $f43(x,y,z) | x * cos(y)+z $f89(x,y,z,w) | x * y^9 + z * w^9
sf79(x,y,z,w) | (x > y) ? z : w $f44(x,y,z) | x * cos(y)-z $f90(x,y,z,w) | (x and y) ? z : w
sf80(x,y,z,w) | (x >= y) ? z : w $f45(x,y,z) | x ? y : z $f91(x,y,z,w) | (x or y) ? z : w
sf81(x,y,z,w) | (x == y) ? z : w $f92(x,y,z,w) | (x < y) ? z : w
sf82(x,y,z,w) | x*sin(y) + z*cos(w) $f93(x,y,z,w) | (x <= y) ? z : w
$f94(x,y,z,w) | (x > y) ? z : w
$f95(x,y,z,w) | (x >= y) ? z : w
$f96(x,y,z,w) | (x == y) ? z : w
[MACROS] $f97(x,y,z,w) | x*sin(y) + z*cos(w)
ExprTk utilizes certain macros to modify the underlying behaviour of
the parser and the evaluation engine. The following macros are used to
switch off certain capabilities within the ExprTk evaluation engine.
The capabilities are predominantly related to expression optimisations
and the ability to evaluate strings within expressions.
(1) exprtk_disable_string_capabilities
(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
(7) exprtk_enable_all_optimizations
(1) "exprtk_disable_string_capabilities"
If defined, the macro will disable all string processing capabilities.
When defined, if an expression containing a string or string related
action is encountered, a compilation error will be raised by the
parser.
(2) "exprtk_disable_cardinal_pow_optimisation"
If defined, the macro will disable the special case regarding
exponentiation of a variable to an integer constant (where the
constant is <= 60). Defining this variable may be desirable if the
error magnitude of the results using this special case are intolerable
with regards to the precision required. When defined, the pow function
used for all other powers will be invoked.
(3) "exprtk_disable_extended_optimisations"
If defined, the macro will disable the third tier optimisations. This
group of optimisations creates roughly 4K type instantiations. This
large number of type and branch instantiations in one translation unit
may cause some older compilers to crash or not be able to properly
compile ExprTk. If such compiler problems are encountered it is
recommended to test having this particular macro defined. It should
also be noted that some of the third tier optimisations are also
available through the predefined 'special functions', however these
require that expressions utilize them explicitly.
(4) "exprtk_disable_extended_operator_optimizations"
By default most of the mathematical operators are included as part of
the optimisation process. However if this macro is defined, then only
the basic mathematical operators (+,-,*,/,^) will be included.
(5) "exprtk_lean_and_mean"
The default mode of ExprTk is lean and mean. This macro encompasses
both modes [3] and [4].
(6) "exprtk_lean_and_mean_numeric_only"
The mode when this macro is defined, is 'lean and mean' coupled with
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
exchange for a dramatic increase in performance during run-time is
always a worthy undertaking.