62 votes

Existe-t-il une implémentation facilement disponible de erf() pour Python ?

Je peux implémenter la fonction d'erreur, erf, moi-même, mais je préfère ne pas le faire. Existe-t-il un paquetage python sans dépendances externes qui contient une implémentation de cette fonction ? J'ai trouvé http://pylab.sourceforge.net/packages/included\_functions.html>this mais cela semble faire partie d'un paquetage beaucoup plus large (et on ne sait même pas lequel !).

Je suis désolé si cette question est naïve - je suis totalement novice en matière de Python.

73voto

bezalel Points 466

Depuis la v.2.7., la norme mathématiques Le module contient erf fonction. Cela devrait être le moyen le plus simple.

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

0 votes

Existe-t-il un module Python qui fournit erf¹(x) ?

1 votes

@Lori - oui, math.erfc

4 votes

@Matthew Je ne pense pas que ce soit correct selon la documentation. Cela calcule 1.0 - erf(x). L'inverse de erf() est dans SciPy : stackoverflow.com/questions/31266249/

56voto

John D. Cook Points 19036

Je recommande SciPy pour les fonctions numériques en Python, mais si vous voulez quelque chose sans dépendances, voici une fonction dont l'erreur est inférieure à 1,5 * 10 -7 pour toutes les entrées.

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)

L'algorithme provient de Manuel des fonctions mathématiques , formule 7.1.26.

2 votes

Vous avez raison. J'ai modifié ma réponse pour trouver le signe de x d'une manière différente pour résoudre ce problème. Maintenant, c'est bon.

6 votes

De wikipedia : "le 'manuel' est l'œuvre du gouvernement fédéral américain [employés], non protégé par le droit d'auteur". Je mets ici un lien plus direct vers le livre : math.sfu.ca/~cbm/aands/frameindex.htm

0 votes

J'essaie d'utiliser cette fonction mais en passant le tableau numpy à x et en retournant le tableau numy comme réponse, sans succès. Pouvez-vous réécrire la version array de la fonction ?

26voto

Mapad Points 3033

Je vous recommande de télécharger numpy (pour avoir une matrice efficace en python) et scipy (un substitut de la boîte à outils Matlab, qui utilise numpy). La fonction erf se trouve dans scipy.

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

Vous pouvez également utiliser la fonction erf définie dans pylab, mais elle est davantage destinée à tracer les résultats des choses que vous calculez avec numpy et scipy. Si vous voulez une installation tout-en-un de ces logiciels, vous pouvez utiliser directement le Distribution Python Enthought .

0 votes

SciPy est l'ensemble des logiciels numériques pour Python. Mais commencer à l'utiliser peut être un peu difficile. Commencez par regarder scipy.org

2 votes

Je dois dire que j'ai totalement échoué à l'installer. Il y a une raison pour laquelle j'ai demandé un paquet sans dépendances externes. Numpy n'est pas le seul. UMFPack en est un autre. Il sera plus facile d'écrire mon propre erf() !

1 votes

Essayez Python Enthought, comme je l'ai dit, ils ont regroupé tout ce dont vous avez besoin.

8voto

Une implémentation purement python peut être trouvée dans le module mpmath (http://code.google.com/p/mpmath/).

De la chaîne de documents :

>>> 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

Pour les grands réels x , \mathrm{erf}(x) approche 1 très rapidement: :

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

La fonction d'erreur est une fonction impaire : :

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

:func : erf implémente l'évaluation en précision arbitraire et supporte les nombres complexes :

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

Fonctions connexes

Voir également :func : erfc ce qui est plus précis pour les grandes x , et :func : erfi ce qui donne l'antidérivée de \exp(t^2) .

Les intégrales de Fresnel :func : fresnels et :func : fresnelc sont également liés à la fonction d'erreur.

0 votes

C'est vraiment intéressant. je suppose que cette implémentation multi-précision est un peu plus lente que l'utilisation de la virgule flottante native ?

6voto

meteore Points 828

J'ai une fonction qui fait 10^5 appels erf. Sur ma machine...

scipy.special.erf fait son temps à 6.1s

erf Handbook of Mathematical Functions prend 8.3s

erf Recettes numériques 6.2 prend 9.5s

(moyennes de trois coups, code repris des affiches ci-dessus).

1 votes

Erf appelé avec ctypes de libm.so (bibliothèque mathématique c standard, ici linux 64 bit) descend à 5.6s.

0 votes

J'ai également besoin de milliers d'appels erf. D'après vos chiffres, j'opte pour scipy.special.erf. Avez-vous trouvé quelque chose de plus rapide depuis ? Je me suis demandé s'il était possible d'utiliser un lookup

1 votes

Pour info, comment utilisez-vous la méthode de scipy erf fonction ? Avec la configuration suivante : from scipy.special import erf; import numpy as np; data = np.random.randn(10e5) j'obtiens des temps d'exécution très rapides : result = erf(data) . En particulier, j'obtiens 32 ms par boucle dans ce cas. La seule façon d'obtenir des temps d'exécution > 1s est de boucler naïvement sur tous les éléments d'un fichier numpy le tableau.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X