![]() |
Home | Libraries | People | FAQ | More |
#include <boost/math/special_functions/gamma.hpp>
namespace boost{ namespace math{ template <class T> calculated-result-type tgamma(T z); template <class T, class Policy> calculated-result-type tgamma(T z, const Policy&); template <class T> calculated-result-type tgamma1pm1(T dz); template <class T, class Policy> calculated-result-type tgamma1pm1(T dz, const Policy&); }} // namespaces
template <class T> calculated-result-type tgamma(T z); template <class T, class Policy> calculated-result-type tgamma(T z, const Policy&);
返回z值的"true gamma" (也即是函數名 tgamma) :
最後一個策略 參數是可選的並且可以用來控制函數的行為: 如何處理錯誤, 使用哪種層次的精度等等. 參見策略文檔瞭解更多信息。
在庫的內部,這個函數有兩個高效的版本:一個完全通用的版本,運行速度慢一些但是更精確一些, 以及一個更高效的使用逼近方法的版本,當T的有效數字的個數於一個特定的 蘭克澤斯逼近對應時。實際上,任何一個你所遇到的內建的浮點類型都有一個適當的蘭克澤斯逼近 定義. 給定足夠的運算時間,也有可能使用libs/math/tools/lanczos_generator.cpp產生其它的蘭克澤斯逼近 .
函數返回值的類型使用返回值推導法則:來確定。如果T是整型,那麼結果類型為double,否則為T。
template <class T> calculated-result-type tgamma1pm1(T dz); template <class T, class Policy> calculated-result-type tgamma1pm1(T dz, const Policy&);
返回tgamma(dz + 1) -
1. 在實現的內部並沒有使用加法和減法,這就可以使得即使對很小的d值也會產生精確的結果。然而,這個實現的精度交叉於35個數字或與T類型相關的蘭克澤斯逼近 相關,無論哪一個更精確一些。
函數返回值的類型使用返回值推導法則:來確定。如果T是整型,那麼結果類型為double,否則為T。
最後一個策略 參數是可選的並且可以用來控制函數的行為: 如何處理錯誤, 使用哪種層次的精度等等. 參見策略文檔瞭解更多信息
下面的表顯示了在不同平台上的不同浮點類型的峰值誤差,以及與GSL-1.9, GNU C Lib, HP-UX C Library 和Cephes 庫的比較. 除非另外指定比此處的類型更窄的浮點類型,否則計算結果具有有效的零誤差 .
|
有效數字位數 |
平台和編譯器 |
階乘和半階乘 |
接近於0的值 |
接近於 1 或 2的值 |
接近於一個負極(Negative Pole ) |
|---|---|---|---|---|---|
|
53 |
Win32 Visual C++ 8 |
峰值=1.9 均值=0.7 (GSL=3.9) (Cephes=3.0) |
峰值=2.0 均值=1.1 (GSL=4.5) (Cephes=1) |
峰值=2.0 均值=1.1 (GSL=7.9) (Cephes=1.0) |
峰值=2.6 均值=1.3 (GSL=2.5) (Cephes=2.7) |
|
64 |
Linux IA32 / GCC |
峰值=300 均值=49.5 (GNU C Lib 峰值=395 均值=89) |
峰值=3.0 均值=1.4 (GNU C Lib 峰值=11 均值=3.3) |
峰值=5.0 均值=1.8 (GNU C Lib 峰值=0.92 均值=0.2) |
峰值=157 均值=65 (GNU C Lib 峰值=205 均值=108) |
|
64 |
Linux IA64 / GCC |
GNU C Lib 峰值 2.8 均值=0.9 (GNU C Lib 峰值 0.7) |
峰值=4.8 均值=1.5 (GNU C Lib 峰值 0) |
峰值=4.8 均值=1.5 (GNU C Lib 峰值 0) |
峰值=5.0 均值=1.7 (GNU C Lib 峰值 0) |
|
113 |
HPUX IA64, aCC A.06.06 |
峰值=2.5 均值=1.1 (HP-UX C Library 峰值 0) |
峰值=3.5 均值=1.7 (HP-UX C Library 峰值 0) |
峰值=3.5 均值=1.6 (HP-UX C Library 峰值 0) |
峰值=5.2 均值=1.92 (HP-UX C Library 峰值 0) |
γ函數很容易測試:階乘與半整數階乘可以精確的計算並且與γ函數相比較。此外,在一些獨特的區域中的精確測試使用這個函數的一般版本在高精度情況下計算。
函數tgamma1pm1
使用基於方程tgamma(1+dz)-1使用蘭克澤斯逼近至精度為100個十進制數字來計算的數據.
tgamma
函數的一般版本使用不完全γ函數的合併級數和連分數的方法來實現:
其中l 是一個任意的積分限: 選擇l = max(10, a)看起來效果很好.
對於精度已知的類型使用 蘭克澤斯逼近 , boost::math::lanczos::lanczos_traits
類將類型T映射到一個合適的逼近方法。
對於在 -20 < z < 1 範圍內的z值,下面的迭代用來將z調整到z > 1 :
對於非常中的z,這可以用來維持等式:
對於z < -20 使用下面的反射方程:
對於 z * sin([pi][space] * z)
部分的計算需要額外注意:一個特殊的程序用來約化與 π 相乘之前的一個z用來確保結果的區間[0, π/2].沒有這一處理,那麼在這個區域內會出現大量的誤差(這已經很困難了,因為在一個負極附近的函數變化相當快)
最後,如果參數是一個很小的整數,那麼就使用階乘查找表方法。
函數tgamma1pm1
使用由JM 發明的在-0.5 < dz < 2內的有理逼近. 這些與lgamma函數相同的逼近.
所以在這裡就不做進一步的解釋了。結果是log(tgamma(dz+1))的逼近作為函數 expm1 的參數用來產生期望的結果.在範圍-0.5 < dz < 2 這外,那麼可以直接使用方程tgamma1pm1(dz) = tgamma(dz+1) - 1.