【问题标题】:python-sympy: lambdify returns the wrong answer when function defined piecewisepython-sympy:当函数分段定义时,lambdify 返回错误答案
【发布时间】:2013-01-06 20:01:12
【问题描述】:

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

【问题讨论】:

    标签: python sympy piecewise


    【解决方案1】:

    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
    

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

    【讨论】:

      【解决方案2】:

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

      这是您的示例,其中明确输入了 lock1k2 的值。如果您的代码要求,您当然可以象征性地使用它们并稍后用subs 替换它们。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-25
        • 1970-01-01
        • 1970-01-01
        • 2022-08-17
        • 2022-11-03
        • 1970-01-01
        • 1970-01-01
        • 2019-01-19
        相关资源
        最近更新 更多