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 que je veux la valeur de la dérivée en x = 5...

6 votes

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

0 votes

Alternativement, souhaitez-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 terriblement 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 pas d'outils externes mais sont sujettes aux erreurs numériques et, si vous êtes 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 assez robustes de nos jours. SymPy est un excellent projet pour cela qui s'intègre bien avec NumPy. Consultez 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 intéressantes, ne sont pas sujettes aux erreurs numériques, mais nécessitent des bibliothèques supplémentaires (recherchez sur Google à ce sujet, il existe quelques bonnes options). C'est le choix le plus robuste mais aussi le plus sophistiqué/difficile à mettre en place. Si vous êtes à l'aise avec 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 la 3.Différenciation symbolique et la 4.Différenciation manuelle??

13 votes

Lorsque j'ai dit "différenciation symbolique", je voulais impliquer que le processus était effectué par un ordinateur. En principe 3 et 4 diffèrent uniquement par celui qui fait le travail, l'ordinateur ou le programmeur. 3 est préféré à 4 en raison de la cohérence, de la scalabilité et de la paresse. 4 est nécessaire si 3 échoue à 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 que je connaisse consiste à utiliser la fonction gradient de numpy :

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

Ainsi, dydx sera calculé en utilisant des différences centrées et aura la même longueur que y, contrairement à numpy.diff, qui utilise des différences en avant et renverra un vecteur de taille (n-1).

2 votes

Que se passe-t-il si dx n'est pas constant?

3 votes

@weberc2, dans ce cas, vous devez 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 une constante dx, 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 particulier 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 souhaitez calculer la dérivée numériquement, vous pouvez utiliser des quotients de différences centrales 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 d'abscisses avec un tableau correspondant y de valeurs de fonction, vous pouvez calculer des approximations de 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 simplement choisi des fonctions bien comportées.

0 votes

Que signifie 2 après >>>print p ?? (à la 2e ligne)

0 votes

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

22voto

yellow01 Points 582

En supposant que vous voulez 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 numériquement la dérivée en x=5:

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

12voto

flutefreak7 Points 349

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

La plupart des splines interpolantes de scipy.interpolate sont capables de fournir des dérivées. Ainsi, en utilisant une spline linéaire (k=1), la dérivée de la spline (en utilisant la méthode derivative()) devrait être équivalente à une différence avant. Je ne suis pas totalement 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 avant et après pour construire la spline cubique.

from scipy.interpolate import InterpolatedUnivariateSpline

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

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

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

0 votes

Je viens juste de tester cela, mais je continue à recevoir des erreurs de cette fonction AxisError: L'axe -1 est en dehors des limites pour un tableau de dimension 0 et je ne vois pas de réponses à ce sujet dans la communauté non plus, est-ce que quelqu'un peut m'aider ?

0 votes

Publiez votre problème comme une nouvelle question et faites un lien vers celui-ci 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 quand elles sont triées ne sont pas une fonction valide, etc. Il est possible que scipy appelle numpy de manière incorrecte, mais très peu probable. Vérifiez x.shape et y.shape. Voir si np.interp() fonctionne - cela peut fournir une erreur plus utile sinon.

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