Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

誤差函數反函數

概要

#include <boost/math/special_functions/erf.hpp>

namespace boost{ namespace math{

template <class T>
calculated-result-type erf_inv(T p);

template <class T, class Policy>
calculated-result-type erf_inv(T p, const Policy&);

template <class T>
calculated-result-type erfc_inv(T p);

template <class T, class Policy>
calculated-result-type erfc_inv(T p, const Policy&);

}} // namespaces

函數返回值的類型使用返回值推導法則:來確定,當x是整型的時候,返回值的類型是double,否則返回值是類型是T.

最後一個策略 參數是可選的並且可以用來控制函數的行為: 如何處理錯誤, 使用哪種層次的精度等等. 參見策略文檔瞭解更多信息。

說明
template <class T>
calculated-result-type erf_inv(T z);

template <class T, class Policy>
calculated-result-type erf_inv(T z, const Policy&);

返回z的誤差函數的反函數 , 也就是變量x的值滿足:

p = erf(x);

template <class T>
calculated-result-type erfc_inv(T z);

template <class T, class Policy>
calculated-result-type erfc_inv(T z, const Policy&);

返回z的誤差函數的反函數的補集,也就是變量x的值滿足:

p = erfc(x);

精確度

對於包含以及超過80-bit 的 long double類型所使用的逼近方法的精度略中於 2 epsilon(10的-5次方). 對於精度較高的類型,函數的精度與正向誤差函數的精度一樣。

測試

有兩類測試:

實現

這些函數使用由 JM發明的有理逼近來計算精度~10-19的結果的初始近似值,然後,僅當對於類型T的精確度與epsilon(10的-5次方)相比不足時,我們使用 Halley 迭代來清除結果。

構造erf/erfc函數的有理逼近出乎意料的困難,尤其是當精度很高時。出於這個原因,並沒有嘗試使用得128-bit的有理數的計算精度達到10-34

在下面的討論中,p是傳遞給函數erf_inv的值,而q是傳遞給函數erf_inv的值,滿足:p = 1 - qq = 1 - p 在兩種情況下我們想要計算出相同的結果x.

對於p < 0.5 ,erf函數的反函數非常平緩,而且下面的逼近:

x = p(p + 10)(Y + R(p))

對於一個常量Y給出了很好的計算結果, 同時 R(p)對與|Y|相比 的較小的絕對誤差進行了優化。

對於 q < 0.5 ,事情就變得很棘手 , 在區間 0.5 > q > 0.25 之上,下面的逼近運行得非常好:

x = sqrt(-2log(q)) / (Y + R(q))

而勇於進取 q < 0.25, 假定

z = sqrt(-log(q))

那麼結果由下面的方程給定:

x = z(Y + R(z - B))

與前面一樣Y是一個常量且有理函數R針對於與|Y|相比的絕對誤差進行了優化。B也是一個常量:它是對於每一個逼近都合法的z的最小值。每一種形式都有幾個逼近方法,每一種逼近方式都超過了erfc函數的範圍(在long double精度上,與double比較的擴充的指數範圍意味著超過的範圍延續了很長一段距離)。


PrevUpHomeNext