是否有任何信息可供提升的ERF功能背后的算法? 该模块的文件是不是很精确。 所有我发现的是,几种方法进行混合。 对我来说,它看起来像阿布拉莫维茨和Stegun的变化。
- 哪些方法混合使用吗?
- 该方法是怎么混?
- 什么是对ERF功能(恒定时间)的复杂性?
塞巴斯蒂安
是否有任何信息可供提升的ERF功能背后的算法? 该模块的文件是不是很精确。 所有我发现的是,几种方法进行混合。 对我来说,它看起来像阿布拉莫维茨和Stegun的变化。
塞巴斯蒂安
对于文档升压数学工具包有一长串的引用 ,其中阿布拉莫维茨和Stegun。 的叔-功能接口包含一个策略可用于控制数值精度(以及因此它的运行时间复杂度)的模板的参数。
#include <boost/math/special_functions/erf.hpp>
namespace boost{ namespace math{
template <class T>
calculated-result-type erf(T z);
template <class T, class Policy>
calculated-result-type erf(T z, const Policy&);
template <class T>
calculated-result-type erfc(T z);
template <class T, class Policy>
calculated-result-type erfc(T z, const Policy&);
}} // namespaces
更新 :
下面较早提供参考ERF功能的部分“执行”的完整副本:
履行
这些功能的所有版本首先使用通常的反射方程,使他们的论点正:
erf(-z) = 1 - erf(z);
erfc(-z) = 2 - erfc(z); // preferred when -z < -0.5
erfc(-z) = 1 + erf(z); // preferred when -0.5 <= -z < 0
这些函数的一般版本使用不完全伽玛功能方面实现。
当有效数(尾数)大小被识别(目前为53,64和113位的实数,加上通过促进加倍单精度的24位处理),则使用一系列由JM发明有理近似的。
对于z <= 0.5,则一个有理近似ERF被使用,基于这样的观察ERF为奇函数,因此ERF使用计算:
erf(z) = z * (C + R(z*z));
有效地,只要相对于常数C的绝对误差足够小,则R(Z * z)的计算期间所发生的任何舍入误差会:其中有理近似R(Z * Z)600是绝对误差优化从结果中消失。 因此在这个区域ERF ERFC和误差是非常低:最后一位是只有极少数病例不正确。
对于z> 0.5,我们观察到在一个小的区间[a,b)中,则:
erfc(z) * exp(z*z) * z ~ c
对于一些常数c。
因此对于z> 0.5,我们计算使用ERFC:
erfc(z) = exp(-z*z) * (C + R(z - B)) / z;
再次R(ž - B)为绝对误差的优化,和常数C是ERFC(Z)* EXP(Z * Z)*在该范围的端点所采取z的平均值。 再一次,只要R中的绝对误差 - 和C相比则c + R(Z - B)(Z B)是小将被正确地舍入,并且结果中的误差将在exp的精度仅取决于功能。 在实践中,但在所有极少数的情况下,错误被限制到结果的最后一位。 选择常数B,使得有理近似的范围的左手端是0。
对于大Z在一定范围内并[a,+∞]的上述近似被修改为:
erfc(z) = exp(-z*z) * (C + R(1 / z)) / z;
合理近似值中解释痛苦的细节 。 TF,你需要更多的细节,你可以随时看看源代码 。