NCBI C++ ToolKit
muParser.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /*
2  __________
3  _____ __ __\______ \_____ _______ ______ ____ _______
4  / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
5  | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
6  |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
7  \/ \/ \/ \/
8 
9  Copyright (C) 2004-2008 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 
27 #include <ncbi_pch.hpp>
29 
30 //--- Standard includes ------------------------------------------------------------------------
31 #include <cmath>
32 #include <algorithm>
33 #include <numeric>
34 
35 /** \brief Pi (what else?). */
36 #define PARSER_CONST_PI 3.141592653589793238462643
37 
38 /** \brief The eulerian number. */
39 #define PARSER_CONST_E 2.718281828459045235360287
40 
41 #define wxT(x) MUP_T(x)
42 
43 using namespace std;
44 
45 /** \file
46  \brief Implementation of the standard floating point parser.
47 */
48 
49 
50 /** \brief Namespace for mathematical applications. */
51 namespace mu
52 {
53  std::locale Parser::s_locale = std::locale("C");
54 
55  //---------------------------------------------------------------------------
56  // Trigonometric function
57  value_type Parser::Sin(value_type v) { return sin(v); }
58  value_type Parser::Cos(value_type v) { return cos(v); }
59  value_type Parser::Tan(value_type v) { return tan(v); }
60  value_type Parser::ASin(value_type v) { return asin(v); }
61  value_type Parser::ACos(value_type v) { return acos(v); }
62  value_type Parser::ATan(value_type v) { return atan(v); }
63  value_type Parser::Sinh(value_type v) { return sinh(v); }
64  value_type Parser::Cosh(value_type v) { return cosh(v); }
65  value_type Parser::Tanh(value_type v) { return tanh(v); }
66  value_type Parser::ASinh(value_type v) { return log(v + sqrt(v * v + 1)); }
67  value_type Parser::ACosh(value_type v) { return log(v + sqrt(v * v - 1)); }
68  value_type Parser::ATanh(value_type v) { return ((value_type)0.5 * log((1 + v) / (1 - v))); }
69 
70  //---------------------------------------------------------------------------
71  // Logarithm functions
72  value_type Parser::Log2(value_type v) { return log(v)/log((value_type)2); } // Logarithm base 2
73  value_type Parser::Log10(value_type v) { return log10(v); } // Logarithm base 10
74  value_type Parser::Ln(value_type v) { return log(v); } // Logarithm base e (natural logarithm)
75 
76  //---------------------------------------------------------------------------
77  // misc
78  value_type Parser::Exp(value_type v) { return exp(v); }
79  value_type Parser::Abs(value_type v) { return fabs(v); }
80  value_type Parser::Sqrt(value_type v) { return sqrt(v); }
81  value_type Parser::Rint(value_type v) { return floor(v + (value_type)0.5); }
82  value_type Parser::Sign(value_type v) { return (value_type)((v<0) ? -1 : (v>0) ? 1 : 0); }
83 
84  //---------------------------------------------------------------------------
85  /** \brief Conditional (if then else).
86  \param v1 Condition
87  \param v2 First value
88  \param v3 Second value
89  \return v2 if v1!=0 v3 otherwise.
90  */
92  {
93  return (v1) ? v2 : v3;
94  }
95 
96  //---------------------------------------------------------------------------
97  /** \brief Callback for the unary minus operator.
98  \param v The value to negate
99  \return -v
100  */
101  value_type Parser::UnaryMinus(value_type v)
102  {
103  return -v;
104  }
105 
106  //---------------------------------------------------------------------------
107  /** \brief Callback for adding multiple values.
108  \param [in] a_afArg Vector with the function arguments
109  \param [in] a_iArgc The size of a_afArg
110  */
111  value_type Parser::Sum(const value_type *a_afArg, int a_iArgc)
112  {
113  if (!a_iArgc)
114  throw exception_type(wxT("too few arguments for function sum."));
115 
116  value_type fRes=0;
117  for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
118  return fRes;
119  }
120 
121  //---------------------------------------------------------------------------
122  /** \brief Callback for averaging multiple values.
123  \param [in] a_afArg Vector with the function arguments
124  \param [in] a_iArgc The size of a_afArg
125  */
126  value_type Parser::Avg(const value_type *a_afArg, int a_iArgc)
127  {
128  if (!a_iArgc)
129  throw exception_type(wxT("too few arguments for function sum."));
130 
131  value_type fRes=0;
132  for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
133  return fRes/(double)a_iArgc;
134  }
135 
136 
137  //---------------------------------------------------------------------------
138  /** \brief Callback for determining the minimum value out of a vector.
139  \param [in] a_afArg Vector with the function arguments
140  \param [in] a_iArgc The size of a_afArg
141  */
142  value_type Parser::Min(const value_type *a_afArg, int a_iArgc)
143  {
144  if (!a_iArgc)
145  throw exception_type(wxT("too few arguments for function min."));
146 
147  value_type fRes=a_afArg[0];
148  for (int i=0; i<a_iArgc; ++i) fRes = std::min(fRes, a_afArg[i]);
149 
150  return fRes;
151  }
152 
153 
154  //---------------------------------------------------------------------------
155  /** \brief Callback for determining the maximum value out of a vector.
156  \param [in] a_afArg Vector with the function arguments
157  \param [in] a_iArgc The size of a_afArg
158  */
159  value_type Parser::Max(const value_type *a_afArg, int a_iArgc)
160  {
161  if (!a_iArgc)
162  throw exception_type(wxT("too few arguments for function min."));
163 
164  value_type fRes=a_afArg[0];
165  for (int i=0; i<a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]);
166 
167  return fRes;
168  }
169 
170 
171  //---------------------------------------------------------------------------
172  /** \brief Default value recognition callback.
173  \param [in] a_szExpr Pointer to the expression
174  \param [in, out] a_iPos Pointer to an index storing the current position within the expression
175  \param [out] a_fVal Pointer where the value should be stored in case one is found.
176  \return 1 if a value was found 0 otherwise.
177  */
178  int Parser::IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal)
179  {
180  value_type fVal(0);
181 
182  // 20080309 commented the fix since it is not local aware
183  //
184  //// thanks to CodeProject member sailorickm for writing this fix:
185  //// http://www.codeproject.com/cpp/FastMathParser.asp?msg=1354598#xx1354598xx
186  //// i cant test it myself, if you see problems please contact me.
187  ////
188  //// - 20080309 ibg; support for locales wont work with this fix
189  //#if defined (__hpux) || (defined __GNUC__ && (__GNUC__ == 3 && (__GNUC_MINOR__ < 3 )))
190  // int iEnd = 0;
191  // int nAssigned = sscanf(a_szExpr, "%lf%n", &fVal, &iEnd);
192  // if (nAssigned == 0)
193  // iEnd = -1;
194  //#else
195  stringstream_type stream(a_szExpr);
196  stream.seekg(0); // todo: check if this really is necessary
197  stream.imbue(Parser::s_locale);
198  stream >> fVal;
199  int iEnd = static_cast<int>(stream.tellg()); // Position after reading
200  //#endif
201 
202  if (iEnd==-1)
203  return 0;
204 
205  *a_iPos += iEnd;
206  *a_fVal = fVal;
207  return 1;
208  }
209 
210 
211  //---------------------------------------------------------------------------
212  /** \brief Constructor.
213 
214  Call ParserBase class constructor and trigger Function, Operator and Constant initialization.
215  */
217  :ParserBase()
218  {
220 
221  InitCharSets();
222  InitFun();
223  InitConst();
224  InitOprt();
225  }
226 
227  //---------------------------------------------------------------------------
228  /** \brief Define the character sets.
229  \sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars
230 
231  This function is used for initializing the default character sets that define
232  the characters to be useable in function and variable names and operators.
233  */
235  {
236  DefineNameChars( wxT("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );
237  DefineOprtChars( wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_") );
238  DefineInfixOprtChars( wxT("/+-*^?<>=#!$%&|~'_") );
239  }
240 
241  //---------------------------------------------------------------------------
242  /** \brief Initialize the default functions. */
244  {
245  // trigonometric functions
246  DefineFun(wxT("sin"), Sin);
247  DefineFun(wxT("cos"), Cos);
248  DefineFun(wxT("tan"), Tan);
249  // arcus functions
250  DefineFun(wxT("asin"), ASin);
251  DefineFun(wxT("acos"), ACos);
252  DefineFun(wxT("atan"), ATan);
253  // hyperbolic functions
254  DefineFun(wxT("sinh"), Sinh);
255  DefineFun(wxT("cosh"), Cosh);
256  DefineFun(wxT("tanh"), Tanh);
257  // arcus hyperbolic functions
258  DefineFun(wxT("asinh"), ASinh);
259  DefineFun(wxT("acosh"), ACosh);
260  DefineFun(wxT("atanh"), ATanh);
261  // Logarithm functions
262  DefineFun(wxT("log2"), Log2);
263  DefineFun(wxT("log10"), Log10);
264  DefineFun(wxT("log"), Log10);
265  DefineFun(wxT("ln"), Ln);
266  // misc
267  DefineFun(wxT("exp"), Exp);
268  DefineFun(wxT("sqrt"), Sqrt);
269  DefineFun(wxT("sign"), Sign);
270  DefineFun(wxT("rint"), Rint);
271  DefineFun(wxT("abs"), Abs);
272  DefineFun(wxT("if"), Ite);
273  // Functions with variable number of arguments
274  DefineFun(wxT("sum"), Sum);
275  DefineFun(wxT("avg"), Avg);
276  DefineFun(wxT("min"), Min);
277  DefineFun(wxT("max"), Max);
278  }
279 
280  //---------------------------------------------------------------------------
281  /** \brief Initialize constants.
282 
283  By default the parser recognizes two constants. Pi ("pi") and the eulerian
284  number ("_e").
285  */
287  {
290  }
291 
292  //---------------------------------------------------------------------------
293  /** \brief Set the decimal separator.
294  \param cDecSep Decimal separator as a character value.
295  \sa SetThousandsSep
296 
297  By default muparser uses the "C" locale. The decimal separator of this
298  locale is overwritten by the one provided here.
299  */
301  {
302  char_type cThousandsSep = MUP_USE_FACET(change_dec_sep<char_type>, s_locale).thousands_sep();
303  s_locale = std::locale(std::locale("C"), new change_dec_sep<char_type>(cDecSep, cThousandsSep));
304  }
305 
306  //---------------------------------------------------------------------------
307  /** \brief Sets the thousands operator.
308  \param cThousandsSep The thousands separator as a character
309  \sa SetDecSep
310 
311  By default muparser uses the "C" locale. The thousands separator of this
312  locale is overwritten by the one provided here.
313  */
314  void Parser::SetThousandsSep(char_type cThousandsSep)
315  {
316  char_type cDecSep = MUP_USE_FACET(change_dec_sep<char_type>, s_locale).decimal_point();
317  s_locale = std::locale(std::locale("C"), new change_dec_sep<char_type>(cDecSep, cThousandsSep));
318  }
319 
320  //---------------------------------------------------------------------------
321  /** \brief Initialize operators.
322 
323  By default only the unary minus operator is added.
324  */
326  {
328  }
329 
330 
331  //---------------------------------------------------------------------------
332  /** \brief Numerically differentiate with regard to a variable.
333  \param [in] a_Var Pointer to the differentiation variable.
334  \param [in] a_fPos Position at which the differentiation should take place.
335  \param [in] a_fEpsilon Epsilon used for the numerical differentiation.
336 
337  Numerical differentiation uses a 5 point operator yielding a 4th order
338  formula. The default value for epsilon is 0.00074 which is
339  numerical_limits<double>::epsilon() ^ (1/5) as suggested in the muparser
340  forum:
341 
342  http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843
343  */
345  value_type a_fPos,
346  value_type a_fEpsilon) const
347  {
348  value_type fRes(0),
349  fBuf(*a_Var),
350  f[4] = {0,0,0,0};
351 
352  *a_Var = a_fPos+2 * a_fEpsilon; f[0] = Eval();
353  *a_Var = a_fPos+1 * a_fEpsilon; f[1] = Eval();
354  *a_Var = a_fPos-1 * a_fEpsilon; f[2] = Eval();
355  *a_Var = a_fPos-2 * a_fEpsilon; f[3] = Eval();
356  *a_Var = fBuf; // restore variable
357 
358  fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*a_fEpsilon);
359  return fRes;
360  }
361 } // namespace mu
Mathematical expressions parser (base parser engine).
Definition: muParserBase.h:64
void AddValIdent(identfun_type a_pCallback)
void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true)
Add a user defined operator.
value_type Eval() const
Calculate the result.
Definition: muParserBase.h:116
void DefineConst(const string_type &a_sName, value_type a_fVal)
Add a user defined constant.
void DefineOprtChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of binary operators and postfix operators.
void DefineInfixOprtChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of infix operators.
void DefineNameChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of functions, variables, constants.
void DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt=true)
Definition: muParserBase.h:138
Error class of the parser.
A facet class used to change decimal and thousands separator.
Definition: muParser.h:75
static int IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
Default value recognition callback.
Definition: muParser.cpp:178
static value_type ATanh(value_type)
Definition: muParser.cpp:68
static value_type Sign(value_type)
Definition: muParser.cpp:82
static value_type Tanh(value_type)
Definition: muParser.cpp:65
void SetThousandsSep(char_type cThousandsSep)
Sets the thousands operator.
Definition: muParser.cpp:314
static value_type Cosh(value_type)
Definition: muParser.cpp:64
static value_type ASin(value_type)
Definition: muParser.cpp:60
static value_type UnaryMinus(value_type)
Callback for the unary minus operator.
Definition: muParser.cpp:101
static value_type Sum(const value_type *, int)
Callback for adding multiple values.
Definition: muParser.cpp:111
value_type Diff(value_type *a_Var, value_type a_fPos, value_type a_fEpsilon=0.00074) const
Numerically differentiate with regard to a variable.
Definition: muParser.cpp:344
static value_type Avg(const value_type *, int)
Callback for averaging multiple values.
Definition: muParser.cpp:126
virtual void InitCharSets()
Define the character sets.
Definition: muParser.cpp:234
static value_type Sqrt(value_type)
Definition: muParser.cpp:80
void SetDecSep(char_type cDecSep)
Set the decimal separator.
Definition: muParser.cpp:300
static std::locale s_locale
The locale used by the parser.
Definition: muParser.h:149
static value_type Min(const value_type *, int)
Callback for determining the minimum value out of a vector.
Definition: muParser.cpp:142
virtual void InitOprt()
Initialize operators.
Definition: muParser.cpp:325
static value_type Sinh(value_type)
Definition: muParser.cpp:63
static value_type ACos(value_type)
Definition: muParser.cpp:61
static value_type Tan(value_type)
Definition: muParser.cpp:59
static value_type Abs(value_type)
Definition: muParser.cpp:79
static value_type Exp(value_type)
Definition: muParser.cpp:78
static value_type Rint(value_type)
Definition: muParser.cpp:81
static value_type ATan(value_type)
Definition: muParser.cpp:62
static value_type Log10(value_type)
Definition: muParser.cpp:73
static value_type Cos(value_type)
Definition: muParser.cpp:58
static value_type ASinh(value_type)
Definition: muParser.cpp:66
virtual void InitFun()
Initialize the default functions.
Definition: muParser.cpp:243
static value_type Ite(value_type, value_type, value_type)
Conditional (if then else).
Definition: muParser.cpp:91
virtual void InitConst()
Initialize constants.
Definition: muParser.cpp:286
static value_type Log2(value_type)
Definition: muParser.cpp:72
static value_type Max(const value_type *, int)
Callback for determining the maximum value out of a vector.
Definition: muParser.cpp:159
static value_type Ln(value_type)
Definition: muParser.cpp:74
static value_type Sin(value_type)
Definition: muParser.cpp:57
static value_type ACosh(value_type)
Definition: muParser.cpp:67
static FILE * f
Definition: readconf.c:23
const CVect2< U > & v2
Definition: globals.hpp:440
int i
#define MUP_USE_FACET(FACET, LOCALE)
Definition: muParserDef.h:72
#define PARSER_CONST_E
The eulerian number.
Definition: muParser.cpp:39
#define PARSER_CONST_PI
Pi (what else?).
Definition: muParser.cpp:36
#define wxT(x)
Definition: muParser.cpp:41
Definition of the standard floating point parser.
Namespace for mathematical applications.
Definition: muParser.h:41
string_type::value_type char_type
The character type used by the parser.
Definition: muParserDef.h:246
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:251
double value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:228
#define fabs(v)
Definition: ncbi_dispd.c:46
T max(T x_, T y_)
T log10(T x_)
T min(T x_, T y_)
static const char * locale
Definition: pcre2grep.c:212
Modified on Fri Sep 20 14:57:48 2024 by modify_doxy.py rev. 669887