2

我对为什么以下代码的答案是 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。

4

2 回答 2

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

不过,考虑到额外的间接性,我不确定这对您有多大好处:我可能只使用函数本身(假设您最终要寻找积分的数值评估。)

于 2013-01-06T20:23:05.437 回答
2

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

这是您的示例,其中包含loc,k1k2明确输入的值。您当然可以象征性地使用它们,然后subs在您的代码规定的情况下替换它们。

>>> kFct = Piecewise((1, x < 0.5), (10, True))
>>> kfun = lambdify(x, kFct)
>>> kfun(0)
1
>>> kfun(1)
10
于 2013-01-08T23:13:34.983 回答