2010-02-28 1 views
4

У меня есть ряд данных, которые я аппроксимировал, используя полином степени 2 в Python. Я хочу рассчитать площадь под этим многочленом между 0 и 1.Расчет области под математической функцией

Есть ли исчисление или аналогичный пакет из numpy, который я могу использовать, или просто просто сделать простую функцию для интеграции этих функций?

Я немного непонятно, какой лучший подход для определения математических функций.

Спасибо.

+2

Если это полином степени 2, просто проинтегрируйте его вручную - нет необходимости использовать код. – 2010-02-28 21:15:56

+0

Это для большого набора полиномов, которые я обрабатываю партиями по 40. – djq

+0

Площадь под кривой многочлена степени 2 является полиномом со степенью 1. Просто вставляйте значения в это уравнение. –

ответ

8

Если вы интегрируете только полиномы, вам не нужно представлять общую математическую функцию, используйте numpy.poly1d, который имеет метод интеграции .

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

Для интеграции произвольных числовых функций, можно использовать scipy.integrate с обычными функциями Python для функций. Для интеграции аналитических функций вы должны использовать sympy. Не похоже, что вы хотите в этом случае, особенно не в последнем.

+0

Отлично - спасибо! Это очень полезно. Поэтому для вычисления области от 0 до 1 я могу использовать: Area = i (1) - i (0)? – djq

+1

Это будет определенный интеграл от 0 до 1. В этом случае это то же самое, что и область, но в некоторых ситуациях (где часть или весь многочлен отрицателен), это не так. –

1

'quad' в scipy.integrate - метод общего назначения для интегрирования функций одной переменной на определенный интервал. В простом случае (например, описанном в вашем вопросе) вы передаете свою функцию и нижний и верхний пределы соответственно. «quad» возвращает кортеж, состоящий из интегрального результата и верхней границы условия ошибки.

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) 

[Примечание: после того, как я отправил это я ответ вывешенные перед моим, и которая представляет собой полиномы с помощью «» poly1d в Numpy. Мой скриптлет чуть выше также может принять полином в таком виде:

import numpy as NP 

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

Поскольку полиномы могут быть аналитически интегрированы тривиально, лучше использовать более эффективный метод «integ», а не повторенную квадратурную форму Гаусса для них. –

4

Это может быть излишним прибегать к общему назначению алгоритмам численного интегрирования для особого случая ... если вы работаете алгебру, есть простой выражение, которое дает вам область.

У вас есть многочлен степени 2: ф (х) = ах + Ьх + с

Вы хотите найти площадь под кривой х в диапазоне [0 , 1].

Первообразная Р (х) = ах /3 + BX /2 + Сх + С

Площадь под кривой от 0 до 1 является: Р (1) - F (0) = а/3 + б/2 + с

Так что если вы только вычисления площади для интервала [0,1], вы могли бы рассмотреть с помощью этого простого выражения, а не прибегая к методам общего назначения.

5

Посмотрите, Ма, импорт!

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

Наша гарантия: Работает на полином любой положительной степени или ваши деньги обратно!

Обновление от нашей исследовательской лаборатории: гарантия расширена; с/положительным/неотрицательным/:-)

Обновление Вот версия индустриальной силы, которая является надежной в условиях паразитных Интсов в коэффициентах без необходимости вызова функции в цикле, и использует ни enumerate(), ни reversed() в установке:

>>> 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, Хорошее решение (практически такое же, как у одного «интегрированного», я уверен). Я бы сделал свой знаменатель 'float (i + 1)', если бы я не был в файле с 'из __future__ import division'. –

1

Если один интегрируется квадратичными или кубические многочлены от идти, альтернативой получения явных интегральных выражений является использование правила Симпсона; это глубокий факт, что этот метод точно объединяет многочлены степени 3 и ниже.

Заимствуя пример Майка Грэма (я не использовал Python в то время, извинение, если код выглядит ненадежным):

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

использует Симпсон для вычисления значения integrand. Вы можете сами убедиться, что метод работает так, как рекламируется.

Конечно, я не упрощать выражение для integrand, чтобы указать, что 0 и 1 могут быть заменены произвольными значениями u и v, и код будет работать для нахождения интеграла функции от u к v.

+0

Какой хороший ответ! Правило Симпсона, испробованное и истинное, из исчисления. Очень элегантный, независимо от навыков Python. –