【问题标题】:Error with sympy.lambdify for piecewise functions and numpy module分段函数和 numpy 模块的 sympy.lambdify 错误
【发布时间】:2016-06-26 16:50:42
【问题描述】:

在 sympy 0.7.6 中,对于 modules='sympy' 和 modules='numpy' 选项的以下代码,我没有遇到任何问题。现在使用 sympy v0.1,使用 modules='numpy' 进行评估会引发 ZeroDivisionError:

import sympy

x, y = sympy.symbols(['x', 'y'])
expr = sympy.Piecewise((1/x, y < -1), (x, y <= 1), (1/x, True))

f_sympy = sympy.lambdify([x, y], expr, modules='sympy')
f_numpy = sympy.lambdify([x, y], expr, modules='numpy')

print f_sympy(0, 1)  # performs well

print f_numpy(0, 1) # issue: ZeroDivisionError

似乎分段函数在条件为 modules='numpy' 之前求值。

我的问题是:

这种行为正常吗?

如果是这样,为什么以及如何定义分段表达式并在没有 sympy.lambdify 过程的情况下像使用 numpy 模块一样快速评估它?

编辑:

发现在我的情况下解决方案是theano:

import sympy

x, y = sympy.symbols(['x', 'y'])
f = sympy.Piecewise((1/x, y < -1), (x, y <= 1), (1/x, True))

from sympy.printing.theanocode import theano_function
f_theano = theano_function([x, y], [f])

print f_theano(0, 1)  # OK, return 0

【问题讨论】:

    标签: numpy sympy piecewise lambdify


    【解决方案1】:

    我删除了我的另一个答案(以防你已经看到它)。有一个更简单的解决方案。

    ZeroDivisionError 的出现是因为lambdified 表达式大致生成lambda x, y: select([less(y, -1),less_equal(y, 1),True], [1/x,x,1/x], default=nan)。问题是传入 x = 0 会导致1/0 被 Python 评估,这会引发错误。

    但是 NumPy 可以被零除。它会发出警告,但其他工作正常(它给出inf),在这个例子中没有问题,因为inf实际上并没有使用。

    所以解决方案是将lambdify的输入包装为numpy数组,即代替

    f_numpy(0, 1)
    

    使用

    f_numpy(array(0), array(1))
    

    如果您有兴趣,有一个SymPy issue 正在讨论这个问题。

    【讨论】:

    • 谢谢。这对我来说现在更清楚了。我会尝试“numpy.array”解决方案。现在,我使用我制作的这个解决方法,它调用'lambdarepr' 和(不幸的是)'eval':gist.github.com/A-Falaize/ff2fafd5ab19f88c478f7494e340a619 这对我有用,但不是很'pythonic'。这样的解决方案有什么缺点?
    • 我不明白你的穷人的lambdify如何解决这个问题。据我所知,你的函数所做的一切,sympy.lambdify 也可以,但sympy.lambdify 还可以做更多事情,所以我建议只使用它。
    猜你喜欢
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多