Question

Je suis programme écrit en Python et je dois trouver la dérivée d'une fonction (fonction exprimée sous forme de chaîne).

  • Par exemple: x^2+3*x
  • Son dérivé est: 2*x+3

Y a-t-il des scripts disponibles, ou est-il quelque chose d'utile que vous pouvez me le dire?

Était-ce utile?

La solution

sympy le fait bien.

Autres conseils

Si vous êtes limité à polynômes (qui semble être le cas), il y aurait essentiellement trois étapes:

  1. analyser la chaîne d'entrée en une liste de coefficients à x ^ n
  2. Prenez cette liste des coefficients et les convertir en une nouvelle liste de coefficients selon les règles pour dériver un polynôme.
  3. Prenez la liste des coefficients pour le dérivé et créer une chaîne bien décrivant la fonction polynomiale dérivée.

Si vous devez gérer polynômes comme a*x^15125 + x^2 + c, en utilisant un dict pour la liste des coefficients peut donner un sens, mais nécessitent un peu plus d'attention lorsque vous faites des itérations dans cette liste.

Vous pouvez trouver ce que vous cherchez dans les réponses déjà fournies. Cependant, je voudrais donner une brève explication sur la façon de calculer les dérivées symboliques.

L'entreprise est basée sur la surcharge de l'opérateur et la règle de la chaîne de produits dérivés. Par exemple, le dérivé de v^n est n*v^(n-1)dv/dx, non? Donc, si vous avez v=3*x et n=3, ce que le dérivé serait? La réponse: si f(x)=(3*x)^3, le dérivé est:

f'(x)=3*(3*x)^2*(d/dx(3*x))=3*(3*x)^2*(3)=3^4*x^2

La règle de la chaîne vous permet de « chaîne » de l'opération: chaque dérivé individuel est simple, et vous venez de « chaîne » de la complexité. Un autre exemple, le dérivé de u*v est v*du/dx+u*dv/dx, non? Si vous obtenez une fonction compliquée, vous enchaînez juste, disons que:

d/dx(x^3*sin(x))
u=x^3; v=sin(x)
du/dx=3*x^2; dv/dx=cos(x)
d/dx=v*du+u*dv

Comme vous pouvez le voir, la différenciation est seulement une chaîne d'opérations simples.

Maintenant, la surcharge de l'opérateur.

Si vous pouvez écrire un analyseur (essayez pyparsing), vous pouvez demander à évaluer à la fois la fonction et dérivée! Je l'ai fait (en utilisant Flex / Bison) juste pour le plaisir, et il est assez puissant. Pour vous d'obtenir l'idée, la dérivée est calculée de manière récursive par la surcharge de l'opérateur correspondant, et l'application récursive la règle de la chaîne, de sorte que l'évaluation des "*" correspondrait à u * v pour la valeur de la fonction et u*der(v)+v*der(u) pour valeur dérivée (essayez en C ++, il est aussi amusant).

Donc là vous allez, je sais que vous ne voulez pas écrire votre propre analyseur - par tous les moyens d'utiliser le code existant (visitez www.autodiff.org pour la différenciation automatique des Fortran et C / C ++ code). Mais il est toujours intéressant de savoir comment fonctionne ce genre de choses.

Cheers,

Juan

symbolique de différenciation est une introduction impressionnante au sujet du moins pour non spécialiste comme moi :) Le code est écrit en C ++ btw.

Mieux vaut tard que jamais?

Je l'ai toujours fait la différenciation symbolique dans la langue en travaillant avec un arbre d'analyse syntaxique. Mais j'ai aussi récemment pris conscience d'une autre méthode utilisant nombres complexes .

L'approche de l'arbre d'analyse syntaxique consiste à traduire le petit code Lisp suivant dans la langue que vous souhaitez:

(defun diff (s x)(cond
  ((eq s x) 1)
  ((atom s) 0)
  ((or (eq (car s) '+)(eq (car s) '-))(list (car s)
    (diff (cadr s) x)
    (diff (caddr s) x)
    ))
  ; ... and so on for multiplication, division, and basic functions
  ))

et en le suivant avec un simplificateur approprié, afin que vous vous débarrasser des additions de 0, multipliant par 1, etc.

Mais la méthode complexe, tout en étant complètement numérique, a une certaine qualité magique. Au lieu de programmer votre calcul F en double précision, faites-le dans un complexe double précision. Ensuite, si vous avez besoin du dérivé du calcul par rapport à la variable X, définissez la partie imaginaire de X à un très petit nombre h, comme 1E-100. Ensuite, faites le calcul et obtenir le résultat R. Maintenant réel (R) est le résultat que vous obtiendriez normalement, et imag (R) / h = dF / dX à très haute précision!

Comment ça marche? Prenons le cas de la multiplication des nombres complexes:

(a+bi)(c+di) = ac + i(ad+bc) - bd

Maintenant supposons que les parties imaginaires sont tous nuls, sauf que nous voulons que le dérivé par rapport à a. Nous avons mis b à un très petit nombre h. Maintenant, qu'avons-nous?

(a+hi)(c) = ac + hci

Ainsi, la partie réelle de c'est ac, comme on peut s'y attendre, et la partie imaginaire, divisé par h, est c, qui est le dérivé de ac par rapport à a.

Le même genre de raisonnement semble s'appliquer à toutes les règles de différenciation.

Si vous envisagez d'écrire le programme de différenciation à partir de zéro, sans utiliser d'autres bibliothèques comme aide, l'algorithme / approche de calcul du dérivé d'une équation algébrique I décrit dans mon blog sera utile.

Vous pouvez essayer de créer une classe qui représentera une limite rigoureusement puis l'évaluer pour (f (x) -f (a)) / (x-a) comme x approches a. Cela devrait donner une valeur assez précise de la limite.

À moins qu'une bibliothèque déjà fait dériver c'est assez complexe car vous avez besoin pour analyser et gérer les fonctions et les expressions.

Dérivation par lui-même, il est une tâche facile, car il est mécanique et peut être fait algorithmiquement, mais vous avez besoin d'une structure de base pour stocker une fonction.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top