2010-02-28 7 views
4

J'ai une plage de données que j'ai approximée en utilisant un polynôme de degré 2 en Python. Je veux calculer la surface sous ce polynôme entre 0 et 1.Calcul de l'aire sous une fonction mathématique

Existe-t-il un calcul, ou un paquet similaire à partir de numpy que je peux utiliser, ou devrais-je simplement faire une simple fonction pour intégrer ces fonctions?

Je ne comprends pas très bien quelle est la meilleure approche pour définir les fonctions mathématiques.

Merci.

+2

S'il s'agit d'un polynôme de degré 2, il suffit de l'intégrer manuellement - il n'est pas nécessaire d'utiliser du code. –

+0

C'est pour un grand nombre de polynômes, que je traite en lots de 40. – djq

+0

L'aire sous la courbe d'un polynôme de degré 2 est un polynôme de degré 1. Il suffit de brancher des valeurs dans cette équation. –

Répondre

8

Si vous intégrez polynômes seulement, vous n'avez pas besoin de représenter une fonction mathématique générale, utilisez numpy.poly1d, qui a une méthode integ d'intégration.

>>> import numpy 
>>> p = numpy.poly1d([2, 4, 6]) 
>>> print p 
    2 
2 x + 4 x + 6 
>>> i = p.integ() 
>>> i 
poly1d([ 0.66666667, 2.  , 6.  , 0.  ]) 
>>> integrand = i(1) - i(0) # Use call notation to evaluate a poly1d 
>>> integrand 
8.6666666666666661 

Pour l'intégration des fonctions numériques arbitraires, vous devez utiliser scipy.integrate avec des fonctions Python normales pour les fonctions. Pour l'intégration analytique des fonctions, vous devez utiliser sympy. Il ne semble pas que vous voulez non plus dans ce cas, surtout pas le dernier.

+0

Super - merci! C'est très utile. Donc, pour calculer la zone de 0 à 1, je peux utiliser: Area = i (1) - i (0)? – djq

+1

Ce sera l'intégrale définie de 0 à 1. Dans ce cas, c'est la même chose que la zone, mais dans certaines situations (où tout ou partie du polynôme est négatif), ce n'est pas le cas. –

1

'quad' dans scipy.integrate est la méthode générale d'intégration des fonctions d'une seule variable sur un intervalle défini. Dans un cas simple (tel que celui décrit dans votre question) vous passez dans votre fonction et les limites inférieure et supérieure, respectivement. 'quad' renvoie un tuple composé du résultat intégral et une borne supérieure du terme d'erreur.

from scipy import integrate as TG 

fnx = lambda x: 3*x**2 + 9*x # some polynomial of degree two 
aoc, err = TG.quad(fnx, 0, 1) 

[Note: après avoir posté i une réponse envoyée avant moi, et qui représente polynômes en utilisant 'poly1d' en Numpy. Mon scriptlet juste au-dessus peut également accepter un polynôme sous cette forme:

import numpy as NP 

px = NP.poly1d([2,4,6]) 
aoc, err = TG.quad(px, 0, 1) 
# returns (8.6666666666666661, 9.6219328800846896e-14) 
+0

Puisque les polynômes peuvent être intégrés analytiquement de manière triviale, il est préférable d'utiliser la méthode 'integ' plus efficace plutôt que la quadrature de Gauss répétée pour eux. –

4

Il est peut-être exagéré de recourir à usage général des algorithmes d'intégration numérique pour votre cas particulier ... si vous travaillez l'algèbre, il y a simple expression qui vous donne la zone.

Vous avez un polynôme de degré 2: f (x) = ax + bx + c

vous voulez trouver l'aire sous la courbe pour x dans la gamme [0 , 1].

la primitive F (x) = ax /3 + bx /2 + cx + C

L'aire sous la courbe de 0 à 1 est le suivant: F (1) - F (0) = a/3 + b/2 + c

donc, si vous êtes seulement le calcul de la zone pour l'intervalle [0,1], vous pourriez envisager en utilisant cette simple expression plutôt que recourir aux méthodes générales.

5

Look, Ma, pas d'importations!

>>> coeffs = [2., 4., 6.] 
>>> sum(coeff/(i+1) for i, coeff in enumerate(reversed(coeffs))) 
8.6666666666666661 
>>> 

Notre garantie: Fonctionne pour un polynôme de n'importe quel degré positif ou votre argent de retour!

Mise à jour de notre laboratoire de recherche: Garantie étendue; s/positif/non négatif/:-)

Mise à jour Voici la version force industrielle qui est robuste face à des ints parasites dans les coefficients sans avoir un appel de fonction dans la boucle, et utilise ni enumerate() ni reversed() dans la configuration:

>>> icoeffs = [2, 4, 6] 
>>> tot = 0.0 
>>> divisor = float(len(icoeffs)) 
>>> for coeff in icoeffs: 
...  tot += coeff/divisor 
...  divisor -= 1.0 
... 
>>> tot 
8.6666666666666661 
>>> 
+0

+1, Bonne solution (pratiquement la même que celle implémentée par 'integ', j'en suis sûr). Je ferais mon dénominateur 'float (i + 1)' si je n'étais pas dans un fichier avec 'from __future__ import division'. –

1

Si l'on est l'intégration polynômes quadratique ou cubique du get-go, une alternative à dériver les expressions intégrales explicites est d'utiliser la règle de Simpson; il est un fait profond que cette méthode exactement intègre des polynômes de degré 3 et inférieur.

Pour reprendre l'exemple de Mike Graham (je ne l'ai pas utilisé Python dans un certain temps, des excuses si le code semble bancale):

>>> import numpy 
>>> p = numpy.poly1d([2, 4, 6]) 
>>> print p 
    2 
2 x + 4 x + 6 
>>> integrand = (1 - 0)(p(0) + 4*p((0 + 1)/2) + p(1))/6 

utilise la règle de Simpson pour calculer la valeur de integrand. Vous pouvez vérifier par vous-même que la méthode fonctionne comme annoncée.

Bien sûr, je ne simplifie pas l'expression de integrand pour indiquer que le 0 et 1 peuvent être remplacées par des valeurs arbitraires u et v, et le code sera toujours travailler pour trouver l'intégrale de la fonction u-v.

+0

Quelle belle réponse! La règle de Simpson, éprouvée, à partir du calcul. Très élégant, indépendamment des compétences Python. –

Questions connexes