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