Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/math/special_functions/expm1.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 2.6 KB
Line 
1//  (C) Copyright John Maddock 2005.
2//  Use, modification and distribution are subject to the
3//  Boost Software License, Version 1.0. (See accompanying file
4//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef BOOST_MATH_EXPM1_INCLUDED
7#define BOOST_MATH_EXPM1_INCLUDED
8
9#include <cmath>
10#include <math.h> // platform's ::expm1
11#include <boost/limits.hpp>
12#include <boost/math/special_functions/detail/series.hpp>
13
14#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
15#  include <boost/static_assert.hpp>
16#else
17#  include <boost/assert.hpp>
18#endif
19
20#ifdef BOOST_NO_STDC_NAMESPACE
21namespace std{ using ::exp; using ::fabs; }
22#endif
23
24
25namespace boost{ namespace math{
26
27namespace detail{
28//
29// Functor expm1_series returns the next term in the Taylor series
30// x^k / k!
31// each time that operator() is invoked.
32//
33template <class T>
34struct expm1_series
35{
36   typedef T result_type;
37
38   expm1_series(T x)
39      : k(0), m_x(x), m_term(1) {}
40
41   T operator()()
42   {
43      ++k;
44      m_term *= m_x;
45      m_term /= k;
46      return m_term; 
47   }
48
49   int count()const
50   {
51      return k;
52   }
53
54private:
55   int k;
56   const T m_x;
57   T m_term;
58   expm1_series(const expm1_series&);
59   expm1_series& operator=(const expm1_series&);
60};
61
62} // namespace
63
64//
65// Algorithm expm1 is part of C99, but is not yet provided by many compilers.
66//
67// This version uses a Taylor series expansion for 0.5 > |x| > epsilon.
68//
69template <class T>
70T expm1(T x)
71{
72#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
73   BOOST_STATIC_ASSERT(::std::numeric_limits<T>::is_specialized);
74#else
75   BOOST_ASSERT(std::numeric_limits<T>::is_specialized);
76#endif
77
78   T a = std::fabs(x);
79   if(a > T(0.5L))
80      return std::exp(x) - T(1);
81   if(a < std::numeric_limits<T>::epsilon())
82      return x;
83   detail::expm1_series<T> s(x);
84   T result = detail::kahan_sum_series(s, std::numeric_limits<T>::digits + 2);
85   return result;
86}
87#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
88inline float expm1(float z)
89{
90   return expm1<float>(z);
91}
92inline double expm1(double z)
93{
94   return expm1<double>(z);
95}
96inline long double expm1(long double z)
97{
98   return expm1<long double>(z);
99}
100#endif
101
102#ifdef expm1
103#  ifndef BOOST_HAS_expm1
104#     define BOOST_HAS_expm1
105#  endif
106#  undef expm1
107#endif
108
109#ifdef BOOST_HAS_EXPM1
110#  if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
111inline float expm1(float x){ return ::expm1f(x); }
112inline long double expm1(long double x){ return ::expm1l(x); }
113#else
114inline float expm1(float x){ return ::expm1(x); }
115#endif
116inline double expm1(double x){ return ::expm1(x); }
117#endif
118
119} } // namespaces
120
121#endif // BOOST_MATH_HYPOT_INCLUDED
Note: See TracBrowser for help on using the repository browser.