是否有一个容易实现的erf()for Python?

我可以实现错误函数,我自己,但我不想。 是否有一个没有外部依赖的Python包,包含这个函数的实现? 我已经find了这个,但是这似乎是一些更大的包的一部分(甚至不清楚哪一个!)。

自v.2.7以来。 标准的math模块包含erf函数。 这应该是最简单的方法。

http://docs.python.org/2/library/math.html#math.erf

我推荐SciPy用于Python中的数值函数,但是如果你想要一些没有依赖关系的东西,这里有一个错误错误小于1.5 * 10-7的函数。

def erf(x): # save the sign of x sign = 1 if x >= 0 else -1 x = abs(x) # constants a1 = 0.254829592 a2 = -0.284496736 a3 = 1.421413741 a4 = -1.453152027 a5 = 1.061405429 p = 0.3275911 # A&S formula 7.1.26 t = 1.0/(1.0 + p*x) y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*math.exp(-x*x) return sign*y # erf(-x) = -erf(x) 

该algorithm来自math函数手册 ,公式7.1.26。

我会build议你下载numpy (在Python中有效的matrix)和scipy (一个Matlab工具箱替代品,它使用numpy)。 erf的function在于scipy。

 >>>from scipy.special import erf >>>help(erf) 

你也可以使用pylab中定义的erf函数,但是这更多的是用numpy和scipy来绘制你计算的结果。 如果你想要这些软件的一体化安装,你可以直接使用Python Enthought发行版 。

一个纯粹的python实现可以在mpmath模块中find( http://code.google.com/p/mpmath/

从文档string:

 >>> from mpmath import * >>> mp.dps = 15 >>> print erf(0) 0.0 >>> print erf(1) 0.842700792949715 >>> print erf(-1) -0.842700792949715 >>> print erf(inf) 1.0 >>> print erf(-inf) -1.0 

对于大的实数x\mathrm{erf}(x)非常迅速地接近1 ::

 >>> print erf(3) 0.999977909503001 >>> print erf(5) 0.999999999998463 

错误函数是一个奇怪的函数::

 >>> nprint(chop(taylor(erf, 0, 5))) [0.0, 1.12838, 0.0, -0.376126, 0.0, 0.112838] 

:func: erf实现任意精度评估并支持复数::

 >>> mp.dps = 50 >>> print erf(0.5) 0.52049987781304653768274665389196452873645157575796 >>> mp.dps = 25 >>> print erf(1+j) (1.316151281697947644880271 + 0.1904534692378346862841089j) 

相关function

另请参见:func: erfc ,对于大的x更准确,func: erfi给出\exp(t^2)

Fresnel积分:func: fresnels和:func: fresnelc也与错误函数有关。

我有一个10 ^ 5 erf调用的函数。 在我的机器上…

scipy.special.erf使它在6.1s的时间

erfmath函数手册需要8.3s

erf数字食谱6.2需要9.5s

(三条均线,上面的海报代码)。

为了回答我自己的问题,我最终使用了以下代码,这些代码是从我在网上其他地方find的Java版本改编的:

 # from: http://www.cs.princeton.edu/introcs/21function/ErrorFunction.java.html # Implements the Gauss error function. # erf(z) = 2 / sqrt(pi) * integral(exp(-t*t), t = 0..z) # # fractional error in math formula less than 1.2 * 10 ^ -7. # although subject to catastrophic cancellation when z in very close to 0 # from Chebyshev fitting formula for erf(z) from Numerical Recipes, 6.2 def erf(z): t = 1.0 / (1.0 + 0.5 * abs(z)) # use Horner's method ans = 1 - t * math.exp( -z*z - 1.26551223 + t * ( 1.00002368 + t * ( 0.37409196 + t * ( 0.09678418 + t * (-0.18628806 + t * ( 0.27886807 + t * (-1.13520398 + t * ( 1.48851587 + t * (-0.82215223 + t * ( 0.17087277)))))))))) if z >= 0.0: return ans else: return -ans 

对于那些旨在获得更高性能的注意事项:尽可能vector化。

 import numpy as np from scipy.special import erf def vectorized(n): x = np.random.randn(n) return erf(x) def loopstyle(n): x = np.random.randn(n) return [erf(v) for v in x] %timeit vectorized(10e5) %timeit loopstyle(10e5) 

给出结果

 # vectorized 10 loops, best of 3: 108 ms per loop # loops 1 loops, best of 3: 2.34 s per loop