是否有一个Python的erf()的简单实现?

问题描述:

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

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

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

我建议你下载numpy(在python中有效矩阵)和scipy(Matlab工具箱替代品,它使用numpy)。 erf的功能在于scipy。

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

您还可以使用在pylab定义的ERF的功能,但是这是更打算在密谋你numpy的和SciPy的计算事物的结果。如果您想要安装这些软件的一体机 ,则可以直接使用Python Enthought distribution

+0

SciPy的是Python的数值计算软件的motherload。但是开始使用它可能有点困难。首先看http://www.scipy.org/ – 2009-01-19 13:06:45

+1

我不得不说,我完全没有安装它。有一个原因,我要求一个没有外部依赖的软件包。 Numpy不是唯一的一个。 UMFPack是另一个。编写我自己的erf()会更容易! – rog 2009-01-19 13:35:08

+1

正如我提到的那样尝试Python Enthought,他们已经捆绑了你需要的一切。 – Mapad 2009-01-19 13:51:47

我推荐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) 

该算法来自Handbook of Mathematical Functions,公式7.1.26。

要回答我的问题,我已经结束了使用下面的代码,改编自一个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 

纯Python实现可以在mpmath模块中找到( http://code.google.com/p/mpmath/

从文档字符串:

>>> 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) approache第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) 

相关功能

参见:FUNC:erfc,这是大x, ,更准确:FUNC:erfi赋予的 \exp(t^2)的反导。

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

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

scipy.special.erf使它在6时间。1S

数学函数的ERF手册需要8.3s

ERF数字食谱6.2需要9.5s

(三运行平均值,代码从上方海报截取)。

一注为那些瞄准了更高的性能:矢量化,如果可能的话。

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