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

This commit is contained in:
Arash Partow 2016-08-15 09:08:14 +10:00
parent 26ec96afbf
commit 79a3a265ec
5 changed files with 681 additions and 168 deletions

File diff suppressed because it is too large Load Diff

View File

@ -48,9 +48,9 @@ void logic()
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);
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());

View File

@ -32,9 +32,9 @@ void black_scholes_merton_model()
" var d1 := (log(s / x) + (r + v^2 / 2) * t) / (v * sqrt(t)); "
" var d2 := d1 - v * sqrt(t); "
" "
" if(callput_flag == 'call') "
" if (callput_flag == 'call') "
" s * ncdf(d1) - x * e^(-r * t) * ncdf(d2); "
" else if(callput_flag == 'put') "
" else if (callput_flag == 'put') "
" x * e^(-r * t) * ncdf(-d2) - s * ncdf(-d1); "
" ";
@ -66,6 +66,7 @@ void black_scholes_merton_model()
{
callput_flag = "call";
T bsm = expression.value();
printf("BSM(%s,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f) = %10.6f\n",
@ -76,6 +77,7 @@ void black_scholes_merton_model()
{
callput_flag = "put";
T bsm = expression.value();
printf("BSM(%s,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f) = %10.6f\n",

View File

@ -1193,7 +1193,7 @@ inline bool run_test00()
template <typename T>
struct test_xy
{
test_xy(std::string e, const T& v0, const T& v1, const T& r)
test_xy(const std::string& e, const T& v0, const T& v1, const T& r)
: expr(e),
x(v0),
y(v1),
@ -1209,7 +1209,7 @@ struct test_xy
template <typename T>
struct test_xyzw
{
test_xyzw(std::string e, const T& v0, const T& v1, const T& v2, const T& v3, const T& r)
test_xyzw(const std::string& e, const T& v0, const T& v1, const T& v2, const T& v3, const T& r)
: expr(e),
x(v0),
y(v1),
@ -1850,7 +1850,7 @@ inline bool run_test01()
template <typename T>
struct test_ab
{
test_ab(std::string e, const std::string& v0, const std::string& v1, const T& r)
test_ab(const std::string& e, const std::string& v0, const std::string& v1, const T& r)
: expr(e),
a(v0),
b(v1),
@ -5341,6 +5341,35 @@ struct rem_space_and_uppercase : public exprtk::igeneric_function<T>
}
};
template <typename T>
struct vararg_func : public exprtk::igeneric_function<T>
{
typedef typename exprtk::igeneric_function<T>::parameter_list_t
parameter_list_t;
typedef typename exprtk::igeneric_function<T>::generic_type
generic_type;
typedef typename generic_type::scalar_view scalar_t;
typedef typename generic_type::vector_view vector_t;
vararg_func()
: exprtk::igeneric_function<T>("Z|T*|V")
{}
inline T operator()(const std::size_t& ps_index, parameter_list_t /*arglist*/)
{
switch (ps_index)
{ // Overload resolution:
case 0 : return T(0); // Z - Zero arguments
case 1 : return T(1); // T* - One or more scalars
case 2 : return T(2); // V - One vector
default : return std::numeric_limits<T>::quiet_NaN();
}
}
};
template <typename T>
inline bool run_test18()
{
@ -5868,7 +5897,7 @@ inline bool run_test18()
if (!parser.compile(program,expression))
{
printf("Error: %s\tExpression: %s\n",
printf("run_test18() - Error: %s\tExpression: %s\n",
parser.error().c_str(),
program.c_str());
@ -5931,6 +5960,77 @@ inline bool run_test18()
return false;
}
{
bool failure = false;
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
symbol_table_t symbol_table;
T v[4] = {T(5), T(6), T(7), T(8)};
symbol_table.add_vector("v",v);
vararg_func<T> vaf;
symbol_table.add_function("vararg_func",vaf);
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
std::string programs[] =
{
"equal(0,vararg_func())",
"equal(1,vararg_func() + 1)",
"equal(1,1 + vararg_func())",
"equal(1,vararg_func + 1)",
"equal(1,1 + vararg_func)",
"equal(0,vararg_func() + vararg_func)",
"equal(0,vararg_func + vararg_func())",
"equal(1,vararg_func + vararg_func(1))",
"equal(1,vararg_func + vararg_func(1,2))",
"equal(2,vararg_func + vararg_func(v))",
"equal(1,vararg_func() + vararg_func(1))",
"equal(1,vararg_func() + vararg_func(1,2))",
"equal(2,vararg_func() + vararg_func(v))",
"equal(2,vararg_func(v))",
"equal(1,vararg_func(1))",
"equal(1,vararg_func(1,2,3))",
"equal(1,vararg_func(5,6,7,8))",
"equal(5,vararg_func(v) + 3)",
"equal(5,vararg_func(1) + 4)",
"equal(6,vararg_func(1,2,3) + 5)",
"equal(7,vararg_func(5,6,7,8) + 6)"
};
static const std::size_t programs_size = sizeof(programs) / sizeof(std::string);
for (std::size_t i = 0; i < programs_size; ++i)
{
if (!parser.compile(programs[i],expression))
{
printf("run_test18() - Error: %s\tExpression: %s\n",
parser.error().c_str(),
programs[i].c_str());
failure = true;
}
else if (T(1) != expression.value())
{
printf("run_test18() - Error in evaluation! (5) Expression: %s\n",
programs[i].c_str());
failure = true;
}
}
if (failure)
return false;
}
return true;
}

View File

@ -1334,23 +1334,23 @@ embedded into the expression.
There are five types of function interface:
+---+----------------------+-------------+
| # | Name | Return Type |
+---+----------------------+-------------+
| 1 | ifunction | Scalar |
| 2 | ivararg_function | Scalar |
| 3 | igeneric_function | Scalar |
| 4 | igeneric_function II | String |
| 5 | function_compositor | Scalar |
+---+----------------------+-------------+
+---+----------------------+-------------+----------------------+
| # | Name | Return Type | Input Types |
+---+----------------------+-------------+----------------------+
| 1 | ifunction | Scalar | Scalar |
| 2 | ivararg_function | Scalar | Scalar |
| 3 | igeneric_function | Scalar | Scalar,Vector,String |
| 4 | igeneric_function II | String | Scalar,Vector,String |
| 5 | function_compositor | Scalar | Scalar |
+---+----------------------+-------------+----------------------+
(1) ifunction
This interface supports zero to 20 input parameters. The usage
requires a custom function be derived from ifunction and to override
one of the 21 function operators. As part of the constructor the
custom function will define how many parameters it expects to handle.
The following example defines a 3 parameter function called 'foo':
This interface supports zero to 20 input parameters of only the scalar
type (numbers). The usage requires a custom function be derived from
ifunction and to override one of the 21 function operators. As part of
the constructor the custom function will define how many parameters it
expects to handle. The following example defines a 3 parameter
function called 'foo':
template <typename T>
struct foo : public exprtk::ifunction<T>
@ -1366,8 +1366,8 @@ The following example defines a 3 parameter function called 'foo':
(2) ivararg_function
This interface supports a variable number of arguments as input into
the function. The function operator interface uses a std::vector
This interface supports a variable number of scalar arguments as input
into the function. The function operator interface uses a std::vector
specialized upon type T to facilitate parameter passing. The following
example defines a vararg function called 'boo':
@ -1504,12 +1504,13 @@ listing of said characters and their meanings:
(1) T - Scalar
(2) V - Vector
(3) S - String
(4) ? - Any type (Scalar, Vector or String)
(5) * - Wildcard operator
(6) | - Parameter sequence delimiter
(4) Z - Zero or no parameters
(5) ? - Any type (Scalar, Vector or String)
(6) * - Wildcard operator
(7) | - Parameter sequence delimiter
No other characters other than the six denoted above may be included
No other characters other than the seven denoted above may be included
in the parameter sequence definition. If any such invalid characters
do exist, registration of the associated generic function to a symbol
table ('add_function' method) will fail. If the parameter sequence is
@ -1545,6 +1546,12 @@ parameters in the following sequence:
(3) Scalar
(4) Scalar
Note: The 'Z' or no parameter option may not be used in conjunction
with any other type option in a parameter sequence. When incorporated
in the parameter sequence list, the no parameter option indicates that
the function may be invoked without any parameters being passed. For
more information refer to the section: 'Zero Parameter Functions'
(4) igeneric_function II
This interface is identical to the igeneric_function, in that in can
@ -1851,6 +1858,11 @@ carried out:
{ ... }
};
Note: For the igeneric_function type, there also needs to be a 'Z'
parameter sequence defined inorder for the zero parameter trait to
properly take effect otherwise a compilation error will occur.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[16 - EXPRESSION DEPENDENTS]
@ -2822,6 +2834,7 @@ the ExprTk header. The defines are as follows:
(4) exprtk_disable_sc_andor
(5) exprtk_disable_enhanced_features
(6) exprtk_disable_string_capabilities
(7) exprtk_disable_superscalar_unroll
(1) exprtk_enable_debugging
@ -2854,6 +2867,14 @@ This define will disable all string processing capabilities. Any
expression that contains a string or string related syntax will result
in a compilation failure.
(7) exprtk_disable_superscalar_unroll
This define will set the loop unroll batch size to 4 operations per
loop instead of the default 8 operations. This define is used in
operations that involve vectors and aggregations over vectors. When
targeting non-superscalar architectures, it may be recommended to
build using this particular option if efficiency of evaluations is of
concern.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[23 - FILES]