【问题标题】:Sympy define function of the upper limit of an integralSympy定义积分上限的函数
【发布时间】: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


【解决方案1】:

当然,lambdified 版本更快。它不仅通过 numpy 数组对结果进行矢量化,而不是使用 Python for 循环,而且在另一个版本中,每次都重新计算积分,您的效率也非常低下。

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

【讨论】:

  • 是的,这也是我的想法,也是我寻求其他想法的原因。我知道我写的解决方案是正确的,而且当然更快,但我问是否有其他或更好的方法来做到这一点。我在这里没有看到这个问题的实际答案......
  • 您的“改进”版本对我来说看起来不错。就 SymPy 的使用而言,我没有看到任何改进点。
  • 如果您仍然遇到性能问题,我建议您查看 SymPy 的代码生成模块(例如 autowrapufuncify)。另一种选择是用numba.jit 包装你的lambdified 函数。
猜你喜欢
  • 2017-12-28
  • 1970-01-01
  • 2020-04-13
  • 2020-07-30
  • 2020-06-14
  • 2014-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多