muParser API -  1.35
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
muParser.cpp
Go to the documentation of this file.
1 /*
2  __________
3  _____ __ __\______ \_____ _______ ______ ____ _______
4  / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
5  | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
6  |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
7  \/ \/ \/ \/
8 
9  Copyright (C) 2013 Ingo Berg
10 
11  Permission is hereby granted, free of charge, to any person obtaining a copy of this
12  software and associated documentation files (the "Software"), to deal in the Software
13  without restriction, including without limitation the rights to use, copy, modify,
14  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
15  permit persons to whom the Software is furnished to do so, subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included in all copies or
18  substantial portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
21  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
23  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26 #include "muParser.h"
27 #include "muParserTemplateMagic.h"
28 
29 //--- Standard includes ------------------------------------------------------------------------
30 #include <cmath>
31 #include <algorithm>
32 #include <numeric>
33 
34 /** \brief Pi (what else?). */
35 #define PARSER_CONST_PI 3.141592653589793238462643
36 
37 /** \brief The Eulerian number. */
38 #define PARSER_CONST_E 2.718281828459045235360287
39 
40 using namespace std;
41 
42 /** \file
43  \brief Implementation of the standard floating point parser.
44 */
45 
46 
47 
48 /** \brief Namespace for mathematical applications. */
49 namespace mu
50 {
51 
52 
53  //---------------------------------------------------------------------------
54  // Trigonometric function
55  value_type Parser::Sin(value_type v) { return MathImpl<value_type>::Sin(v); }
56  value_type Parser::Cos(value_type v) { return MathImpl<value_type>::Cos(v); }
57  value_type Parser::Tan(value_type v) { return MathImpl<value_type>::Tan(v); }
58  value_type Parser::ASin(value_type v) { return MathImpl<value_type>::ASin(v); }
59  value_type Parser::ACos(value_type v) { return MathImpl<value_type>::ACos(v); }
60  value_type Parser::ATan(value_type v) { return MathImpl<value_type>::ATan(v); }
61  value_type Parser::ATan2(value_type v1, value_type v2) { return MathImpl<value_type>::ATan2(v1, v2); }
62  value_type Parser::Sinh(value_type v) { return MathImpl<value_type>::Sinh(v); }
63  value_type Parser::Cosh(value_type v) { return MathImpl<value_type>::Cosh(v); }
64  value_type Parser::Tanh(value_type v) { return MathImpl<value_type>::Tanh(v); }
65  value_type Parser::ASinh(value_type v) { return MathImpl<value_type>::ASinh(v); }
66  value_type Parser::ACosh(value_type v) { return MathImpl<value_type>::ACosh(v); }
67  value_type Parser::ATanh(value_type v) { return MathImpl<value_type>::ATanh(v); }
68 
69  //---------------------------------------------------------------------------
70  // Logarithm functions
71 
72  // Logarithm base 2
73  value_type Parser::Log2(value_type v)
74  {
75  #ifdef MUP_MATH_EXCEPTIONS
76  if (v<=0)
77  throw ParserError(ecDOMAIN_ERROR, _T("Log2"));
78  #endif
79 
80  return MathImpl<value_type>::Log2(v);
81  }
82 
83  // Logarithm base 10
84  value_type Parser::Log10(value_type v)
85  {
86  #ifdef MUP_MATH_EXCEPTIONS
87  if (v<=0)
88  throw ParserError(ecDOMAIN_ERROR, _T("Log10"));
89  #endif
90 
91  return MathImpl<value_type>::Log10(v);
92  }
93 
94 // Logarithm base e (natural logarithm)
95  value_type Parser::Ln(value_type v)
96  {
97  #ifdef MUP_MATH_EXCEPTIONS
98  if (v<=0)
99  throw ParserError(ecDOMAIN_ERROR, _T("Ln"));
100  #endif
101 
102  return MathImpl<value_type>::Log(v);
103  }
104 
105  //---------------------------------------------------------------------------
106  // misc
107  value_type Parser::Exp(value_type v) { return MathImpl<value_type>::Exp(v); }
108  value_type Parser::Abs(value_type v) { return MathImpl<value_type>::Abs(v); }
109  value_type Parser::Sqrt(value_type v)
110  {
111  #ifdef MUP_MATH_EXCEPTIONS
112  if (v<0)
113  throw ParserError(ecDOMAIN_ERROR, _T("sqrt"));
114  #endif
115 
116  return MathImpl<value_type>::Sqrt(v);
117  }
118  value_type Parser::Rint(value_type v) { return MathImpl<value_type>::Rint(v); }
119  value_type Parser::Sign(value_type v) { return MathImpl<value_type>::Sign(v); }
120 
121  //---------------------------------------------------------------------------
122  /** \brief Callback for the unary minus operator.
123  \param v The value to negate
124  \return -v
125  */
126  value_type Parser::UnaryMinus(value_type v)
127  {
128  return -v;
129  }
130 
131  //---------------------------------------------------------------------------
132  /** \brief Callback for the unary minus operator.
133  \param v The value to negate
134  \return -v
135  */
136  value_type Parser::UnaryPlus(value_type v)
137  {
138  return v;
139  }
140 
141  //---------------------------------------------------------------------------
142  /** \brief Callback for adding multiple values.
143  \param [in] a_afArg Vector with the function arguments
144  \param [in] a_iArgc The size of a_afArg
145  */
146  value_type Parser::Sum(const value_type *a_afArg, int a_iArgc)
147  {
148  if (!a_iArgc)
149  throw exception_type(_T("too few arguments for function sum."));
150 
151  value_type fRes=0;
152  for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
153  return fRes;
154  }
155 
156  //---------------------------------------------------------------------------
157  /** \brief Callback for averaging multiple values.
158  \param [in] a_afArg Vector with the function arguments
159  \param [in] a_iArgc The size of a_afArg
160  */
161  value_type Parser::Avg(const value_type *a_afArg, int a_iArgc)
162  {
163  if (!a_iArgc)
164  throw exception_type(_T("too few arguments for function sum."));
165 
166  value_type fRes=0;
167  for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
168  return fRes/(value_type)a_iArgc;
169  }
170 
171 
172  //---------------------------------------------------------------------------
173  /** \brief Callback for determining the minimum value out of a vector.
174  \param [in] a_afArg Vector with the function arguments
175  \param [in] a_iArgc The size of a_afArg
176  */
177  value_type Parser::Min(const value_type *a_afArg, int a_iArgc)
178  {
179  if (!a_iArgc)
180  throw exception_type(_T("too few arguments for function min."));
181 
182  value_type fRes=a_afArg[0];
183  for (int i=0; i<a_iArgc; ++i)
184  fRes = std::min(fRes, a_afArg[i]);
185 
186  return fRes;
187  }
188 
189 
190  //---------------------------------------------------------------------------
191  /** \brief Callback for determining the maximum value out of a vector.
192  \param [in] a_afArg Vector with the function arguments
193  \param [in] a_iArgc The size of a_afArg
194  */
195  value_type Parser::Max(const value_type *a_afArg, int a_iArgc)
196  {
197  if (!a_iArgc)
198  throw exception_type(_T("too few arguments for function min."));
199 
200  value_type fRes=a_afArg[0];
201  for (int i=0; i<a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]);
202 
203  return fRes;
204  }
205 
206 
207  //---------------------------------------------------------------------------
208  /** \brief Default value recognition callback.
209  \param [in] a_szExpr Pointer to the expression
210  \param [in, out] a_iPos Pointer to an index storing the current position within the expression
211  \param [out] a_fVal Pointer where the value should be stored in case one is found.
212  \return 1 if a value was found 0 otherwise.
213  */
214  int Parser::IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal)
215  {
216  value_type fVal(0);
217 
218  stringstream_type stream(a_szExpr);
219  stream.seekg(0); // todo: check if this really is necessary
220  stream.imbue(Parser::s_locale);
221  stream >> fVal;
222  stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
223 
224  if (iEnd==(stringstream_type::pos_type)-1)
225  return 0;
226 
227  *a_iPos += (int)iEnd;
228  *a_fVal = fVal;
229  return 1;
230  }
231 
232 
233  //---------------------------------------------------------------------------
234  /** \brief Constructor.
235 
236  Call ParserBase class constructor and trigger Function, Operator and Constant initialization.
237  */
238  Parser::Parser()
239  :ParserBase()
240  {
242 
243  InitCharSets();
244  InitFun();
245  InitConst();
246  InitOprt();
247  }
248 
249  //---------------------------------------------------------------------------
250  /** \brief Define the character sets.
251  \sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars
252 
253  This function is used for initializing the default character sets that define
254  the characters to be useable in function and variable names and operators.
255  */
257  {
258  DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );
259  DefineOprtChars( _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}") );
260  DefineInfixOprtChars( _T("/+-*^?<>=#!$%&|~'_") );
261  }
262 
263  //---------------------------------------------------------------------------
264  /** \brief Initialize the default functions. */
266  {
268  {
269  // When setting MUP_BASETYPE to an integer type
270  // Place functions for dealing with integer values here
271  // ...
272  // ...
273  // ...
274  }
275  else
276  {
277  // trigonometric functions
278  DefineFun(_T("sin"), Sin);
279  DefineFun(_T("cos"), Cos);
280  DefineFun(_T("tan"), Tan);
281  // arcus functions
282  DefineFun(_T("asin"), ASin);
283  DefineFun(_T("acos"), ACos);
284  DefineFun(_T("atan"), ATan);
285  DefineFun(_T("atan2"), ATan2);
286  // hyperbolic functions
287  DefineFun(_T("sinh"), Sinh);
288  DefineFun(_T("cosh"), Cosh);
289  DefineFun(_T("tanh"), Tanh);
290  // arcus hyperbolic functions
291  DefineFun(_T("asinh"), ASinh);
292  DefineFun(_T("acosh"), ACosh);
293  DefineFun(_T("atanh"), ATanh);
294  // Logarithm functions
295  DefineFun(_T("log2"), Log2);
296  DefineFun(_T("log10"), Log10);
297  DefineFun(_T("log"), Ln);
298  DefineFun(_T("ln"), Ln);
299  // misc
300  DefineFun(_T("exp"), Exp);
301  DefineFun(_T("sqrt"), Sqrt);
302  DefineFun(_T("sign"), Sign);
303  DefineFun(_T("rint"), Rint);
304  DefineFun(_T("abs"), Abs);
305  // Functions with variable number of arguments
306  DefineFun(_T("sum"), Sum);
307  DefineFun(_T("avg"), Avg);
308  DefineFun(_T("min"), Min);
309  DefineFun(_T("max"), Max);
310  }
311  }
312 
313  //---------------------------------------------------------------------------
314  /** \brief Initialize constants.
315 
316  By default the parser recognizes two constants. Pi ("pi") and the Eulerian
317  number ("_e").
318  */
320  {
323  }
324 
325  //---------------------------------------------------------------------------
326  /** \brief Initialize operators.
327 
328  By default only the unary minus operator is added.
329  */
331  {
334  }
335 
336  //---------------------------------------------------------------------------
337  void Parser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)
338  {
339  // this is just sample code to illustrate modifying variable names on the fly.
340  // I'm not sure anyone really needs such a feature...
341  /*
342 
343 
344  string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd);
345  string sRepl = std::string("_") + sVar + "_";
346 
347  int nOrigVarEnd = nEnd;
348  cout << "variable detected!\n";
349  cout << " Expr: " << *pExpr << "\n";
350  cout << " Start: " << nStart << "\n";
351  cout << " End: " << nEnd << "\n";
352  cout << " Var: \"" << sVar << "\"\n";
353  cout << " Repl: \"" << sRepl << "\"\n";
354  nEnd = nStart + sRepl.length();
355  cout << " End: " << nEnd << "\n";
356  pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl);
357  cout << " New expr: " << *pExpr << "\n";
358  */
359  }
360 
361  //---------------------------------------------------------------------------
362  /** \brief Numerically differentiate with regard to a variable.
363  \param [in] a_Var Pointer to the differentiation variable.
364  \param [in] a_fPos Position at which the differentiation should take place.
365  \param [in] a_fEpsilon Epsilon used for the numerical differentiation.
366 
367  Numerical differentiation uses a 5 point operator yielding a 4th order
368  formula. The default value for epsilon is 0.00074 which is
369  numeric_limits<double>::epsilon() ^ (1/5) as suggested in the muparser
370  forum:
371 
372  http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843
373  */
375  value_type a_fPos,
376  value_type a_fEpsilon) const
377  {
378  value_type fRes(0),
379  fBuf(*a_Var),
380  f[4] = {0,0,0,0},
381  fEpsilon(a_fEpsilon);
382 
383  // Backwards compatible calculation of epsilon inc case the user doesn't provide
384  // his own epsilon
385  if (fEpsilon==0)
386  fEpsilon = (a_fPos==0) ? (value_type)1e-10 : (value_type)1e-7 * a_fPos;
387 
388  *a_Var = a_fPos+2 * fEpsilon; f[0] = Eval();
389  *a_Var = a_fPos+1 * fEpsilon; f[1] = Eval();
390  *a_Var = a_fPos-1 * fEpsilon; f[2] = Eval();
391  *a_Var = a_fPos-2 * fEpsilon; f[3] = Eval();
392  *a_Var = fBuf; // restore variable
393 
394  fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon);
395  return fRes;
396  }
397 } // namespace mu
void DefineInfixOprtChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of infix operators.
static value_type UnaryMinus(value_type)
Callback for the unary minus operator.
Definition: muParser.cpp:126
#define _T(x)
Activate this option in order to compile with OpenMP support.
Definition: muParserDef.h:69
void DefineNameChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of functions, variables, constants.
virtual void InitFun()
Initialize the default functions.
Definition: muParser.cpp:265
static value_type Sum(const value_type *, int)
Callback for adding multiple values.
Definition: muParser.cpp:146
#define PARSER_CONST_PI
Pi (what else?).
Definition: muParser.cpp:35
void AddValIdent(identfun_type a_pCallback)
Add a value parsing function.
static value_type Min(const value_type *, int)
Callback for determining the minimum value out of a vector.
Definition: muParser.cpp:177
STL namespace.
Definition of the standard floating point parser.
virtual void InitCharSets()
Define the character sets.
Definition: muParser.cpp:256
A class singling out integer types at compile time using template meta programming.
value_type Eval() const
Calculate the result.
std::basic_stringstream< char_type, std::char_traits< char_type >, std::allocator< char_type > > stringstream_type
Typedef for easily using stringstream that respect the parser stringtype.
Definition: muParserDef.h:264
void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true)
Add a user defined operator.
void DefineOprtChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of binary operators and postfix operators...
static int IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
Default value recognition callback.
Definition: muParser.cpp:214
virtual void InitConst()
Initialize constants.
Definition: muParser.cpp:319
catch division by zero, sqrt(-1), log(0) (currently unused)
Definition: muParserError.h:81
static value_type Avg(const value_type *, int)
Callback for averaging multiple values.
Definition: muParser.cpp:161
void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt=true)
Define a parser function without arguments.
Definition: muParserBase.h:133
Error class of the parser.
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:247
A template class for providing wrappers for essential math functions.
Namespace for mathematical applications.
Definition: muParser.cpp:49
static value_type UnaryPlus(value_type)
Callback for the unary minus operator.
Definition: muParser.cpp:136
string_type::value_type char_type
The character type used by the parser.
Definition: muParserDef.h:259
static value_type Max(const value_type *, int)
Callback for determining the maximum value out of a vector.
Definition: muParser.cpp:195
void DefineConst(const string_type &a_sName, value_type a_fVal)
Add a user defined constant.
value_type Diff(value_type *a_Var, value_type a_fPos, value_type a_fEpsilon=0) const
Numerically differentiate with regard to a variable.
Definition: muParser.cpp:374
MUP_STRING_TYPE string_type
The stringtype used by the parser.
Definition: muParserDef.h:253
#define PARSER_CONST_E
The Eulerian number.
Definition: muParser.cpp:38
virtual void InitOprt()
Initialize operators.
Definition: muParser.cpp:330
Mathematical expressions parser (base parser engine).
Definition: muParserBase.h:62