Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
Math.h
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Author: L. Moneta Tue Nov 14 15:44:38 2006
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 // mathematical constants like Pi
12 
13 #ifndef ROOT_Math_Math
14 #define ROOT_Math_Math
15 
16 #ifdef _MSC_VER
17 #define _USE_MATH_DEFINES
18 #endif
19 
20 #include <cmath>
21 
22 #if defined(__sun) || defined(_MSC_VER)
23 //Microsoft and solaris definition of cmath does not include math.h which has the definitions of numerical constants
24 #include <math.h>
25 #endif
26 
27 
28 #ifdef HAVE_NO_EXPM1
29 // needed to implement expm1
30 #include <limits>
31 #endif
32 
33 
34 #ifndef M_PI
35 
36 #define M_PI 3.14159265358979323846264338328 // Pi
37 #endif
38 
39 #ifndef M_PI_2
40 #define M_PI_2 1.57079632679489661923132169164 // Pi/2
41 #endif
42 
43 #ifndef M_PI_4
44 #define M_PI_4 0.78539816339744830961566084582 // Pi/4
45 #endif
46 
47 /**
48  \namespace ROOT
49  Namespace for new ROOT classes and functions
50  */
51 
52 namespace ROOT {
53 
54 /**
55 \namespace Math
56 Namespace for new Math classes and functions.
57 See the \ref Math "Math Libraries" page for a detailed description.
58 */
59 
60 namespace Math {
61 // Enable Vc/VecCore template instantiations to replace std math functions.
62 //
63 // Vc declares `std::sqrt(Vc-type)`. To use this for Vc-`SCALAR`s, the call
64 // to `sqrt()` must only be resolved at the template instantiation time, when
65 // the Vc headers are guaranteed to be included, and thus its `sqrt()`
66 // overloads have been declared.
67 // The trick is to keep sqrt() dependent (on its argument type) by making it
68 // an unqualified name. The `std::` of `std::sqrt()` makes it a qualified
69 // name, so the code here has to use `sqrt()`, not `std::sqrt()`. To still
70 // find `std::sqrt()` we pull `std::sqrt()` into the surrounding namespace.
71 //
72 // We don't want to use 'using namespace std' because it would polute the including headers.
73 using std::atan2;
74 using std::cos;
75 using std::cosh;
76 using std::exp;
77 using std::floor;
78 using std::log;
79 using std::pow;
80 using std::sin;
81 using std::sinh;
82 using std::sqrt;
83 using std::tan;
84 
85 /**
86  Mathematical constants
87 */
88 inline double Pi()
89 {
90  return M_PI;
91  }
92 
93  /**
94  declarations for functions which are not implemented by some compilers
95  */
96 
97  /// log(1+x) with error cancelatio when x is small
98  inline double log1p(double x)
99  {
100 #ifndef HAVE_NO_LOG1P
101  return ::log1p(x);
102 #else
103  // if log1p is not in c math library
104  volatile double y;
105  y = 1 + x;
106  return std::log(y) - ((y-1)-x)/y ; /* cancels errors with IEEE arithmetic */
107 #endif
108 }
109 /// exp(x) -1 with error cancellation when x is small
110 inline double expm1( double x) {
111 #ifndef HAVE_NO_EXPM1
112  return ::expm1(x);
113 #else
114  // compute using taylor expansion until difference is less than epsilon
115  // use for values smaller than 0.5 (for larger (exp(x)-1 is fine
116  if (std::abs(x) < 0.5)
117  {
118  // taylor series S = x + (1/2!) x^2 + (1/3!) x^3 + ...
119 
120  double i = 1.0;
121  double sum = x;
122  double term = x / 1.0;
123  do {
124  i++ ;
125  term *= x/i;
126  sum += term;
127  }
128  while (std::abs(term) > std::abs(sum) * std::numeric_limits<double>::epsilon() ) ;
129 
130  return sum ;
131  }
132  else
133  {
134  return std::exp(x) - 1;
135  }
136 #endif
137 }
138 
139  } // end namespace Math
140 
141 } // end namespace ROOT
142 
143 
144 
145 
146 
147 #endif /* ROOT_Math_Math */