Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-25 10:03:07

0001 // @(#)root/mathcore:$Id$
0002 // Author: L. Moneta Tue Nov 14 15:44:38 2006
0003 
0004 /**********************************************************************
0005  *                                                                    *
0006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
0007  *                                                                    *
0008  *                                                                    *
0009  **********************************************************************/
0010 
0011 // mathematical constants like Pi
0012 
0013 #ifndef ROOT_Math_Math
0014 #define ROOT_Math_Math
0015 
0016 #ifdef _MSC_VER
0017 #define _USE_MATH_DEFINES
0018 #endif
0019 
0020 #include <cmath>
0021 
0022 #if defined(__sun) || defined(_MSC_VER)
0023 //Microsoft and solaris definition of cmath does not include math.h which has the definitions of numerical constants
0024 #include <math.h> // for M_PI
0025 // TODO replace with std::numbers::pi once minimum version is C++20, and remove this code block
0026 #endif
0027 
0028 
0029 #ifdef HAVE_NO_EXPM1
0030 // needed to implement expm1
0031 #include <limits>
0032 #endif
0033 
0034 
0035 #ifndef M_PI
0036 
0037 #define M_PI       3.14159265358979323846264338328      // Pi
0038 #endif
0039 
0040 #ifndef M_PI_2
0041 #define M_PI_2     1.57079632679489661923132169164      // Pi/2
0042 #endif
0043 
0044 #ifndef M_PI_4
0045 #define M_PI_4     0.78539816339744830961566084582      // Pi/4
0046 #endif
0047 
0048 namespace ROOT {
0049 
0050 /**
0051 \namespace Math
0052 Namespace for new Math classes and functions.
0053 See the \ref Math "Math Libraries" page for a detailed description.
0054 */
0055 
0056 namespace Math {
0057 // Enable Vc/VecCore template instantiations to replace std math functions.
0058 //
0059 // Vc declares `std::sqrt(Vc-type)`. To use this for Vc-`SCALAR`s, the call
0060 // to `sqrt()` must only be resolved at the template instantiation time, when
0061 // the Vc headers are guaranteed to be included, and thus its `sqrt()`
0062 // overloads have been declared.
0063 // The trick is to keep sqrt() dependent (on its argument type) by making it
0064 // an unqualified name. The `std::` of `std::sqrt()` makes it a qualified
0065 // name, so the code here has to use `sqrt()`, not `std::sqrt()`. To still
0066 // find `std::sqrt()` we pull `std::sqrt()` into the surrounding namespace.
0067 //
0068 // We don't want to use 'using namespace std' because it would pollute the including headers.
0069 using std::atan2;
0070 using std::cos;
0071 using std::cosh;
0072 using std::exp;
0073 using std::floor;
0074 using std::log;
0075 using std::pow;
0076 using std::sin;
0077 using std::sinh;
0078 using std::sqrt;
0079 using std::tan;
0080 
0081 /**
0082     Mathematical constants
0083 */
0084 inline double Pi()
0085 {
0086    return M_PI;
0087    }
0088 
0089    /**
0090        declarations for functions which are not implemented by some compilers
0091    */
0092 
0093    /// log(1+x) with error cancelation when x is small
0094    inline double log1p(double x)
0095    {
0096 #ifndef HAVE_NO_LOG1P
0097    return ::log1p(x);
0098 #else
0099    // if log1p is not in c math library
0100   volatile double y;
0101   y = 1 + x;
0102   return std::log(y) - ((y-1)-x)/y ;  /* cancels errors with IEEE arithmetic */
0103 #endif
0104 }
0105 /// exp(x) -1 with error cancellation when x is small
0106 inline double expm1( double x) {
0107 #ifndef HAVE_NO_EXPM1
0108    return ::expm1(x);
0109 #else
0110    // compute using taylor expansion until difference is less than epsilon
0111    // use for values smaller than 0.5 (for larger (exp(x)-1 is fine
0112    if (std::abs(x) < 0.5)
0113    {
0114        // taylor series S = x + (1/2!) x^2 + (1/3!) x^3 + ...
0115 
0116       double i = 1.0;
0117       double sum = x;
0118       double term = x / 1.0;
0119       do {
0120          i++ ;
0121          term *= x/i;
0122          sum += term;
0123       }
0124       while (std::abs(term) > std::abs(sum) * std::numeric_limits<double>::epsilon() ) ;
0125 
0126       return sum ;
0127    }
0128    else
0129    {
0130       return std::exp(x) - 1;
0131    }
0132 #endif
0133 }
0134 
0135    } // end namespace Math
0136 
0137 } // end namespace ROOT
0138 
0139 
0140 
0141 
0142 
0143 #endif /* ROOT_Math_Math */