分段函数和 numpy 模块的 sympy.lambdify 错误
Error with sympy.lambdify for piecewise functions and numpy module
在 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
我删除了我的另一个答案(如果你已经看到了)。有一个更简单的解决方案。
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 会讨论这个问题。
在 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
我删除了我的另一个答案(如果你已经看到了)。有一个更简单的解决方案。
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 会讨论这个问题。