![]() |
Home | Libraries | People | FAQ | More |
#include <boost/math/special_functions/beta.hpp>
namespace boost{ namespace math{ template <class T1, class T2> calculated-result-type beta(T1 a, T2 b); template <class T1, class T2, class Policy> calculated-result-type beta(T1 a, T2 b, const Policy&); }} // namespaces
β函數的定義如下:
最後一個策略 參數是可選的並且可以用來控制函數的行為: 如何處理錯誤, 使用哪種層次的精度等等. 參見策略文檔瞭解更多信息。
在庫的內部,這個函數有兩個高效的版本:一個完全通用的版本,運行速度慢一些但是更精確一些, 以及一個更高效的使用逼近方法的版本,當T的有效數字的個數與一個特定的 蘭克澤斯逼近對應時。實際上,任何一個你所遇到的內建的浮點類型都有一個適當的蘭克澤斯逼近 定義. 給定足夠的運算時間,也有可能使用libs/math/tools/lanczos_generator.cpp產生其它的蘭克澤斯逼近 .
當T1和T2是不同類型的時候,函數的返回值的類型使用函數返回值推導法則 來確定。
下面的表顯示了輸入參數的不同定義域的峰值誤差, 以及與GSL-1.9 庫和Cephes 庫的比較. 注意:在一些平台上使用寬浮點類型來表示窄浮點類型的結果具有高效零誤差.
表2.β函數的峰值誤差
|
有效數字位數 |
平台和編譯器 |
0.4 < a,b < 100 時的誤差 |
1e-6 < a,b < 36 時的誤差 |
|---|---|---|---|
|
53 |
Win32, Visual C++ 8 |
峰值=99 均值=22 (GSL 峰值=1178 均值=238) (Cephes=1612) |
峰值=10.7 均值=2.6 (GSL 峰值=12 均值=2.0) (Cephes=174) |
|
64 |
Red Hat Linux IA32, g++ 3.4.4 |
峰值=112.1 均值=26.9 |
峰值=15.8 均值=3.6 |
|
64 |
Red Hat Linux IA64, g++ 3.4.4 |
峰值=61.4 均值=19.5 |
峰值=12.2 均值=3.6 |
|
113 |
HPUX IA64, aCC A.06.06 |
峰值=42.03 均值=13.94 |
峰值=9.8 均值=3.1 |
注意:當a或b很大的時候出現最大誤差,而且,如果剛好是這種情況的時候,結果非常接近於0, 因此絕對誤差將會非常小.
混合抽樣測試(spot tests)使用了精確的測試數據以及隨機生成的測試數據: 測試數據使用精度為1000-bits的NTL::RR 庫生成.
傳統的計算β函數的方法要麼是直接計算函數,要麼是先取對數,然後對結果進行指數運算。然而,前一種方法對於非常合適的參數也容易產生溢出,而後一種方法容易產生消去錯誤(cancellation errors)。 作為取捨,如果我們將β函數看作是一個包含了蘭克澤斯逼近 的白盒子, 那麼我們可以合併冪項(power terms):
這是最理想的解決方案, 然而,當a 或 b很大時,幾乎所有的錯誤都出現在計算冪項( power term)上面,如果我們假定a>b,那麼我們可以把較大的一個冪項減去一個因子b,這就很快將極大誤差(maximum error)減半:
這或許還不是最後的解決方案, 但與其它的實現方式相比卻很有挑戰性.
一般的實現 - 當沒有 蘭克澤斯逼近 可用的時候 - 與γ函數的一般實現具有很大的相似之處。為了避免數值溢出,作為級數前綴的冪項和連分式(continued fraction)部分被合在一起:
其中 la, lb 和 lc 作為 a, b, 和 a+b的積分限(integration limits).
有一些特殊情況值得提及:
當a 或 b 比1小時, 我們可以使用遞推關係:
來移動到一個a和b都大於1的區域。
此外: