python-sympy:当函数定义分段时,lambdify返回错误的答案

时间:2013-01-06 20:01:12

标签: python sympy piecewise

我感到困惑的是为什么以下代码的答案是10而不是1.有人可以帮助我理解lambdify发生了什么或者是什么造成了错误的答案?

import sympy
from sympy.utilities.lambdify import lambdify
from sympy import Function
from sympy.abc import x, y

def kFct(xIndex,loc,k1,k2):
...   if xIndex <= loc:
...     return k1
...   else:
...     return k2
... 
loc = 0.5
k1 = 1
k2 = 10

kfun = lambdify( (x,y), kFct(x,loc,k1,k2) )
print kfun(0,0)
>>> 10

为什么答案为k1或1,因为x = 0小于loc = 0.5

然而,如果我这样做,它会返回正确的答案

print kfct(0,loc,k1,k2)
>>> 1

我需要kfun作为x和y的函数,因为稍后,我将它用作积分参数的一部分。它最终也将取决于y。

我在Mac 10.6.x上使用python 2.6.8。

2 个答案:

答案 0 :(得分:3)

lambdify的参数在传递之前会被评估,因此您实际上并没有将函数传递给lambdify,而是传递数字10:

>>> kFct(x, loc, k1, k2)
10

你在这里得到10,因为

>>> x <= loc
x <= 0.5
>>> bool(x <= loc)
False

所以第二个分支被采取。由于Python的工作方式,我认为你不能让它工作 - 你不能只抑制一个分支。 (原则上,程序可以做一些疯狂的字节码内省,但我很确定sympy没有。)

您可以使用implemented_function

>>> f = implemented_function(Function('kFct'), lambda x,y: kFct(x, loc, k1, k2))
>>> kfun = lambdify((x,y), f(x,y))
>>> kfun(0,0)
1
>>> kfun(0.5,0)
1
>>> kfun(0.51,0)
10
>>> kfun(1, 0.0)
10

我不确定这对你有多大帮助,但是,考虑到额外的间接性:我可能只是使用函数本身(假设你最终正在寻找积分的数值计算。)

答案 1 :(得分:2)

您想使用Piecewise,它代表SymPy可以使用的符号方式的分支。

以下是明确放置lock1k2值的示例。您当然可以象征性地使用它们,如果您的代码规定,可以稍后用subs替换它们。

>>> kFct = Piecewise((1, x < 0.5), (10, True))
>>> kfun = lambdify(x, kFct)
>>> kfun(0)
1
>>> kfun(1)
10