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