Skip to content

Commit

Permalink
C++ Mathematical Expression Library (ExprTk) http://www.partow.net/pr…
Browse files Browse the repository at this point in the history
  • Loading branch information
ArashPartow committed Apr 14, 2013
1 parent e44540b commit 2a810cc
Show file tree
Hide file tree
Showing 13 changed files with 915 additions and 55 deletions.
54 changes: 54 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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
Expand All @@ -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
165 changes: 129 additions & 36 deletions exprtk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ namespace exprtk
('.' != c) &&
('_' != c) &&
('$' != c) &&
('~' != c) &&
('\'' != c);
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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>
{
Expand Down Expand Up @@ -9614,22 +9701,24 @@ namespace exprtk

inline bool valid_vararg_operation(const std::string& symbol)
{
static const std::string s_sum = "sum" ;
static const std::string s_mul = "mul" ;
static const std::string s_avg = "avg" ;
static const std::string s_min = "min" ;
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_sum = "sum" ;
static const std::string s_mul = "mul" ;
static const std::string s_avg = "avg" ;
static const std::string s_min = "min" ;
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 ) ||
details::imatch(symbol,s_mul ) ||
details::imatch(symbol,s_avg ) ||
details::imatch(symbol,s_min ) ||
details::imatch(symbol,s_max ) ||
details::imatch(symbol,s_mand) ||
details::imatch(symbol,s_mor )
details::imatch(symbol,s_sum ) ||
details::imatch(symbol,s_mul ) ||
details::imatch(symbol,s_avg ) ||
details::imatch(symbol,s_min ) ||
details::imatch(symbol,s_max ) ||
details::imatch(symbol,s_mand ) ||
details::imatch(symbol,s_mor ) ||
details::imatch(symbol,s_multi)
);
}

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -11679,13 +11769,14 @@ namespace exprtk
switch (operation)
{
#define case_stmt(op0,op1) case op0 : temp_node = node_allocator_->allocate<details::vararg_node<Type,op1<Type> > >(arglist); break;
case_stmt(details::e_sum, details::vararg_add_op )
case_stmt(details::e_prod, details::vararg_mul_op )
case_stmt(details::e_avg, details::vararg_avg_op )
case_stmt(details::e_min, details::vararg_min_op )
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_sum, details::vararg_add_op )
case_stmt(details::e_prod, details::vararg_mul_op )
case_stmt(details::e_avg, details::vararg_avg_op )
case_stmt(details::e_min, details::vararg_min_op )
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();
}
Expand All @@ -11701,13 +11792,14 @@ namespace exprtk
switch (operation)
{
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<details::vararg_varnode<Type,op1<Type> > >(arglist);
case_stmt(details::e_sum, details::vararg_add_op )
case_stmt(details::e_prod, details::vararg_mul_op )
case_stmt(details::e_avg, details::vararg_avg_op )
case_stmt(details::e_min, details::vararg_min_op )
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_sum, details::vararg_add_op )
case_stmt(details::e_prod, details::vararg_mul_op )
case_stmt(details::e_avg, details::vararg_avg_op )
case_stmt(details::e_min, details::vararg_min_op )
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();
}
Expand All @@ -11729,13 +11821,14 @@ namespace exprtk
switch (operation)
{
#define case_stmt(op0,op1) case op0 : return node_allocator_->allocate<details::vararg_node<Type,op1<Type> > >(arglist);
case_stmt(details::e_sum, details::vararg_add_op )
case_stmt(details::e_prod, details::vararg_mul_op )
case_stmt(details::e_avg, details::vararg_avg_op )
case_stmt(details::e_min, details::vararg_min_op )
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_sum, details::vararg_add_op )
case_stmt(details::e_prod, details::vararg_mul_op )
case_stmt(details::e_avg, details::vararg_avg_op )
case_stmt(details::e_min, details::vararg_min_op )
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();
}
Expand Down
50 changes: 50 additions & 0 deletions exprtk_simple_example_01.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
Loading

0 comments on commit 2a810cc

Please sign in to comment.