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

This commit is contained in:
Arash Partow 2013-04-14 17:01:14 +10:00
parent e44540b0f4
commit 2a810cc9b4
13 changed files with 915 additions and 55 deletions

View File

@ -24,6 +24,15 @@ LINKER_OPT = -L/usr/lib -lstdc++
BUILD_LIST+=exprtk_test
BUILD_LIST+=exprtk_benchmark
BUILD_LIST+=exprtk_simple_example_01
BUILD_LIST+=exprtk_simple_example_02
BUILD_LIST+=exprtk_simple_example_03
BUILD_LIST+=exprtk_simple_example_04
BUILD_LIST+=exprtk_simple_example_05
BUILD_LIST+=exprtk_simple_example_06
BUILD_LIST+=exprtk_simple_example_07
BUILD_LIST+=exprtk_simple_example_08
BUILD_LIST+=exprtk_simple_example_09
all: $(BUILD_LIST)
@ -33,6 +42,33 @@ exprtk_test: exprtk_test.cpp exprtk.hpp
exprtk_benchmark: exprtk_benchmark.cpp exprtk.hpp
$(COMPILER) $(OPTIONS) exprtk_benchmark exprtk_benchmark.cpp $(LINKER_OPT)
exprtk_simple_example_01: exprtk_simple_example_01.cpp exprtk.hpp
$(COMPILER) $(OPTIONS) exprtk_simple_example_01 exprtk_simple_example_01.cpp $(LINKER_OPT)
exprtk_simple_example_02: exprtk_simple_example_02.cpp exprtk.hpp
$(COMPILER) $(OPTIONS) exprtk_simple_example_02 exprtk_simple_example_02.cpp $(LINKER_OPT)
exprtk_simple_example_03: exprtk_simple_example_03.cpp exprtk.hpp
$(COMPILER) $(OPTIONS) exprtk_simple_example_03 exprtk_simple_example_03.cpp $(LINKER_OPT)
exprtk_simple_example_04: exprtk_simple_example_04.cpp exprtk.hpp
$(COMPILER) $(OPTIONS) exprtk_simple_example_04 exprtk_simple_example_04.cpp $(LINKER_OPT)
exprtk_simple_example_05: exprtk_simple_example_05.cpp exprtk.hpp
$(COMPILER) $(OPTIONS) exprtk_simple_example_05 exprtk_simple_example_05.cpp $(LINKER_OPT)
exprtk_simple_example_06: exprtk_simple_example_06.cpp exprtk.hpp
$(COMPILER) $(OPTIONS) exprtk_simple_example_06 exprtk_simple_example_06.cpp $(LINKER_OPT)
exprtk_simple_example_07: exprtk_simple_example_07.cpp exprtk.hpp
$(COMPILER) $(OPTIONS) exprtk_simple_example_07 exprtk_simple_example_07.cpp $(LINKER_OPT)
exprtk_simple_example_08: exprtk_simple_example_08.cpp exprtk.hpp
$(COMPILER) $(OPTIONS) exprtk_simple_example_08 exprtk_simple_example_08.cpp $(LINKER_OPT)
exprtk_simple_example_09: exprtk_simple_example_09.cpp exprtk.hpp
$(COMPILER) $(OPTIONS) exprtk_simple_example_09 exprtk_simple_example_09.cpp $(LINKER_OPT)
pgo: exprtk_test.cpp exprtk_benchmark.cpp exprtk.hpp
$(COMPILER) $(BASE_OPTIONS) -O3 -march=native -fprofile-generate -o exprtk_benchmark exprtk_benchmark.cpp $(LINKER_OPT)
./exprtk_benchmark
@ -41,10 +77,28 @@ pgo: exprtk_test.cpp exprtk_benchmark.cpp exprtk.hpp
strip_bin:
strip -s exprtk_test
strip -s exprtk_benchmark
strip -s exprtk_simple_example_01
strip -s exprtk_simple_example_02
strip -s exprtk_simple_example_03
strip -s exprtk_simple_example_04
strip -s exprtk_simple_example_05
strip -s exprtk_simple_example_06
strip -s exprtk_simple_example_07
strip -s exprtk_simple_example_08
strip -s exprtk_simple_example_09
valgrind_check:
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_test
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_benchmark
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_01
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_02
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_03
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_04
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_05
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_06
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_07
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_08
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_09
clean:
rm -f core.* *~ *.o *.bak *stackdump gmon.out *.gcda *.gcno *.gcnor *.gch

View File

@ -121,6 +121,7 @@ namespace exprtk
('.' != c) &&
('_' != c) &&
('$' != c) &&
('~' != c) &&
('\'' != c);
}
@ -1674,6 +1675,14 @@ namespace exprtk
return;
}
#endif
else if ('~' == (*s_itr_))
{
token_t t;
t.set_symbol(s_itr_,s_itr_ + 1,base_itr_);
token_list_.push_back(t);
++s_itr_;
return;
}
else
{
token_t t;
@ -2768,7 +2777,7 @@ namespace exprtk
e_r2d , e_d2r , e_d2g , e_g2d ,
e_hypot , e_notl , e_erf , e_erfc ,
e_frac , e_trunc , e_assign , e_in ,
e_like , e_ilike ,
e_like , e_ilike , e_multi ,
// Do not add new functions/operators after this point.
e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003,
@ -5591,6 +5600,84 @@ namespace exprtk
}
};
template <typename T>
struct vararg_multi_op : public opr_base<T>
{
typedef typename opr_base<T>::Type Type;
template <typename Type,
typename Allocator,
template <typename,typename> class Sequence>
static inline T process(const Sequence<Type,Allocator>& arglist)
{
if (arglist.size() > 5)
{
if (arglist.empty())
return std::numeric_limits<T>::quiet_NaN();
else
{
for (std::size_t i = 0; i < (arglist.size() - 1); ++i)
{
value(arglist[i]);
}
}
return value(arglist.back());
}
else
{
switch (arglist.size())
{
case 1 : return process_1(arglist);
case 2 : return process_2(arglist);
case 3 : return process_3(arglist);
case 4 : return process_4(arglist);
case 5 : return process_5(arglist);
default : return std::numeric_limits<T>::quiet_NaN();
}
}
}
template <typename Sequence>
static inline T process_1(const Sequence& arglist)
{
return value(arglist[0]);
}
template <typename Sequence>
static inline T process_2(const Sequence& arglist)
{
value(arglist[0]);
return value(arglist[1]);
}
template <typename Sequence>
static inline T process_3(const Sequence& arglist)
{
value(arglist[0]);
value(arglist[1]);
return value(arglist[2]);
}
template <typename Sequence>
static inline T process_4(const Sequence& arglist)
{
value(arglist[0]);
value(arglist[1]);
value(arglist[2]);
return value(arglist[3]);
}
template <typename Sequence>
static inline T process_5(const Sequence& arglist)
{
value(arglist[0]);
value(arglist[1]);
value(arglist[2]);
value(arglist[3]);
return value(arglist[4]);
}
};
template <typename T>
class vov_base_node : public expression_node<T>
{
@ -9621,6 +9708,7 @@ namespace exprtk
static const std::string s_max = "max" ;
static const std::string s_mand = "mand";
static const std::string s_mor = "mor" ;
static const std::string s_multi = "~" ;
return
(
details::imatch(symbol,s_sum ) ||
@ -9629,7 +9717,8 @@ namespace exprtk
details::imatch(symbol,s_min ) ||
details::imatch(symbol,s_max ) ||
details::imatch(symbol,s_mand ) ||
details::imatch(symbol,s_mor )
details::imatch(symbol,s_mor ) ||
details::imatch(symbol,s_multi)
);
}
@ -10290,6 +10379,7 @@ namespace exprtk
else if (details::imatch(symbol,"max" )) opt_type = details::e_max;
else if (details::imatch(symbol,"mand")) opt_type = details::e_mand;
else if (details::imatch(symbol,"mor" )) opt_type = details::e_mor;
else if (details::imatch(symbol,"~" )) opt_type = details::e_multi;
else
{
set_error(
@ -11686,6 +11776,7 @@ namespace exprtk
case_stmt(details::e_max, details::vararg_max_op )
case_stmt(details::e_mand, details::vararg_mand_op )
case_stmt(details::e_mor, details::vararg_mor_op )
case_stmt(details::e_multi,details::vararg_multi_op)
#undef case_stmt
default : return error_node();
}
@ -11708,6 +11799,7 @@ namespace exprtk
case_stmt(details::e_max, details::vararg_max_op )
case_stmt(details::e_mand, details::vararg_mand_op )
case_stmt(details::e_mor, details::vararg_mor_op )
case_stmt(details::e_multi,details::vararg_multi_op)
#undef case_stmt
default : return error_node();
}
@ -11736,6 +11828,7 @@ namespace exprtk
case_stmt(details::e_max, details::vararg_max_op )
case_stmt(details::e_mand, details::vararg_mand_op )
case_stmt(details::e_mor, details::vararg_mor_op )
case_stmt(details::e_multi,details::vararg_multi_op)
#undef case_stmt
default : return error_node();
}

View File

@ -0,0 +1,50 @@
/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 1 *
* Author: Arash Partow (1999-2013) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the Common Public License. *
* http://www.opensource.org/licenses/cpl1.0.php *
* *
**************************************************************
*/
#include <cstdio>
#include <string>
#include "exprtk.hpp"
template<typename T>
void trig_function()
{
std::string expression_string = "clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)";
T x;
exprtk::symbol_table<T> symbol_table;
symbol_table.add_variable("x",x);
symbol_table.add_constants();
exprtk::expression<T> expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
parser.compile(expression_string,expression);
for (x = T(-5.0); x <= T(+5.0); x += 0.001)
{
T y = expression.value();
printf("%19.15f\t%19.15f\n",x,y);
}
}
int main()
{
trig_function<double>();
return 0;
}

View File

@ -0,0 +1,64 @@
/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 2 *
* Author: Arash Partow (1999-2013) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the Common Public License. *
* http://www.opensource.org/licenses/cpl1.0.php *
* *
**************************************************************
*/
#include <cstdio>
#include <string>
#include "exprtk.hpp"
template<typename T>
void square_wave()
{
std::string expr_string = "a*(4/pi)*"
"((1 /1)*sin( 2*pi*f*t)+(1 /3)*sin( 6*pi*f*t)+"
" (1 /5)*sin(10*pi*f*t)+(1 /7)*sin(14*pi*f*t)+"
" (1 /9)*sin(18*pi*f*t)+(1/11)*sin(22*pi*f*t)+"
" (1/13)*sin(26*pi*f*t)+(1/15)*sin(30*pi*f*t)+"
" (1/17)*sin(34*pi*f*t)+(1/19)*sin(38*pi*f*t)+"
" (1/21)*sin(42*pi*f*t)+(1/23)*sin(46*pi*f*t)+"
" (1/25)*sin(50*pi*f*t)+(1/27)*sin(54*pi*f*t))";
static const T pi = T(3.14159265358979323846);
T f = pi/10.0;
T t = T(0.0);
T a = T(10.0);
exprtk::symbol_table<T> symbol_table;
symbol_table.add_variable("f",f);
symbol_table.add_variable("t",t);
symbol_table.add_variable("a",a);
symbol_table.add_constants();
exprtk::expression<T> expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
parser.compile(expr_string,expression);
const T delta = (4.0*pi)/1000.0;
for (t = -2.0*pi; t <= +2.0*pi; t+=delta)
{
T result = expression.value();
printf("%19.15f\t%19.15f\n",t,result);
}
}
int main()
{
square_wave<double>();
return 0;
}

View File

@ -0,0 +1,52 @@
/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 3 *
* Author: Arash Partow (1999-2013) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the Common Public License. *
* http://www.opensource.org/licenses/cpl1.0.php *
* *
**************************************************************
*/
#include <cstdio>
#include <string>
#include "exprtk.hpp"
template<typename T>
void polynomial()
{
std::string expression_string = "25x^5 - 35x^4 - 15x^3 + 40x^2 - 15x + 1";
T r0 = T(0.0);
T r1 = T(1.0);
T x = T(0.0);
exprtk::symbol_table<T> symbol_table;
symbol_table.add_variable("x",x);
exprtk::expression<T> expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
parser.compile(expression_string,expression);
const T delta = T(1/100.0);
for (x = r0; x <= r1; x += delta)
{
printf("%19.15f\t%19.15f\n",x,expression.value());
}
}
int main()
{
polynomial<double>();
return 0;
}

View File

@ -0,0 +1,87 @@
/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 4 *
* Author: Arash Partow (1999-2013) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the Common Public License. *
* http://www.opensource.org/licenses/cpl1.0.php *
* *
**************************************************************
*/
#include <cstdio>
#include <string>
#include "exprtk.hpp"
template <typename T>
void fibonacci()
{
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
typedef exprtk::function_compositor<T> compositor_t;
compositor_t compositor;
compositor
.add("fibonacci_impl",
"switch "
"{ "
" case x == 0 : 0; "
" case x == 1 : 1; "
" default : "
" while (~(x := (x - 1)) > 0)"
" {~ "
" ( "
" w := z, "
" z := z + y, "
" y := w, "
" z "
" ) "
" }; "
"} ",
"x","y","z","w");
compositor
.add("fibonacci",
"fibonacci_impl(x,0,1,0)",
"x");
T x = T(0);
symbol_table_t& symbol_table = compositor.symbol_table();
symbol_table.add_constants();
symbol_table.add_variable("x",x);
std::string expression_str = "fibonacci(x)";
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
parser.compile(expression_str,expression);
for (std::size_t i = 0; i < 40; ++i)
{
x = i;
T result = expression.value();
printf("fibonacci(%3d) = %10.0f\n",
static_cast<unsigned int>(i),
result);
}
}
int main()
{
fibonacci<double>();
return 0;
}

View File

@ -0,0 +1,66 @@
/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 5 *
* Author: Arash Partow (1999-2013) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the Common Public License. *
* http://www.opensource.org/licenses/cpl1.0.php *
* *
**************************************************************
*/
#include <cstdio>
#include <string>
#include "exprtk.hpp"
template<typename T>
struct myfunc : public exprtk::ifunction<T>
{
myfunc()
: exprtk::ifunction<T>(2)
{}
inline T operator()(const T& v1, const T& v2)
{
return T(1) + (v1 * v2) / T(3);
}
};
template<typename T>
void custom_function()
{
typedef exprtk::expression<T> expression_t;
std::string expression_string = "myfunc(sin(x*pi),y/2)";
T x = T(1.0);
T y = T(2.0);
myfunc<T> mf;
exprtk::symbol_table<T> symbol_table;
symbol_table.add_variable("x",x);
symbol_table.add_variable("y",y);
symbol_table.add_function("myfunc",mf);
symbol_table.add_constants();
expression_t expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
parser.compile(expression_string,expression);
T result = expression.value();
printf("Result: %10.5f\n",result);
}
int main()
{
custom_function<double>();
return 0;
}

View File

@ -0,0 +1,63 @@
/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 6 *
* Author: Arash Partow (1999-2013) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the Common Public License. *
* http://www.opensource.org/licenses/cpl1.0.php *
* *
**************************************************************
*/
#include <cstdio>
#include <string>
#include "exprtk.hpp"
template<typename T>
void vector_function()
{
typedef exprtk::expression<T> expression_t;
std::string expression_string = "z := (3sin(x) + 2log(y))";
const std::size_t vec_size = 5;
T x[vec_size] = { 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 z[vec_size] = { T(0.0), T(0.0), T(0.0), T(0.0), T(0.0) };
T x_ = x[0];
T y_ = y[0];
T z_ = z[0];
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.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
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();
x[i] = x_; y[i] = y_; z[i] = z_;
}
}
int main()
{
vector_function<double>();
return 0;
}

View File

@ -0,0 +1,67 @@
/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 7 *
* Author: Arash Partow (1999-2013) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the Common Public License. *
* http://www.opensource.org/licenses/cpl1.0.php *
* *
**************************************************************
*/
#include <cstdio>
#include <string>
#include "exprtk.hpp"
template <typename T>
void logic()
{
typedef exprtk::expression<T> expression_t;
std::string expression_string = "not(A and B) or C";
exprtk::symbol_table<T> symbol_table;
symbol_table.create_variable("A");
symbol_table.create_variable("B");
symbol_table.create_variable("C");
expression_t expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
parser.compile(expression_string,expression);
printf(" # | A | B | C | %s\n"
"---+---+---+---+-%s\n",
expression_string.c_str(),
std::string(expression_string.size(),'-').c_str());
for (int i = 0; i < 8; ++i)
{
symbol_table.get_variable("A")->ref() = T(i & 0x01 ? 1 : 0);
symbol_table.get_variable("B")->ref() = T(i & 0x02 ? 1 : 0);
symbol_table.get_variable("C")->ref() = T(i & 0x04 ? 1 : 0);
int result = static_cast<int>(expression.value());
printf(" %d | %d | %d | %d | %d \n",
i,
static_cast<int>(symbol_table.get_variable("A")->value()),
static_cast<int>(symbol_table.get_variable("B")->value()),
static_cast<int>(symbol_table.get_variable("C")->value()),
result);
}
}
int main()
{
logic<double>();
return 0;
}

View File

@ -0,0 +1,81 @@
/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 8 *
* Author: Arash Partow (1999-2013) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the Common Public License. *
* http://www.opensource.org/licenses/cpl1.0.php *
* *
**************************************************************
*/
#include <cstdio>
#include <string>
#include "exprtk.hpp"
template <typename T>
void composite()
{
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
typedef exprtk::parser_error::type error_t;
typedef exprtk::function_compositor<T> compositor_t;
compositor_t compositor;
T x = T(1);
T y = T(2);
symbol_table_t& symbol_table = compositor.symbol_table();
symbol_table.add_constants();
symbol_table.add_variable("x",x);
symbol_table.add_variable("y",y);
compositor.add("f","sin(x/pi)","x"); // f(x) = sin(x/pi)
compositor.add("g","3*[f(x)+f(y)]","x","y"); // g(x,y) = 3[f(x)+f(y)]
std::string expression_string = "g(1 + f(x),f(y) / 2)";
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
if (!parser.compile(expression_string,expression))
{
printf("Error: %s\tExpression: %s\n",
parser.error().c_str(),
expression_string.c_str());
for (std::size_t i = 0; i < parser.error_count(); ++i)
{
error_t error = parser.get_error(i);
printf("Error: %02d Position: %02d Type: [%14s] Msg: %s\tExpression: %s\n",
static_cast<unsigned int>(i),
static_cast<unsigned int>(error.token.position),
exprtk::parser_error::to_str(error.mode).c_str(),
error.diagnostic.c_str(),
expression_string.c_str());
}
return;
}
T result = expression.value();
printf("%s = %e\n", expression_string.c_str(), result);
}
int main()
{
composite<double>();
return 0;
}

View File

@ -0,0 +1,136 @@
/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 9 *
* Author: Arash Partow (1999-2012) *
* URL: http://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the Common Public License. *
* http://www.opensource.org/licenses/cpl1.0.php *
* *
**************************************************************
*/
#include <cstdio>
#include <string>
#include "exprtk.hpp"
template <typename T>
void primes()
{
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
typedef exprtk::function_compositor<T> compositor_t;
T x = T(0);
exprtk::symbol_table<T> symbol_table;
symbol_table.add_constants();
symbol_table.add_variable("x",x);
compositor_t compositor(symbol_table);
//Mode 1 - if statement based
compositor
.add("is_prime_impl1",
"if(y == 1,true, "
" if(0 == (x % y),false, "
" is_prime_impl1(x,y-1)))",
"x","y");
compositor
.add("is_prime1",
"if(frac(x) != 0, false, "
" if(x <= 0, false, "
" is_prime_impl1(x,min(x - 1,trunc(sqrt(x)) + 1))))",
"x");
//Mode 2 - switch statement based
compositor
.add("is_prime_impl2",
"switch "
"{ "
" case y == 1 : true; "
" case (x % y) == 0 : false; "
" default : is_prime_impl2(x,y - 1);"
"} ",
"x","y");
compositor
.add("is_prime2",
"switch "
"{ "
" case x <= 0 : false; "
" case frac(x) != 0 : false; "
" default : is_prime_impl2(x,min(x - 1,trunc(sqrt(x)) + 1));"
"} ",
"x");
//Mode 3 - switch statement and while-loop based
compositor
.add("is_prime_impl3",
"while (y > 0) "
"{ "
" switch "
" { "
" case y == 1 : ~(y := 0,true); "
" case (x % y) == 0 : ~(y := 0,false);"
" default : y := y - 1; "
" } "
"} ",
"x","y");
compositor
.add("is_prime3",
"switch "
"{ "
" case x <= 0 : false; "
" case frac(x) != 0 : false; "
" default : is_prime_impl3(x,min(x - 1,trunc(sqrt(x)) + 1));"
"} ",
"x");
std::string expression_str1 = "is_prime1(x)";
std::string expression_str2 = "is_prime2(x)";
std::string expression_str3 = "is_prime3(x)";
expression_t expression1;
expression_t expression2;
expression_t expression3;
expression1.register_symbol_table(symbol_table);
expression2.register_symbol_table(symbol_table);
expression3.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
parser.compile(expression_str1,expression1);
parser.compile(expression_str2,expression2);
parser.compile(expression_str3,expression3);
for (std::size_t i = 0; i < 100; ++i)
{
x = i;
T result1 = expression1.value();
T result2 = expression2.value();
T result3 = expression3.value();
printf("%03d Result1: %c Result2: %c Result3: %c\n",
static_cast<unsigned int>(i),
(result1 == T(1)) ? 'T' : 'F',
(result2 == T(1)) ? 'T' : 'F',
(result3 == T(1)) ? 'T' : 'F');
}
}
int main()
{
primes<double>();
return 0;
}

View File

@ -3578,8 +3578,8 @@ inline bool run_test19()
"{ "
" switch "
" { "
" case y == 1 : true + (y := 0);"
" case (x % y) == 0 : false + (y := 0);"
" case y == 1 : ~(y := 0,true); "
" case (x % y) == 0 : ~(y := 0,false);"
" default : y := y - 1; "
" } "
"} ",
@ -3671,7 +3671,7 @@ inline bool run_test19()
{
printf("run_test19() - Error in evaluation! (3) Results don't match! Prime: %d "
"Expression1: %s Expression2: %s Expression3: %s\n",
prime_list[i],
static_cast<unsigned int>(prime_list[i]),
expression_str1.c_str(),
expression_str2.c_str(),
expression_str3.c_str());
@ -3682,7 +3682,7 @@ inline bool run_test19()
{
printf("run_test19() - Error in evaluation! (3) Prime: %d "
"Expression1: %s Expression2: %s Expression3: %s\n",
(int)prime_list[i],
static_cast<unsigned int>(prime_list[i]),
expression_str1.c_str(),
expression_str2.c_str(),
expression_str3.c_str());
@ -3716,17 +3716,44 @@ inline bool run_test19()
"} ",
"x");
compositor
.add("fibonacci_impl3",
"switch "
"{ "
" case x == 0 : 0; "
" case x == 1 : 1; "
" default : while (~(x := (x - 1)) > 0)"
" {~ "
" ( "
" w := z, "
" z := z + y, "
" y := w, "
" z "
" ) "
" }; "
"} ",
"x","y","z","w");
compositor
.add("fibonacci3",
"fibonacci_impl3(x,0,1,0)",
"x");
exprtk::symbol_table<T>& symbol_table = compositor.symbol_table();
symbol_table.add_constants();
symbol_table.add_variable("x",x);
std::string expression_str1 = "fibonacci1(x)";
std::string expression_str2 = "fibonacci2(x)";
std::string expression_str3 = "fibonacci3(x)";
expression_t expression1;
expression_t expression2;
expression_t expression3;
expression1.register_symbol_table(symbol_table);
expression2.register_symbol_table(symbol_table);
expression3.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
@ -3746,6 +3773,14 @@ inline bool run_test19()
return false;
}
if (!parser.compile(expression_str3,expression3))
{
printf("run_test19() - Error: %s Expression3: %s\n",
parser.error().c_str(),
expression_str3.c_str());
return false;
}
bool failure = false;
const std::size_t fibonacci_list[] =
@ -3766,22 +3801,29 @@ inline bool run_test19()
x = i;
T result1 = expression1.value();
T result2 = expression2.value();
if (result1 != result2)
T result3 = expression3.value();
if ((result1 != result2) || (result1 != result3))
{
printf("run_test19() - Error in evaluation! (3) Results don't match! Prime: %d Expression1: %s Expression2: %s\n",
fibonacci_list[i],
printf("run_test19() - Error in evaluation! (3) Results don't match! fibonacci(%d) = %d "
"Expression1: %s Expression2: %s Expression3: %s\n",
static_cast<unsigned int>(i),
static_cast<unsigned int>(fibonacci_list[i]),
expression_str1.c_str(),
expression_str2.c_str());
expression_str2.c_str(),
expression_str3.c_str());
failure = true;
}
if (fibonacci_list[i] != expression1.value())
{
printf("run_test19() - Error in evaluation! (4) fibonacci(%d) = %d Expression1: %s Expression2: %s\n",
i,
fibonacci_list[i],
printf("run_test19() - Error in evaluation! (4) fibonacci(%d) = %d "
"Expression1: %s Expression2: %s Expression3: %s\n",
static_cast<unsigned int>(i),
static_cast<unsigned int>(fibonacci_list[i]),
expression_str1.c_str(),
expression_str2.c_str());
expression_str2.c_str(),
expression_str3.c_str());
failure = true;
}
}

View File

@ -276,6 +276,11 @@ include path (e.g: /usr/include/).
+-----------+--------------------------------------------------------+
| trunc | Integer portion of x |
+-----------+--------------------------------------------------------+
| ~ | Evaluate each sub-expression, then return as the result|
| | the value of the last sub-expression. This is known as |
| | multiple sequence point evaluation. |
| | (eg: ~(x+1,y/z,abs(y^3),sin(w/u)) == (sin(w/u))) |
+-----------+--------------------------------------------------------+
(4) Trigonometry Functions
+-----------+--------------------------------------------------------+