Sympy定义积分

时间:2015-12-04 13:40:09

标签: python function sympy integral

使用Sympy,我想定义一个变量的函数,其中变量是某个积分的上限。

我尝试了以下功能

import sympy as sp

def g(a,x):
    y = sp.Symbol('y')
    expr = sp.Integral( f(y,p), [y,a,x] )
    return expr.doit()

然而,我问自己,如果在许多方面进行评估,这是否会有效。我一直在阅读关于lambdify的内容,并希望在这种情况下使用它,但我不确定如何。

我实际上不确定lambdify是否是正确的方法。或者,可以考虑计算一次不定积分,然后仅应用极限来评估定积分。

让我举个例子。我有一个带有一些参数的变量的函数,比如y

中的多项式
def f(y, p):
    c0,c1,c2=p
    return c0+c1*y+c2*y**2

我想通过整合这个多项式来定义另一个函数,其中函数将取决于积分的上限(Latex因为我没有足够的声誉......),

g_ {a,p}(x)= \ int_ {a} ^ {x} f(y,p)dy

因此,在这个简单的情况下,g(x)将是多项式或阶数3,需要在a和x之间进行求值。一旦我有g(x),我想在"很多"点,所以我的问题是我能否有效地做到这一点。

我做了一个天真的解决方案实现,一个使用sympy.lambdify。只计时一次,所以不是最准确的结果。但是,使用sympy.lambdify似乎要快100倍。

天真的实施

import sympy as sp
import numpy as np
import time

def f(y, p):
    c0,c1,c2,c3,c4,c5 = p
    return c0 + c1*x + c2*x**2 + c3*x**3 + c4*x**4 + c5*x**5

def g(a,x):
    y = sp.Symbol('y')
    expr = sp.Integral( f(y,p), [y,a,x] )
    return expr.doit()

start = time.clock()
l = []
for x in np.arange(a,b,0.001):
    l.append(g(a,x))
end = time.clock()
print end-start

改进实施

import sympy as sp
import numpy as np
import time

def f(y, p):
    c0,c1,c2,c3,c4,c5 = p
    return c0 + c1*x + c2*x**2 + c3*x**3 + c4*x**4 + c5*x**5

x=sp.Symbol('x')
itgx = sp.Integral( f(y,p), [y,a, x] )
start = time.clock()
g = sp.lambdify(x, itgx.doit(), "numpy")
l = g(np.arange(a,b,0.001))
end = time.clock()
print end-start

在我的架构上(i7-3770 @ 3.40GHz,Ubuntu 14.04), 天真的实现时间为12.086627s,而lambdify实现时间为0.054799s,这看起来像是一个显着的加速。 Sympy手册还建议尽可能使用lambdify

所以我的问题,可能不够清楚,是: 有更好的方法进行此类计算吗?如果有,请告诉我

1 个答案:

答案 0 :(得分:0)

当然,lambdified版本更快。它不仅将结果矢量化为numpy数组而不是使用Python for循环,而且在其他版本中,每次重新计算积分时效率也非常低。

我在这里看不到实际的问题。你的lambdified版本看起来正确。我没有看到任何问题。