muParser API -  1.35
muParser.cpp
Go to the documentation of this file.
1 /*
2 
3  _____ __ _____________ _______ ______ ___________
4  / \| | \____ \__ \\_ __ \/ ___// __ \_ __ \
5  | Y Y \ | / |_> > __ \| | \/\___ \\ ___/| | \/
6  |__|_| /____/| __(____ /__| /____ >\___ >__|
7  \/ |__| \/ \/ \/
8  Copyright (C) 2004 - 2020 Ingo Berg
9 
10  Redistribution and use in source and binary forms, with or without modification, are permitted
11  provided that the following conditions are met:
12 
13  * Redistributions of source code must retain the above copyright notice, this list of
14  conditions and the following disclaimer.
15  * Redistributions in binary form must reproduce the above copyright notice, this list of
16  conditions and the following disclaimer in the documentation and/or other materials provided
17  with the distribution.
18 
19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #include "muParser.h"
30 #include "muParserTemplateMagic.h"
31 
32 //--- Standard includes ------------------------------------------------------------------------
33 #include <cmath>
34 #include <algorithm>
35 #include <numeric>
36 
37 using namespace std;
38 
39 /** \file
40  \brief Implementation of the standard floating point parser.
41 */
42 
43 
44 
45 /** \brief Namespace for mathematical applications. */
46 namespace mu
47 {
48  //---------------------------------------------------------------------------
49  /** \brief Default value recognition callback.
50  \param [in] a_szExpr Pointer to the expression
51  \param [in, out] a_iPos Pointer to an index storing the current position within the expression
52  \param [out] a_fVal Pointer where the value should be stored in case one is found.
53  \return 1 if a value was found 0 otherwise.
54  */
55  int Parser::IsVal(const char_type* a_szExpr, int* a_iPos, value_type* a_fVal)
56  {
57  value_type fVal(0);
58 
59  stringstream_type stream(a_szExpr);
60  stream.seekg(0); // todo: check if this really is necessary
61  stream.imbue(Parser::s_locale);
62  stream >> fVal;
63  stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
64 
65  if (iEnd == (stringstream_type::pos_type) - 1)
66  return 0;
67 
68  *a_iPos += (int)iEnd;
69  *a_fVal = fVal;
70  return 1;
71  }
72 
73 
74  //---------------------------------------------------------------------------
75  /** \brief Constructor.
76 
77  Call ParserBase class constructor and trigger Function, Operator and Constant initialization.
78  */
79  Parser::Parser()
80  :ParserBase()
81  {
83 
84  InitCharSets();
85  InitFun();
86  InitConst();
87  InitOprt();
88  }
89 
90  //---------------------------------------------------------------------------
91  /** \brief Define the character sets.
92  \sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars
93 
94  This function is used for initializing the default character sets that define
95  the characters to be useable in function and variable names and operators.
96  */
98  {
99  DefineNameChars(_T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"));
100  DefineOprtChars(_T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}"));
101  DefineInfixOprtChars(_T("/+-*^?<>=#!$%&|~'_"));
102  }
103 
104  //---------------------------------------------------------------------------
105  /** \brief Initialize the default functions. */
107  {
109  {
110  // When setting MUP_BASETYPE to an integer type
111  // Place functions for dealing with integer values here
112  // ...
113  // ...
114  // ...
115  }
116  else
117  {
118  // trigonometric functions
122  // arcus functions
127  // hyperbolic functions
131  // arcus hyperbolic functions
135  // Logarithm functions
140  // misc
146  // Functions with variable number of arguments
151  }
152  }
153 
154  //---------------------------------------------------------------------------
155  /** \brief Initialize constants.
156 
157  By default the parser recognizes two constants. Pi ("pi") and the Eulerian
158  number ("_e").
159  */
161  {
164  }
165 
166  //---------------------------------------------------------------------------
167  /** \brief Initialize operators.
168 
169  By default only the unary minus operator is added.
170  */
172  {
175  }
176 
177  //---------------------------------------------------------------------------
178  void Parser::OnDetectVar(string_type* /*pExpr*/, int& /*nStart*/, int& /*nEnd*/)
179  {
180  // this is just sample code to illustrate modifying variable names on the fly.
181  // I'm not sure anyone really needs such a feature...
182  /*
183 
184 
185  string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd);
186  string sRepl = std::string("_") + sVar + "_";
187 
188  int nOrigVarEnd = nEnd;
189  cout << "variable detected!\n";
190  cout << " Expr: " << *pExpr << "\n";
191  cout << " Start: " << nStart << "\n";
192  cout << " End: " << nEnd << "\n";
193  cout << " Var: \"" << sVar << "\"\n";
194  cout << " Repl: \"" << sRepl << "\"\n";
195  nEnd = nStart + sRepl.length();
196  cout << " End: " << nEnd << "\n";
197  pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl);
198  cout << " New expr: " << *pExpr << "\n";
199  */
200  }
201 
202  //---------------------------------------------------------------------------
203  /** \brief Numerically differentiate with regard to a variable.
204  \param [in] a_Var Pointer to the differentiation variable.
205  \param [in] a_fPos Position at which the differentiation should take place.
206  \param [in] a_fEpsilon Epsilon used for the numerical differentiation.
207 
208  Numerical differentiation uses a 5 point operator yielding a 4th order
209  formula. The default value for epsilon is 0.00074 which is
210  numeric_limits<double>::epsilon() ^ (1/5).
211  */
212  value_type Parser::Diff(value_type* a_Var, value_type a_fPos, value_type a_fEpsilon) const
213  {
214  value_type fRes(0);
215  value_type fBuf(*a_Var);
216  value_type f[4] = { 0,0,0,0 };
217  value_type fEpsilon(a_fEpsilon);
218 
219  // Backwards compatible calculation of epsilon inc case the user doesn't provide
220  // his own epsilon
221  if (fEpsilon == 0)
222  fEpsilon = (a_fPos == 0) ? (value_type)1e-10 : (value_type)1e-7 * a_fPos;
223 
224  *a_Var = a_fPos + 2 * fEpsilon; f[0] = Eval();
225  *a_Var = a_fPos + 1 * fEpsilon; f[1] = Eval();
226  *a_Var = a_fPos - 1 * fEpsilon; f[2] = Eval();
227  *a_Var = a_fPos - 2 * fEpsilon; f[3] = Eval();
228  *a_Var = fBuf; // restore variable
229 
230  fRes = (-f[0] + 8 * f[1] - 8 * f[2] + f[3]) / (12 * fEpsilon);
231  return fRes;
232  }
233 } // namespace mu
void DefineInfixOprtChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of infix operators.
#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:106
void AddValIdent(identfun_type a_pCallback)
Add a value parsing function.
STL namespace.
Definition of the standard floating point parser.
virtual void InitCharSets()
Define the character sets.
Definition: muParser.cpp:97
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:309
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:55
virtual void InitConst()
Initialize constants.
Definition: muParser.cpp:160
void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt=true)
Define a parser function without arguments.
Definition: muParserBase.h:134
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:294
A template class for providing wrappers for essential math functions.
Namespace for mathematical applications.
Definition: muParser.cpp:46
string_type::value_type char_type
The character type used by the parser.
Definition: muParserDef.h:306
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:212
MUP_STRING_TYPE string_type
The stringtype used by the parser.
Definition: muParserDef.h:300
virtual void InitOprt()
Initialize operators.
Definition: muParser.cpp:171
Mathematical expressions parser (base parser engine).
Definition: muParserBase.h:63