使用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
所以我的问题,可能不够清楚,是: 有更好的方法进行此类计算吗?如果有,请告诉我
答案 0 :(得分:0)
当然,lambdified版本更快。它不仅将结果矢量化为numpy数组而不是使用Python for
循环,而且在其他版本中,每次重新计算积分时效率也非常低。
我在这里看不到实际的问题。你的lambdified版本看起来正确。我没有看到任何问题。