49 #include "../utility/utility.h"
50 #include "../utility/numutil.h"
56 "Evaluated value of the function for the current variable values.");
63 "Value of derivative of the function for the current variable values");
73 "Result of the function evaluation with current variable values.",
76 "Derivative of the function at given variable values.",
79 "Mode of operation: \n"
80 " 1: only the function value will be calculated\n"
81 " 2: only the derivative will be calculated\n"
82 " 3: both function value and derivative at current variable values will be calculated.",
86 "Mathematical expression defining the function. The underlying parser\n"
87 "is muParser. In addition to the available functions and operators from\n"
88 "muParser, some more functions are added.\n"
90 "Name args explanation\n"
91 "sin 1 sine function\n"
92 "cos 1 cosine function\n"
93 "tan 1 tangens function\n"
94 "asin 1 arcus sine function\n"
95 "acos 1 arcus cosine function\n"
96 "atan 1 arcus tangens function\n"
97 "sinh 1 hyperbolic sine function\n"
98 "cosh 1 hyperbolic cosine\n"
99 "tanh 1 hyperbolic tangens function\n"
100 "asinh 1 hyperbolic arcus sine function\n"
101 "acosh 1 hyperbolic arcus tangens function\n"
102 "atanh 1 hyperbolic arcur tangens function\n"
103 "log2 1 logarithm to the base 2\n"
104 "log10 1 logarithm to the base 10\n"
105 "log 1 logarithm to the base 10\n"
106 "ln 1 logarithm to base e (2.71828...)\n"
107 "exp 1 e raised to the power of x\n"
108 "sqrt 1 square root of a value\n"
109 "sign 1 sign function -1 if x<0; 1 if x>0\n"
110 "rint 1 round to nearest integer\n"
111 "abs 1 absolute value\n"
112 "min var. min of all arguments\n"
113 "max var. max of all arguments\n"
114 "sum var. sum of all arguments\n"
115 "avg var. mean value of all arguments\n"
116 "rand 1 rand(seed), random float between 0 and 1, \n"
117 " if seed = -1, then a 'random' seed is created.\n"
118 "rand2 3 rand(a, b, seed), random float between a and b, \n"
119 " if seed = -1, a 'random' seed is created using either\n"
120 " by random_device or by reading system clock\n"
122 "Op meaning prioroty\n"
126 "<= less or equal 4\n"
127 ">= greater or equal 4\n"
134 "* multiplication 6\n"
136 "^ raise x to the power of y 7\n"
138 "?: if then else operator C++ style syntax\n",
142 "Lookup table for variable values.",
146 "Variable names in the expression",
149 "Value for variable named x. This is a shorthand. If the\n"
150 "expression does not have any variable named x, this the first variable\n"
151 "in the sequence `vars`.",
155 "Value for variable named y. This is a utility for two/three\n"
156 " variable functions where the y value comes from a source separate\n"
157 " from that of x. This is a shorthand. If the\n"
158 "expression does not have any variable named y, this the second\n"
159 "variable in the sequence `vars`.",
163 "Value for variable named z. This is a utility for three\n"
164 " variable functions where the z value comes from a source separate\n"
165 " from that of x or z. This is a shorthand. If the expression does not\n"
166 " have any variable named z, this the third variable in the sequence `vars`.",
173 "Handle value for specified variable coming from other objects",
176 "Handle value for variable named x. This is a shorthand. If the\n"
177 "expression does not have any variable named x, this the first variable\n"
178 "in the sequence `vars`.",
181 "Handle value for variable named y. This is a utility for two/three\n"
182 " variable functions where the y value comes from a source separate\n"
183 " from that of x. This is a shorthand. If the\n"
184 "expression does not have any variable named y, this the second\n"
185 "variable in the sequence `vars`.",
188 "Handle value for variable named z. This is a utility for three\n"
189 " variable functions where the z value comes from a source separate\n"
190 " from that of x or y. This is a shorthand. If the expression does not\n"
191 " have any variable named y, this the second variable in the sequence `vars`.",
194 "Handle value for variables x and y for two-variable function",
197 "Handle value for variables x, y and z for three-variable function",
201 "Utility function to assign the variable values of the function.\n"
202 "Takes a list of variable names and a list of corresponding values.",
212 "Handles process call, updates internal time stamp.",
215 "Handles reinit call.",
217 static Finfo* processShared[] =
223 "This is a shared message to receive Process messages "
224 "from the scheduler objects."
225 "The first entry in the shared msg is a MsgDest "
226 "for the Process operation. It has a single argument, "
227 "ProcInfo, which holds lots of information about current "
228 "time, thread, dt and so on. The second entry is a MsgDest "
229 "for the Reinit operation. It also uses ProcInfo. ",
230 processShared,
sizeof( processShared ) /
sizeof(
Finfo* )
233 static Finfo *funcFinfos[] =
255 static string doc[] =
258 "Author",
"Subhasis Ray",
260 "Func: general purpose function calculator using real numbers. It can\n"
261 "parse mathematical expression defining a function and evaluate it\n"
262 "and/or its derivative for specified variable values.\n"
263 "The variables can be input from other moose objects. In case of\n"
264 "arbitrary variable names, the source message must have the variable\n"
265 "name as the first argument. For most common cases, input messages to\n"
266 "set x, y, z and xy, xyz are made available without such\n"
267 "requirement. This class handles only real numbers\n"
268 "(C-double). Predefined constants are: pi=3.141592...,\n"
276 sizeof(funcFinfos) /
sizeof(
Finfo*),
279 sizeof(doc)/
sizeof(
string));
288 Func::Func():_x(NULL), _y(NULL), _z(NULL), _mode(1), _valid(false)
305 vector <string> vars = rhs.
getVars();
306 for (
unsigned int ii = 0; ii < vars.size(); ++ii)
320 vector <string> vars = rhs.
getVars();
321 for (
unsigned int ii = 0; ii < vars.size(); ++ii)
337 for (
unsigned int ii = 0; ii <
_varbuf.size(); ++ii)
346 cout <<
"Error occurred in parser.\n"
347 <<
"Message: " << e.GetMsg() <<
"\n"
348 <<
"Formula: " << e.GetExpr() <<
"\n"
349 <<
"Token: " << e.GetToken() <<
"\n"
350 <<
"Position: " << e.GetPos() <<
"\n"
351 <<
"Error code: " << e.GetCode() << endl;
358 Func* func =
reinterpret_cast< Func *
>(data);
359 double *ret =
new double;
371 mu::varmap_type vars;
377 catch (mu::Parser::exception_type &e)
383 mu::varmap_type::iterator v = vars.find(
"x");
388 else if (vars.size() >= 1)
398 else if (vars.size() >= 2)
409 else if (vars.size() >= 3)
423 cout <<
"Error: Func::getExpr() - invalid parser state" << endl;
436 cout <<
"Error: Func::setVar() - invalid parser state" << endl;
439 mu::varmap_type vars;
444 catch (mu::Parser::exception_type &e)
450 mu::varmap_type::iterator v = vars.find(name);
457 cout <<
"Error: no such variable " << name << endl;
468 cout <<
"Error: Func::getVar() - invalid parser state" << endl;
473 const mu::varmap_type &vars =
_parser.GetVar();
474 mu::varmap_type::const_iterator v = vars.find(name);
481 cout <<
"Error: no such variable " << name << endl;
485 catch (mu::Parser::exception_type &e)
585 cout <<
"Error: Func::getValue() - invalid state" << endl;
592 catch (mu::Parser::exception_type &e)
604 cout <<
"Error: Func::getDerivative() - invalid state" << endl;
613 catch (mu::Parser::exception_type &e)
624 vector< string > ret;
627 cout <<
"Error: Func::getVars() - invalid parser state" << endl;
630 mu::varmap_type vars;
634 for (mu::varmap_type::iterator ii = vars.begin();
635 ii != vars.end(); ++ii)
637 ret.push_back(ii->first);
640 catch (mu::Parser::exception_type &e)
650 if (vars.size() > vals.size() || !
_valid)
654 mu::varmap_type varmap =
_parser.GetVar();
655 for (
unsigned int ii = 0; ii < vars.size(); ++ii)
657 mu::varmap_type::iterator v = varmap.find(vars[ii]);
658 if ( v != varmap.end())
660 *v->second = vals[ii];
685 cout <<
"Error: Func::reinit() - invalid parser state. Will do nothing." << endl;
690 cout <<
"Error: no expression set. Will do nothing." << endl;
void setVarValues(vector< string > vars, vector< double > vals)
void setVar(string name, double value)
static double * _addVar(const char *name, void *data)
static const Cinfo * initCinfo()
vector< string > getVars() const
void setXYZ(double x, double y, double z)
double getVar(string name) const
static SrcFinfo1< double > * derivativeOut()
void reinit(const Eref &e, ProcPtr p)
void setXY(double x, double y)
static SrcFinfo1< double > * valueOut()
friend double * _addVar(const char *name, void *data)
void setMode(unsigned int mode)
double getDerivative() const
void process(const Eref &e, ProcPtr p)
static const Cinfo * initCinfo()
std::string trim(const std::string myString, const string &delimiters)
void setExpr(string expr)
static const Cinfo * funcCinfo
void _showError(mu::Parser::exception_type &e) const
vector< double * > _varbuf
unsigned int getMode() const
Func & operator=(const Func rhs)