NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
muParser.cpp
Go to the documentation of this file.
1/*
2 __________
3 _____ __ __\______ \_____ _______ ______ ____ _______
4 / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
5 | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
6 |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
7 \/ \/ \/ \/
8
9 Copyright (C) 2012 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"
28
29//--- Standard includes ------------------------------------------------------------------------
30#include <cmath>
31#include <algorithm>
32#include <numeric>
33
35#define PARSER_CONST_PI 3.141592653589793238462643
36
38#define PARSER_CONST_E 2.718281828459045235360287
39
40using namespace std;
41
50
52namespace mu
53{
54
55
56 //---------------------------------------------------------------------------
57 // Trigonometric function
59 {
61 }
63 {
65 }
67 {
69 }
71 {
73 }
75 {
77 }
79 {
81 }
83 {
84 return MathImpl<double>::ATan2(v1.real(), v2.real());
85 }
87 {
89 }
91 {
93 }
95 {
97 }
99 {
101 }
103 {
105 }
107 {
109 }
110
111 //---------------------------------------------------------------------------
112 // Logarithm functions
114 {
115 return MathImpl<value_type>::Log2(v); // Logarithm base 2
116 }
118 {
119 return MathImpl<value_type>::Log10(v); // Logarithm base 10
120 }
122 {
123 return MathImpl<value_type>::Log(v); // Logarithm base e (natural logarithm)
124 }
125
126 //---------------------------------------------------------------------------
127 // misc
129 {
131 }
133 {
134 return (v.real() == 0.0 || v.imag() == 0.0) ? (std::abs(v.real()) + std::abs(v.imag())) : std::abs(v); //MathImpl<value_type>::Abs(v);
135 }
137 {
139 }
141 {
142 return value_type(MathImpl<double>::Rint(v.real()), MathImpl<double>::Rint(v.imag()));
143 }
145 {
146 return value_type(MathImpl<double>::Sign(v.real()), MathImpl<double>::Sign(v.imag()));
147 }
148
149 //---------------------------------------------------------------------------
155 {
156 return -v;
157 }
158
159 //---------------------------------------------------------------------------
164 value_type Parser::Sum(const value_type* a_afArg, int a_iArgc)
165 {
166 if (!a_iArgc)
167 throw exception_type(_nrT("too few arguments for function sum."));
168 return parser_Sum(a_afArg, a_iArgc);
169 }
170
171 //---------------------------------------------------------------------------
176 value_type Parser::Avg(const value_type* a_afArg, int a_iArgc)
177 {
178 if (!a_iArgc)
179 throw exception_type(_nrT("too few arguments for function avg."));
180 return parser_Avg(a_afArg, a_iArgc);
181 }
182
183
184 //---------------------------------------------------------------------------
189 value_type Parser::Min(const value_type* a_afArg, int a_iArgc)
190 {
191 if (!a_iArgc)
192 throw exception_type(_nrT("too few arguments for function min."));
193 return parser_Min(a_afArg, a_iArgc);
194 }
195
196
197 //---------------------------------------------------------------------------
202 value_type Parser::Max(const value_type* a_afArg, int a_iArgc)
203 {
204 if (!a_iArgc)
205 throw exception_type(_nrT("too few arguments for function max."));
206 return parser_Max(a_afArg, a_iArgc);
207 }
208
209
210 //---------------------------------------------------------------------------
217 int Parser::IsVal(const char_type* a_szExpr, int* a_iPos, value_type* a_fVal)
218 {
219 value_type fVal(0);
220
221 stringstream_type stream(a_szExpr);
222 stream.seekg(0); // todo: check if this really is necessary
223 stream.imbue(Parser::s_locale);
224 stream >> fVal;
225 stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
226
227 if (iEnd == (stringstream_type::pos_type) - 1)
228 return 0;
229
230 *a_iPos += (int)iEnd;
231 *a_fVal = fVal;
232 return 1;
233 }
234
235
236 //---------------------------------------------------------------------------
242 : ParserBase()
243 {
245
246 InitCharSets();
247 InitFun();
248 InitConst();
249 InitOprt();
250 }
251
252 //---------------------------------------------------------------------------
260 {
261 DefineNameChars( _nrT("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ[]~\\") );
262 DefineOprtChars( _nrT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}") );
263 DefineInfixOprtChars( _nrT("/+-*^?<>=#!$%&|~'_") );
264 }
265
266 //---------------------------------------------------------------------------
269 {
271 {
272 // When setting MUP_BASETYPE to an integer type
273 // Place functions for dealing with integer values here
274 // ...
275 // ...
276 // ...
277 }
278 else
279 {
280 // trigonometric functions
281 DefineFun("sin", Sin);
282 DefineFun("cos", Cos);
283 DefineFun("tan", Tan);
284 // arcus functions
285 DefineFun("asin", ASin);
286 DefineFun("arcsin", ASin);
287 DefineFun("acos", ACos);
288 DefineFun("arccos", ACos);
289 DefineFun("atan", ATan);
290 DefineFun("arctan", ATan);
291 DefineFun("atan2", ATan2);
292 // hyperbolic functions
293 DefineFun("sinh", Sinh);
294 DefineFun("cosh", Cosh);
295 DefineFun("tanh", Tanh);
296 // arcus hyperbolic functions
297 DefineFun("asinh", ASinh);
298 DefineFun("arsinh", ASinh);
299 DefineFun("acosh", ACosh);
300 DefineFun("arcosh", ACosh);
301 DefineFun("atanh", ATanh);
302 DefineFun("artanh", ATanh);
303 // Logarithm functions
304 DefineFun("log2", Log2);
305 DefineFun("log10", Log10);
306 DefineFun("log", Log10);
307 DefineFun("ln", Ln);
308 // misc
309 DefineFun("exp", Exp);
310 DefineFun("sqrt", Sqrt);
311 DefineFun("sign", Sign);
312 DefineFun("rint", Rint);
313 DefineFun("abs", Abs);
314 // Functions with variable number of arguments
315 DefineFun("sum", Sum);
316 DefineFun("avg", Avg);
317 DefineFun("min", Min);
318 DefineFun("max", Max);
319 }
320 }
321
322 //---------------------------------------------------------------------------
329 {
331 }
332
333 //---------------------------------------------------------------------------
339 {
341 }
342
343 //---------------------------------------------------------------------------
344 void Parser::OnDetectVar(string_type* /*pExpr*/, int& /*nStart*/, int& /*nEnd*/)
345 {
346 }
347 // this is just sample code to illustrate modifying variable names on the fly.
348 // I'm not sure anyone really needs such a feature...
349 /*
350
351
352 string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd);
353 string sRepl = std::string("_") + sVar + "_";
354
355 int nOrigVarEnd = nEnd;
356 cout << "variable detected!\n";
357 cout << " Expr: " << *pExpr << "\n";
358 cout << " Start: " << nStart << "\n";
359 cout << " End: " << nEnd << "\n";
360 cout << " Var: \"" << sVar << "\"\n";
361 cout << " Repl: \"" << sRepl << "\"\n";
362 nEnd = nStart + sRepl.length();
363 cout << " End: " << nEnd << "\n";
364 pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl);
365 cout << " New expr: " << *pExpr << "\n";
366 */
367//}
368
369 //---------------------------------------------------------------------------
384 value_type a_fPos,
385 value_type a_fEpsilon,
386 size_t order)
387 {
388 value_type fBuf(*a_Var),
389 fEpsilon(a_fEpsilon),
390 fRes;
391 std::array<value_type, 5> f;
392 std::array<double, 5> factors = {-2, -1, 0, 1, 2};
393
394 // Backwards compatible calculation of epsilon inc case the user doesnt provide
395 // his own epsilon
396 if (fEpsilon == 0.0)
397 fEpsilon = (a_fPos == 0.0) ? (value_type)1e-10 : (value_type)(1e-7*std::abs(a_fPos)*intPower(10, 2*(order-1)));
398
399
400 for (size_t i = 0; i < f.size(); i++)
401 {
402 *a_Var = a_fPos + factors[i] * fEpsilon;
403 f[i] = Eval();
404 }
405
406 // Reference: https://web.media.mit.edu/~crtaylor/calculator.html
407 if (order == 1)
408 fRes = ( f[0] - 8.0 * f[1] + 8.0 * f[3] - f[4]) / (12.0 * fEpsilon);
409 else if (order == 2)
410 fRes = (-f[0] + 16.0 * f[1] - 30.0*f[2] + 16.0 * f[3] - f[4]) / (12.0 * fEpsilon * fEpsilon);
411 else if (order == 3)
412 fRes = (-f[0] + 2.0 * f[1] - 2.0 * f[3] + f[4]) / (2.0 * fEpsilon * fEpsilon * fEpsilon);
413 else
414 return NAN;
415
416 *a_Var = fBuf; // restore variable
417 return fRes;
418 }
419} // namespace mu
Mathematical expressions parser (base parser engine).
Definition: muParserBase.h:69
void AddValIdent(identfun_type a_pCallback)
Add a value parsing function.
value_type Eval()
Single-value wrapper around the vectorized overload of this member function.
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 DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool optimizeAway=true)
Add a user defined operator.
ParserError exception_type
Type of the error class.
Definition: muParserBase.h:96
void DefineInfixOprtChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of infix operators.
static std::locale s_locale
The locale used by the parser.
Definition: muParserBase.h:228
void DefineFun(const string_type &a_strName, T a_pFun, bool optimizeAway=true)
Define a parser function without arguments.
Definition: muParserBase.h:156
void DefineNameChars(const char_type *a_szCharset)
Define the set of valid characters to be used in names of functions, variables, constants.
value_type Diff(value_type *a_Var, value_type a_fPos, value_type a_fEpsilon=0, size_t order=1)
Numerically differentiate with regard to a variable.
Definition: muParser.cpp:383
static value_type ATan(const value_type &)
Definition: muParser.cpp:78
virtual void InitFun() override
Initialize the default functions.
Definition: muParser.cpp:268
static value_type ATanh(const value_type &)
Definition: muParser.cpp:106
static value_type Abs(const value_type &)
Definition: muParser.cpp:132
static value_type Rint(const value_type &)
Definition: muParser.cpp:140
static value_type ASinh(const value_type &)
Definition: muParser.cpp:98
static value_type Sinh(const value_type &)
Definition: muParser.cpp:86
static value_type Sin(const value_type &)
Definition: muParser.cpp:58
virtual void InitOprt() override
Initialize operators.
Definition: muParser.cpp:338
static value_type Log10(const value_type &)
Definition: muParser.cpp:117
static value_type ACos(const value_type &)
Definition: muParser.cpp:74
static value_type UnaryMinus(const value_type &)
Callback for the unary minus operator.
Definition: muParser.cpp:154
static value_type Tan(const value_type &)
Definition: muParser.cpp:66
Parser()
Constructor.
Definition: muParser.cpp:241
static value_type Avg(const value_type *, int)
Callback for averaging multiple values.
Definition: muParser.cpp:176
static value_type Min(const value_type *, int)
Callback for determining the minimum value out of a vector.
Definition: muParser.cpp:189
static value_type Sqrt(const value_type &)
Definition: muParser.cpp:136
virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd) override
Definition: muParser.cpp:344
static value_type Tanh(const value_type &)
Definition: muParser.cpp:94
static value_type Ln(const value_type &)
Definition: muParser.cpp:121
static value_type ACosh(const value_type &)
Definition: muParser.cpp:102
static int IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
Default value recognition callback.
Definition: muParser.cpp:217
virtual void InitConst() override
Initialize constants.
Definition: muParser.cpp:328
static value_type ATan2(const value_type &, const value_type &)
Definition: muParser.cpp:82
static value_type Max(const value_type *, int)
Callback for determining the maximum value out of a vector.
Definition: muParser.cpp:202
static value_type Cos(const value_type &)
Definition: muParser.cpp:62
static value_type ASin(const value_type &)
Definition: muParser.cpp:70
static value_type Cosh(const value_type &)
Definition: muParser.cpp:90
static value_type Log2(const value_type &)
Definition: muParser.cpp:113
virtual void InitCharSets() override
Define the character sets.
Definition: muParser.cpp:259
static value_type Sign(const value_type &)
Definition: muParser.cpp:144
static value_type Sum(const value_type *, int)
Callback for adding multiple values.
Definition: muParser.cpp:164
static value_type Exp(const value_type &)
Definition: muParser.cpp:128
mu::value_type parser_Sum(const mu::value_type *, int)
This function summarizes all elements in the passed array.
#define PARSER_CONST_PI
Pi (what else?).
Definition: muParser.cpp:35
mu::value_type parser_Max(const mu::value_type *, int)
This function calculates the maximal value of all elements in the passed array.
mu::value_type parser_Min(const mu::value_type *, int)
This function calculates the minimal value of all elements in the passed array.
mu::value_type parser_Avg(const mu::value_type *, int)
This function calculates the average of all elements in passed array.
Definition of the standard floating point parser.
#define _nrT(x)
Activate this option in order to compile with OpenMP support.
Definition: muParserDef.h:62
std::complex< double > intPower(const std::complex< double > &, int)
This function calculates the power of a value with the specialization that the exponent is an integer...
Definition: tools.cpp:3640
CONSTCD11 std::chrono::duration< Rep, Period > abs(std::chrono::duration< Rep, Period > d)
Definition: date.h:1317
Namespace for mathematical applications.
Definition: muParser.cpp:53
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:251
string_type::value_type char_type
The character type used by the parser.
Definition: muParserDef.h:263
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:268
std::string string_type
The stringtype used by the parser.
Definition: muParserDef.h:257
A template class for providing wrappers for essential math functions.
static T ACos(const T &v)
static T ASinh(const T &v)
static T Log10(const T &v)
static T Tanh(const T &v)
static T ATan(const T &v)
static T Tan(const T &v)
static T ATan2(const T &v1, const T &v2)
static T Sqrt(const T &v)
static T Sin(const T &v)
static T ATanh(const T &v)
static T Cosh(const T &v)
static T Log(const T &v)
static T Log2(const T &v)
static T Sinh(const T &v)
static T Cos(const T &v)
static T ACosh(const T &v)
static T ASin(const T &v)
static T Exp(const T &v)
A class singling out integer types at compile time using template meta programming.