【发布时间】:2015-12-04 13:40:08
【问题描述】:
使用 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
我想通过积分这个多项式来定义另一个函数,其中函数将取决于积分的上限(乳胶因为我没有足够的声誉......),
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.086627 秒,而lambdify 的实现时间为 0.054799 秒,这看起来是一个显着的加速。 Sympy 手册还建议尽可能使用lambdify
所以我的问题可能不够清楚,是: 有没有更好的方法来进行这种计算?如果有,请告诉我
【问题讨论】:
-
你能举个实际的例子吗!?此外,参数 p 未定义。你的变量 y 的作用是什么?
标签: python function sympy integral