对于分段函数和numpy模块,sympy.lambdify出错

时间:2016-06-26 16:50:43

标签: numpy sympy piecewise lambdify

在第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'的条件之前评估分段函数。

我的问题是:

这种行为是否正常?

如果是这样,为什么以及如何定义分段表达式并使用numpy模块快速评估它而不使用sympy.lambdify过程?

编辑:

发现在我的情况下解决方案是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

1 个答案:

答案 0 :(得分:2)

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

ZeroDivisionError之所以出现是因为lambdified表达式大致产生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除以零就可以了。它会发出警告,但在其他方面工作正常(它给出inf),在这个例子中没有问题,因为实际上没有使用inf

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

f_numpy(0, 1)

使用

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

如果您有兴趣,可以SymPy issue讨论这个问题。