Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

級數計算(Series Evaluation)

概要

#include <boost/math/tools/series.hpp>

namespace boost{ namespace math{ namespace tools{

template <class Functor>
typename Functor::result_type sum_series(Functor& func, int bits);

template <class Functor>
typename Functor::result_type sum_series(Functor& func, int bits, boost::uintmax_t& max_terms);

template <class Functor, class U>
typename Functor::result_type sum_series(Functor& func, int bits, U init_value);

template <class Functor, class U>
typename Functor::result_type sum_series(Functor& func, int bits, boost::uintmax_t& max_terms, U init_value);

template <class Functor>
typename Functor::result_type kahan_sum_series(Functor& func, int bits);

template <class Functor>
typename Functor::result_type kahan_sum_series(Functor& func, int bits, boost::uintmax_t& max_terms);

}}} // namespaces
說明

這些算法打算用來進行無限級數求和.

每個算法都帶有一個 nullary-function 函數對像作為第一個參數:這個函數將被重複調用來獲取這個被計算的級數的後續項。

第二個參數是結果的所要求的精度的二進制bit個數,當下一項太小以至於不能對開始的bits 產生影響時計算就會停止。

可選的第三個參數max_terms 設置被計算的級數項數的上限。此外,在函數退出的時候,函數將會把max_terms 設置為實際的級數項數:這對於為一個新級數繪製收斂性質圖像會很有幫助。

最後一個可選參數init_value 是這個級數和的初始值。這在兩種情況下很有用:

這些算法的兩個kahan_sum_series 變量和一個攜帶項(carray term)來校正求和過程中的捨入誤差。這受到在What Every Computer Scientist Should Know About Floating-Point Arithmetic.中的 Kahan Summation Formula 的啟發。然而,需要指出的是,只有非常少的級數需要以這種方式求和。

例子

假設我們想要通過無限級數來實現函數log(1+x)

我們定義一個返回級數連續項的小的函數對像:

template <class T>
struct log1p_series
{
   // 我們定義一個 result_type typedef:
   typedef T result_type;

   log1p_series(T x)
      : k(0), m_mult(-x), m_prod(-1){}

   T operator()()
   {
      // 這是被求和算法使用的函數對像
      // 對這個運算符的第一次調用應當返回
      // 級數的第一項,第二次調用返回第二項
      // 以此類推.
      m_prod *= m_mult;
      return m_prod / ++k; 
   }

private:
   int k;
   const T m_mult;
   T m_prod;
};

實現 log(1+x) 現在就非常簡單:

template <class T>
T log1p(T x)
{
   // 我們需要在這裡對x進行一些錯誤檢查!
   assert(std::fabs(x) < 1);
   
   // 構造級數函數對像:
   log1p_series<T> s(x);
   // 並將其累加,使用完全的機器精度(machine precision)的數字個數
   // 以及一些依靠運氣的多餘的幾個精度數字.... !
   return tools::sum_series(s, tools::digits(x) + 2);
}

PrevUpHomeNext