epoc32/include/stdapis/boost/math/special_functions/detail/series.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
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_SERIES_INCLUDED
williamr@2
     7
#define BOOST_MATH_SERIES_INCLUDED
williamr@2
     8
williamr@2
     9
#include <cmath>
williamr@2
    10
williamr@2
    11
#ifdef BOOST_NO_STDC_NAMESPACE
williamr@2
    12
namespace std{ using ::pow; using ::fabs; }
williamr@2
    13
#endif
williamr@2
    14
williamr@2
    15
williamr@2
    16
namespace boost{ namespace math{ namespace detail{
williamr@2
    17
williamr@2
    18
//
williamr@2
    19
// Algorithm kahan_sum_series invokes Functor func until the N'th
williamr@2
    20
// term is too small to have any effect on the total, the terms 
williamr@2
    21
// are added using the Kahan summation method.
williamr@2
    22
//
williamr@2
    23
// CAUTION: Optimizing compilers combined with extended-precision
williamr@2
    24
// machine registers conspire to render this algorithm partly broken:
williamr@2
    25
// double rounding of intermediate terms (first to a long double machine
williamr@2
    26
// register, and then to a double result) cause the rounding error computed
williamr@2
    27
// by the algorithm to be off by up to 1ulp.  However this occurs rarely, and 
williamr@2
    28
// in any case the result is still much better than a naive summation.
williamr@2
    29
//
williamr@2
    30
template <class Functor>
williamr@2
    31
typename Functor::result_type kahan_sum_series(Functor& func, int bits)
williamr@2
    32
{
williamr@2
    33
   typedef typename Functor::result_type result_type;
williamr@2
    34
   result_type factor = std::pow(result_type(2), bits);
williamr@2
    35
   result_type result = func();
williamr@2
    36
   result_type next_term, y, t;
williamr@2
    37
   result_type carry = 0;
williamr@2
    38
   do{
williamr@2
    39
      next_term = func();
williamr@2
    40
      y = next_term - carry;
williamr@2
    41
      t = result + y;
williamr@2
    42
      carry = t - result;
williamr@2
    43
      carry -= y;
williamr@2
    44
      result = t;
williamr@2
    45
   }
williamr@2
    46
   while(std::fabs(result) < std::fabs(factor * next_term));
williamr@2
    47
   return result;
williamr@2
    48
}
williamr@2
    49
williamr@2
    50
} } } // namespaces
williamr@2
    51
williamr@2
    52
#endif // BOOST_MATH_SERIES_INCLUDED