sympy错误.Lambdify用于分段函数和numpy模块



在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的numpy模块一样快。lambdify手续?

编辑:

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

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

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

ZeroDivisionError出现的原因是,粗略地说,lambdized表达式产生了lambda x, y: select([less(y, -1),less_equal(y, 1),True], [1/x,x,1/x], default=nan)。问题是,传入x = 0会导致Python计算1/0,从而引发错误。

但是NumPy可以很好地除以0。它将发出警告,但除此之外工作正常(它给出了inf),并且在本例中没有问题,因为实际上没有使用inf

所以解决方案是将lambdify的输入包装为numpy数组,也就是说,而不是

f_numpy(0, 1)
使用

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

有一个SymPy问题讨论这个如果你感兴趣。

最新更新