计算数学函数下方的面积

4

我在Python中使用2次多项式逼近了一组数据,现在希望计算该多项式在0到1之间的面积。

请问,numpy是否提供类似微积分的包来解决这个问题?或者我应该编写一个简单的函数来进行积分计算呢?

对于定义数学函数的最佳方法我还有些不清楚。

谢谢。


2
如果它是一个二次多项式,只需手动积分即可 - 没有必要使用代码。 - user97370
这是针对一大批多项式的处理,我会将其分批处理,每批处理40个。 - djq
二次多项式曲线下的面积是一次多项式,只需将值代入方程即可。 - S.Lott
@S.Lott 这是3次方程,但是没错。 - user97370
@Paul Hankin:哎呀——由于某种原因,我一直在想每个点的多项式导数。 - S.Lott
5个回答

9
如果您仅集成多项式,无需表示一般数学函数,请使用numpy.poly1d,它具有用于集成的integ方法。
>>> 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到1计算面积,我可以使用:Area = i(1) - i(0)? - djq
1
这将是从0到1的定积分。在这种情况下,这与面积相同,但在某些情况下(其中多项式的一部分或全部为负),它并不相同。 - Mike Graham

5

Look, Ma, no imports!

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

+1,好的解决方案(实际上与“integ”实现的几乎相同,我敢肯定)。如果我不是在使用“from future import division”文件中,我会将分母设为“float(i + 1)”。 - Mike Graham

3
可能使用通用数值积分算法求解您的特定情况有些过头了……如果您能算出代数表达式,就可以得到一个简单的表达式来计算该区间下的面积。
您有一个二次多项式:f(x) = ax2 + bx + c 您想要找到x在范围[0,1]内的曲线下的面积。
反函数为:F(x) = ax3/3 + bx2/2 + cx + C 从0到1的曲线下面积为:F(1) - F(0) = a/3 + b/2 + c
所以,如果您只需要计算区间[0,1]下的面积,您可以考虑使用这个简单的表达式,而不是使用通用方法。

1
在编程中,scipy.integrate 中的'quad'是用于积分单变量函数的通用方法,在一定区间上。在简单情况下(例如在您的问题中描述的情况),您只需传入函数、下限和上限即可。'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)

[注意:在我发布这篇文章之后,有人在我的回答之前发布了一个使用Numpy中的'poly1d'表示多项式的答案。我的脚本也可以接受这种形式的多项式:]
import numpy as NP

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

由于多项式可以被解析积分,因此最好使用更高效的“integ”方法,而不是重复使用高斯积分。 - Mike Graham

1

如果一开始就要集成二次或三次多项式,除了推导显式积分表达式之外,另一种选择是使用辛普森法则;这是一个深刻的事实,该方法可以精确地集成3次及以下次数的多项式。

借用Mike Graham的例子(我已经有一段时间没有使用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

使用辛普森法则计算被积函数的值。您可以自行验证该方法是否按照广告所述有效。

当然,我没有简化被积函数的表达式,以表明01可以替换为任意值uv,并且该代码仍将用于查找从uv的函数的积分。


多好的答案!辛普森法则,它来自微积分,既经得起时间的考验,又非常优雅,无论你是否掌握Python技能。 - Ellie Kesselman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接