1
/******************************************************************************
2
Copyright (c) 2007 netAllied GmbH, Tettnang
4
Permission is hereby granted, free of charge, to any person
5
obtaining a copy of this software and associated documentation
6
files (the "Software"), to deal in the Software without
7
restriction, including without limitation the rights to use,
8
copy, modify, merge, publish, distribute, sublicense, and/or sell
9
copies of the Software, and to permit persons to whom the
10
Software is furnished to do so, subject to the following
13
The above copyright notice and this permission notice shall be
14
included in all copies or substantial portions of the Software.
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
OTHER DEALINGS IN THE SOFTWARE.
24
******************************************************************************/
26
#ifndef __MATHML_SOLVER_FUNCTION_EXTENTIONS_H__
27
#define __MATHML_SOLVER_FUNCTION_EXTENTIONS_H__
29
#include "MathMLSolverPrerequisites.h"
30
#include "MathMLParserConstants.h"
34
#include "MathMLSymbolTable.h"
38
/** Forward Declarations. */
42
/** Extensions for additional functions for the solver */
43
class _MATHML_SOLVER_EXPORT SolverFunctionExtentions
47
SolverFunctionExtentions()
51
virtual ~SolverFunctionExtentions()
55
/** Method for retrieving information about the sign of a value.
56
@return Returns 1 for values > 0 or -1 for values < 0, otherwise 0.
58
inline static double sign ( double value )
74
/** Adds all trigonometric and basic functions to the given symbolTable.
75
@param symbolTable The symbol table for adding functions.
77
static void addAllExtensionFunctions( MathML::SymbolTable& symbolTable );
81
//-------------------------------------------------------------------------------------------
82
inline static void sin( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
84
result.setValue( ::sin( paramlist.at( 0 ).getDoubleValue() ) );
87
//-------------------------------------------------------------------------------------------
88
inline static void cos( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
90
result.setValue( ::cos( paramlist.at( 0 ).getDoubleValue() ) );
93
//-------------------------------------------------------------------------------------------
94
inline static void tan( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
96
result.setValue( ::tan( paramlist.at( 0 ).getDoubleValue() ) );
99
//-------------------------------------------------------------------------------------------
100
inline static void abs( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
102
result.setValue( ( double ) ::abs( paramlist.at( 0 ).getDoubleValue() ) );
105
//-------------------------------------------------------------------------------------------
106
inline static void logn( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
108
result.setValue( ::log( paramlist.at( 0 ).getDoubleValue() ) );
111
//-------------------------------------------------------------------------------------------
112
inline static void exp( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
114
result.setValue( ::exp( paramlist.at( 0 ).getDoubleValue() ) );
117
//-------------------------------------------------------------------------------------------
118
inline static void pow( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
120
result.setValue( ::pow( paramlist.at( 0 ).getDoubleValue(), paramlist.at( 1 ).getDoubleValue() ) );
123
/** Reciprocal value of cosinus ( 1 / cosinus ). */
124
inline static void sec( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
126
double cosinus = ::cos( paramlist.at( 0 ).getDoubleValue() );
127
result.setValue( 1. / cosinus );
130
/** Reciprocal value of sinus ( 1 / sinus ). */
131
inline static void cosec( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
133
double sinus = ::sin( paramlist.at( 0 ).getDoubleValue() );
134
result.setValue( 1. / sinus );
137
/** Reciprocal value of tangens ( 1 / tangens ). */
138
inline static void cotan( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
140
double tangens = ::tan( paramlist.at( 0 ).getDoubleValue() );
141
result.setValue( 1. / tangens );
144
/** Inverse function of sinus. */
145
inline static void arcsin( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
147
double para = paramlist.at( 0 ).getDoubleValue();
148
result.setValue( ::asin( para ) );
151
/** Inverse function of cosinus. */
152
inline static void arccos( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
154
double para = paramlist.at( 0 ).getDoubleValue();
155
result.setValue( ::acos( para ) );
158
/** Inverse function of tangens. */
159
inline static void arctan( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
161
double para = paramlist.at( 0 ).getDoubleValue();
162
result.setValue( ::atan( para ) );
165
/** Reciprocal value of secant ( arctan(x / sqrt(x * x - 1)) + sign(x - 1) * (2 * arctan(1)) ). */
166
inline static void arcsec( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
168
double x = paramlist.at( 0 ).getDoubleValue();
169
result.setValue( ::atan( ( double ) ( x / ::sqrt( x * x - 1 ) ) ) + sign( x - 1 ) * ( 2 * ::atan( ( double ) 1 ) ) );
172
/** Reciprocal value of cosecant ( arctan(x / sqrt(x * x - 1)) + (sign(x) - 1) * (2 * arctan(1)) ). */
173
inline static void arccsc( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
175
double x = paramlist.at( 0 ).getDoubleValue();
176
result.setValue( ::atan( ( double ) ( x / ::sqrt( x * x - 1 ) ) ) + ( sign( x ) - 1 ) * ( 2 * ::atan( ( double ) 1 ) ) );
179
/** Reciprocal value of cotangens ( arctan(x) + 2 * arctan(1) ). */
180
inline static void arccotan( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
182
double x = paramlist.at( 0 ).getDoubleValue();
183
result.setValue( ::atan( x ) + 2 * ::atan( ( double ) 1 ) );
188
/** Sinus hyperbolicus. */
189
inline static void sinh( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
191
double para = paramlist.at( 0 ).getDoubleValue();
192
result.setValue( ::sinh( para ) );
195
/** Cosinus hyperbolicus. */
196
inline static void cosh( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
198
double para = paramlist.at( 0 ).getDoubleValue();
199
result.setValue( ::cosh( para ) );
202
/** Tangens hyperbolicus. */
203
inline static void tanh( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler)
205
double para = paramlist.at( 0 ).getDoubleValue();
206
result.setValue( ::tanh( para ) );
209
/** Hyperbolicus of reciprocal value of cosinus ( 2 / (exp(x) + exp(-x)) ). */
210
inline static void sech( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
212
double x = paramlist.at( 0 ).getDoubleValue();
213
result.setValue( 2 / ( ::exp( x ) + ::exp( -x ) ) );
216
/** Hyperbolicus of reciprocal value of sinus ( 2 / (exp(x) - exp(-x)) ). */
217
inline static void cosech( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
219
double x = paramlist.at( 0 ).getDoubleValue();
220
result.setValue( 2 / ( ::exp( x ) - ::exp( -x ) ) );
223
/** Hyperbolicus of reciprocal value of tangens ( (exp(x) + exp(-x)) / (exp(x) - exp(-x)) ). */
224
inline static void cotanh( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
226
double x = paramlist.at( 0 ).getDoubleValue();
227
result.setValue( ( ::exp( x ) + ::exp( -x ) ) / ( ::exp( x ) - ::exp( -x ) ) );
231
/** Hyperbolicus of inverse function of sinus. ( log(x + sqrt(x * x + 1)) ) */
232
inline static void arcsinh( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
234
double x = paramlist.at( 0 ).getDoubleValue();
235
result.setValue( ::log( x + ::sqrt( x * x + 1 ) ) );
238
/** Hyperbolicus of inverse function of cosinus. ( log(x + sqrt(x * x - 1)) ) */
239
inline static void arccosh( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
241
double x = paramlist.at( 0 ).getDoubleValue();
242
result.setValue( ::log( x + ::sqrt( x * x - 1 ) ) );
245
/** Hyperbolicus of inverse function of tangens. ( log((1 + x) / (1 - x)) / 2 ) */
246
inline static void arctanh( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
248
double x = paramlist.at( 0 ).getDoubleValue();
249
result.setValue( ::log( ( 1 + x ) / ( 1 - x ) ) / 2 );
252
/** Hyperbolicus of reciprocal value of secant. ( log((sqrt(-x * x + 1) + 1) / x) ) */
253
inline static void arcsech( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
255
double x = paramlist.at( 0 ).getDoubleValue();
256
result.setValue( ::log( ( ::sqrt( -x * x + 1 ) + 1 ) / x ) );
259
/** Hyperbolicus of reciprocal value of cosecant. ( log((sign(x) * sqrt(x * x + 1) + 1) / x) ) */
260
inline static void arccsch( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
262
double x = paramlist.at( 0 ).getDoubleValue();
263
result.setValue( ::log( ( sign( x ) * ::sqrt( x * x + 1 ) + 1 ) / x ) );
266
/** Hyperbolicus of reciprocal value of cotangens. ( log((x + 1) / (x - 1)) / 2 ) */
267
inline static void arccotanh( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
269
double x = paramlist.at( 0 ).getDoubleValue();
270
result.setValue( ::log( ( x + 1 ) / ( x - 1 ) ) / 2 );
275
/** Modulo: Remaining of a / b. */
276
inline static void rem( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
278
double para1 = paramlist.at( 0 ).getDoubleValue();
279
double para2 = paramlist.at( 1 ).getDoubleValue();
280
result.setValue( ( long ) para1 % ( long ) para2 );
283
/** GCD (greatest common divisor): see _gcd(..) -> eucidean algorithm. */
284
inline static void gcd( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
286
double current = paramlist.at( 0 ).getDoubleValue();
288
for ( unsigned int i = 1; i < paramlist.size(); ++i )
290
double paraI = paramlist.at( i ).getDoubleValue();
291
current = _gcd( ( long ) paraI, ( long ) current );
294
result.setValue( current );
297
/** LCM (least common multiple): see _lcm(..) -> lcm(a,b) = (a * b) / gcd(a,b). */
298
inline static void lcm( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
300
double current = paramlist.at( 0 ).getDoubleValue();
302
for ( unsigned int i = 1; i < paramlist.size(); ++i )
304
double paraI = paramlist.at( i ).getDoubleValue();
305
current = _lcm( paraI, current );
308
result.setValue( current );
311
//-------------------------------------------------------------------------------------------
312
inline static void floor( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
314
double para = paramlist.at( 0 ).getDoubleValue();
315
result.setValue( ::floor( para ) );
318
//-------------------------------------------------------------------------------------------
319
inline static void ceiling( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
321
double para = paramlist.at( 0 ).getDoubleValue();
322
result.setValue( ::ceil( para ) );
325
//-------------------------------------------------------------------------------------------
326
inline static void min( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
328
double current = paramlist.at( 0 ).getDoubleValue();
330
for ( unsigned int i = 1; i < paramlist.size(); ++i )
332
double paraI = paramlist.at( i ).getDoubleValue();
333
current = std::min( current, paraI );
336
result.setValue( current );
339
//-------------------------------------------------------------------------------------------
340
inline static void max( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
342
double current = paramlist.at( 0 ).getDoubleValue();
344
for ( unsigned int i = 1; i < paramlist.size(); ++i )
346
double paraI = paramlist.at( i ).getDoubleValue();
347
current = std::max( current, paraI );
350
result.setValue( current );
353
//-------------------------------------------------------------------------------------------
354
static void factorial( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler );
356
//-------------------------------------------------------------------------------------------
357
inline static void root( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
359
double r = paramlist.at( 0 ).getDoubleValue();
360
double x = paramlist.at( 1 ).getDoubleValue();
364
result.setValue( std::sqrt( x ) );
369
result.setValue( ::pow( x, 1 / r ) );
373
//-------------------------------------------------------------------------------------------
374
inline static void log( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
376
double base = paramlist.at( 0 ).getDoubleValue();
377
double x = paramlist.at( 1 ).getDoubleValue();
378
result.setValue( std::log( x ) / std::log( base ) );
381
//-------------------------------------------------------------------------------------------
382
inline static void _xor( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
384
bool a = paramlist.at( 0 ).getBoolValue();
385
bool b = paramlist.at( 1 ).getBoolValue();
386
result.setValue( ( bool ) ( a ^ b ) );
390
//-------------------------------------------------------------------------------------------
393
@return The side of the sas result.
395
inline static void sass( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
397
double para1 = paramlist.at( 0 ).getDoubleValue();
398
double para2 = paramlist.at( 1 ).getDoubleValue();
399
double para3 = paramlist.at( 2 ).getDoubleValue();
400
SASResult sasRresult;
401
sas( sasRresult, para1, para2, para3 );
402
result.setValue( sasRresult.c );
406
@return The side of the sas result.
408
inline static double sass(double a, double gamma, double b)
410
SASResult sasRresult = sas( a, gamma, b );
416
@return The alpha angle of the sas result.
418
inline static void sasa( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
420
double para1 = paramlist.at( 0 ).getDoubleValue();
421
double para2 = paramlist.at( 1 ).getDoubleValue();
422
double para3 = paramlist.at( 2 ).getDoubleValue();
423
SASResult sasRresult;
424
sas( sasRresult, para1, para2, para3 );
425
result.setValue( sasRresult.alpha );
430
@return The alpha angle of the sas result.
432
inline static double sasa(double a, double gamma, double b)
434
SASResult sasRresult = sas( a, gamma, b );
435
return sasRresult.alpha;
440
@return The alpha angle value of the sss result.
442
inline static void sssa( MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler )
444
double para1 = paramlist.at( 0 ).getDoubleValue();
445
double para2 = paramlist.at( 1 ).getDoubleValue();
446
double para3 = paramlist.at( 2 ).getDoubleValue();
448
sss(sssResult, para1, para2, para3 );
449
result.setValue( sssResult.alpha );
454
@return The alpha angle value of the sss result.
456
inline static double sssa(double a, double b, double c)
458
SSSResult sssResult = sss(a, b, c);
459
return sssResult.alpha;
463
@todo dof implementation
464
@param i The index of the DOF to return the axis angle.
465
@return The current axis angle of the specified DOF.
467
inline static void dof(MathML::AST::ConstantExpression& result, const ScalarList& paramlist, ErrorHandler* errorHandler)
469
result.setValue(paramlist.at( 0 ).getDoubleValue());
473
@todo dof implementation
474
@param i The index of the DOF to return the axis angle.
475
@return The current axis angle of the specified DOF.
477
inline static double dof(unsigned int i)
484
/** GCD (euclidean algorithm). */
485
inline static long _gcd( long a, long b )
493
return _gcd( b, ( a % b ) );
496
/** LCM (least common multiple): lcm(a,b) = (a * b) / gcd(a,b). */
497
inline static double _lcm( double a, double b )
499
return ( a * b ) / _gcd( ( long ) a, ( long ) b );
503
//------------------------------------
504
//--- typedefs for SSS, SAS methods
505
//------------------------------------
523
* Trigonemtry function for not orthogonal triangles. Takes two sides and
524
* one angle as input and calculates all missing data.
526
* <li>Calculates the opposite side (c) of the given angle gamma.</li>
527
* <li>Calculates the angle alpha.</li>
528
* <li>Calculates the angle beta.</li>
531
* @param result Result values by reference: c, alpha and beta
533
* @param gamma in rad
536
inline static void sas( SASResult& result, double a, double gamma, double b )
538
result.c = ::sqrt( ::pow( a, 2 ) + ::pow( b, 2 ) - 2 * a * b * ::cos( gamma ) );
539
result.alpha = ::asin( a * ::sin( gamma ) / result.c );
540
result.beta = PI_NUMBER - result.alpha - gamma;
544
* Trigonemtry function for not orthogonal triangles. Takes two sides and
545
* one angle as input and calculates all missing data.
547
* <li>Calculates the opposite side (c) of the given angle gamma.</li>
548
* <li>Calculates the angle alpha.</li>
549
* <li>Calculates the angle beta.</li>
553
* @param gamma in rad
555
* @return Result values by value: c, alpha and beta
557
inline static SASResult sas(double a, double gamma, double b)
560
sas(result, a, gamma, b);
565
* Trigonemtry function for not orthogonal triangles. Takes three sides as
566
* input and calculates all angles.
568
* @param result Result values by reference: alpha, beta, and gamma
569
* @param a first side in mm
570
* @param b second side in mm
571
* @param c third side in mm
573
inline static void sss( SSSResult& result, double a, double b, double c )
575
// alpha = acos( (b≤ + c≤ - a≤) / 2 * b * c )
576
result.alpha = ::acos( ( ::pow( b, 2 ) + ::pow( c, 2 ) - ::pow( a, 2 ) ) / ( 2 * b * c ) );
577
// beta = asin( b * sin(alpha) / a )
578
result.beta = ::asin( b * ::sin( result.alpha ) / a );
579
// gamma = PI - alpha - beta
580
result.gamma = PI_NUMBER - result.alpha - result.beta;
584
* Trigonemtry function for not orthogonal triangles. Takes three sides as
585
* input and calculates all angles.
587
* @param a first side in mm
588
* @param b second side in mm
589
* @param c third side in mm
590
* @return Result values by value: alpha, beta, and gamma
592
inline static SSSResult sss(double a, double b, double c)
595
sss(result, a, b, c);
601
} // namespace MathML
603
#endif // __MATHML_SOLVER_FUNCTION_EXTENTIONS_H__