121 votes

Comment calculer la dérivée en utilisant Numpy ?

Comment calculer la dérivée d'une fonction, par exemple

y = x2+1

en utilisant numpy ?

Disons, je veux la valeur de la dérivée à x = 5...

6 votes

Vous devez utiliser Sympy : sympy.org/fr/index.html. Numpy est une bibliothèque de calcul numérique pour Python.

0 votes

Alternatively, voulez-vous une méthode pour estimer la valeur numérique de la dérivée? Pour cela, vous pouvez utiliser une méthode de différences finies, mais gardez à l'esprit qu'elles ont tendance à être horriblement bruyantes.

205voto

MRocklin Points 2855

Vous avez quatre options

  1. Différences finies
  2. Dérivées automatiques
  3. Différenciation symbolique
  4. Calculer les dérivées à la main.

Les différences finies ne nécessitent aucun outil externe mais sont sujettes aux erreurs numériques et, si vous vous trouvez dans une situation multivariée, cela peut prendre du temps.

La différenciation symbolique est idéale si votre problème est assez simple. Les méthodes symboliques sont de plus en plus robustes de nos jours. SymPy est un excellent projet qui s'intègre bien avec NumPy. Regardez les fonctions autowrap ou lambdify ou consultez l'article de blog de Jensen sur une question similaire.

Les dérivées automatiques sont très efficaces, ne sont pas sujettes aux erreurs numériques, mais nécessitent des bibliothèques supplémentaires (cherchez sur Google, il y a quelques bonnes options). C'est le choix le plus robuste mais aussi le plus sophistiqué/difficile à configurer. Si vous vous limitez à la syntaxe de numpy, alors Theano pourrait être un bon choix.

Voici un exemple utilisant SymPy

In [1]: from sympy import *
In [2]: import numpy as np
In [3]: x = Symbol('x')
In [4]: y = x**2 + 1
In [5]: yprime = y.diff(x)
In [6]: yprime
Out[6]: 2⋅x

In [7]: f = lambdify(x, yprime, 'numpy')
In [8]: f(np.ones(5))
Out[8]: [ 2.  2.  2.  2.  2.]

0 votes

Désolé, si cela semble stupide, Quelles sont les différences entre 3. Différenciation symbolique et 4. la différenciation à la main?

13 votes

Lorsque j'ai dit "différenciation symbolique", je voulais sous-entendre que le processus était géré par un ordinateur. En principe, 3 et 4 diffèrent uniquement par celui qui effectue le travail, l'ordinateur ou le programmeur. Le 3 est préféré au 4 en raison de la cohérence, de la scalabilité et de la paresse. Le 4 est nécessaire si le 3 ne parvient pas à trouver une solution.

4 votes

Dans la ligne 7, nous avons créé f, une fonction qui calcule la dérivée de y par rapport à x. En 8, nous appliquons cette fonction dérivée à un vecteur de tous les uns et obtenons le vecteur de tous les deux. Cela est dû au fait que, comme indiqué dans la ligne 6, yprime = 2*x.

54voto

Sparkler Points 28

La manière la plus simple à laquelle je peux penser est d'utiliser la fonction de gradient de numpy:

x = numpy.linspace(0,10,1000)
dx = x[1]-x[0]
y = x**2 + 1
dydx = numpy.gradient(y, dx)

De cette manière, dydx sera calculé en utilisant des différences centrales et aura la même longueur que y, contrairement à numpy.diff, qui utilise des différences en avant et retournera un vecteur de taille (n-1).

2 votes

Et si dx n'est pas constant?

3 votes

@weberc2, dans ce cas, vous devriez diviser un vecteur par un autre, mais traiter les bords séparément avec des dérivées avant et arrière manuellement.

2 votes

Ou vous pourriez interpoler y avec un dx constant, puis calculer le gradient.

36voto

Sven Marnach Points 133943

NumPy ne fournit pas de fonctionnalité générale pour calculer des dérivées. Il peut cependant gérer le cas spécial simple des polynômes :

>>> p = numpy.poly1d([1, 0, 1])
>>> print p
   2
1 x + 1
>>> q = p.deriv()
>>> print q
2 x
>>> q(5)
10

Si vous voulez calculer la dérivée numériquement, vous pouvez utiliser des quotients de différence centrale pour la grande majorité des applications. Pour la dérivée en un seul point, la formule serait quelque chose comme

x = 5.0
eps = numpy.sqrt(numpy.finfo(float).eps) * (1.0 + x)
print (p(x + eps) - p(x - eps)) / (2.0 * eps * x)

si vous avez un tableau x des abscisses avec un tableau correspondant y des valeurs de la fonction, vous pouvez calculer des approximations des dérivées avec

numpy.diff(y) / numpy.diff(x)

2 votes

'Calculer des dérivées numériques pour des cas plus généraux est facile' -- Je suis en désaccord, calculer des dérivées numériques pour des cas généraux est assez difficile. Vous avez juste choisi des fonctions bien comportées.

0 votes

Que signifie 2 après >>>print p ?? (sur la 2ème ligne)

0 votes

@ DrStrangeLove: C'est l'exposant. Il est censé simuler la notation mathématique.

22voto

yellow01 Points 582

En supposant que vous souhaitez utiliser numpy, vous pouvez calculer numériquement la dérivée d'une fonction en n'importe quel point en utilisant la définition rigoureuse:

def d_fun(x):
    h = 1e-5 #en théorie h est infinitésimal
    return (fun(x+h)-fun(x))/h

Vous pouvez également utiliser la dérivée symétrique pour de meilleurs résultats:

def d_fun(x):
    h = 1e-5
    return (fun(x+h)-fun(x-h))/(2*h)

En utilisant votre exemple, le code complet devrait ressembler à ceci:

def fun(x):
    return x**2 + 1

def d_fun(x):
    h = 1e-5
    return (fun(x+h)-fun(x-h))/(2*h)

Maintenant, vous pouvez trouver la dérivée numériquement à x=5:

In [1]: d_fun(5)
Out[1]: 9.999999999621423

12voto

flutefreak7 Points 349

Je vais ajouter une autre méthode à la pile...

Les nombreux splines interpolants de scipy.interpolate sont capables de fournir des dérivées. Ainsi, en utilisant un spline linéaire (k=1), la dérivée du spline (en utilisant la méthode derivative()) devrait être équivalente à une différence avant. Je ne suis pas entièrement sûr, mais je crois qu'utiliser une dérivée de spline cubique serait similaire à une dérivée de différence centrée car elle utilise des valeurs d'avant et d'après pour construire le spline cubique.

from scipy.interpolate import InterpolatedUnivariateSpline

# Obtenir une fonction qui évalue le spline linéaire à n'importe quel x
f = InterpolatedUnivariateSpline(x, y, k=1)

# Obtenir une fonction qui évalue la dérivée du spline linéaire à n'importe quel x
dfdx = f.derivative()

# Évaluer la dérivée dydx à chaque emplacement x...
dydx = dfdx(x)

0 votes

Je viens juste d'essayer ceci, je continue à obtenir des erreurs de cette fonction AxisError: axis -1 is out of bounds for array of dimension 0 et je ne vois aucune réponse à ce sujet sur la communauté non plus, quelqu'un peut-il aider ?

0 votes

Publiez votre problème en tant que nouvelle question et mettez un lien vers elle ici. Fournir un exemple qui provoque votre erreur sera probablement nécessaire. Les erreurs que j'ai avec les fonctions interp sont généralement dues au fait que les données ne sont pas bien formées - comme des valeurs répétées, un nombre incorrect de dimensions, l'un des tableaux est accidentellement vide, les données ne sont pas triées par rapport à x ou ne sont pas une fonction valide une fois triées, etc. Il est possible que scipy appelle numpy incorrectement, mais très peu probable. Vérifiez x.shape et y.shape. Voyez si np.interp() fonctionne - il peut fournir une erreur plus utile si ce n'est pas le cas.

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