Is there an easily available implementation of erf() for Python?

后端 未结 8 1950
日久生厌
日久生厌 2020-12-24 04:54

I can implement the error function, erf, myself, but I\'d prefer not to. Is there a python package with no external dependencies that contains an implementation of this func

相关标签:
8条回答
  • 2020-12-24 05:16

    I recommend SciPy for numerical functions in Python, but if you want something with no dependencies, here is a function with an error error is less than 1.5 * 10-7 for all inputs.

    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)
    

    The algorithm comes from Handbook of Mathematical Functions, formula 7.1.26.

    0 讨论(0)
  • 2020-12-24 05:21

    A pure python implementation can be found in the mpmath module (http://code.google.com/p/mpmath/)

    From the doc 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
    

    For large real x, \mathrm{erf}(x) approaches 1 very rapidly::

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

    The error function is an odd function::

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

    :func:erf implements arbitrary-precision evaluation and supports complex numbers::

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

    Related functions

    See also :func:erfc, which is more accurate for large x, and :func:erfi which gives the antiderivative of \exp(t^2).

    The Fresnel integrals :func:fresnels and :func:fresnelc are also related to the error function.

    0 讨论(0)
  • 2020-12-24 05:31

    To answer my own question, I have ended up using the following code, adapted from a Java version I found elsewhere on the web:

    # 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
    
    0 讨论(0)
  • 2020-12-24 05:32

    Since v.2.7. the standard math module contains erf function. This should be the easiest way.

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

    0 讨论(0)
  • 2020-12-24 05:33

    I would recommend you download numpy (to have efficiant matrix in python) and scipy (a Matlab toolbox substitute, which uses numpy). The erf function lies in scipy.

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

    You can also use the erf function defined in pylab, but this is more intended at plotting the results of the things you compute with numpy and scipy. If you want an all-in-one installation of these software you can use directly the Python Enthought distribution.

    0 讨论(0)
  • 2020-12-24 05:37

    I have a function which does 10^5 erf calls. On my machine...

    scipy.special.erf makes it time at 6.1s

    erf Handbook of Mathematical Functions takes 8.3s

    erf Numerical Recipes 6.2 takes 9.5s

    (three-run averages, code taken from above posters).

    0 讨论(0)
提交回复
热议问题